Subversion Repositories pentevo

Rev

Rev 179 | Rev 364 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <util/twi.h>
  4.  
  5. #include "pins.h"
  6. #include "mytypes.h"
  7. #include "main.h"
  8. #include "zx.h"
  9. #include "rtc.h"
  10. #include "ps2.h"
  11. #include "version.h"
  12. #include "rs232.h"
  13.  
  14. //if want Log than comment next string
  15. #undef LOGENABLE
  16.  
  17. volatile UBYTE gluk_regs[14];
  18.  
  19. //stop transmit
  20. #define tw_send_stop() {TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);}
  21.  
  22. static UBYTE tw_send_start(void)
  23. {
  24.         //start transmit
  25.         TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  26.  
  27.         //wait for flag
  28.         while (!(TWCR & (1<<TWINT)));
  29.  
  30. #ifdef LOGENABLE
  31.         char log_reset_type[] = "TWS..\r\n";
  32.         UBYTE b = TWSR;
  33.         log_reset_type[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  34.         log_reset_type[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  35.         to_log(log_reset_type);
  36. #endif
  37.         //return status
  38.    return TWSR&0xF8;
  39. }
  40.  
  41. static UBYTE tw_send_addr(UBYTE addr)
  42. {
  43.         //set address
  44.         TWDR = addr;
  45.  
  46.         //enable transmit
  47.         TWCR = (1<<TWINT)|(1<<TWEN);
  48.  
  49.         //wait for end transmit
  50.         while (!(TWCR & (1<<TWINT)));
  51.  
  52. #ifdef LOGENABLE
  53.         char log_tw[] = "TWA.. ..\r\n";
  54.         UBYTE b = TWSR;
  55.         log_tw[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  56.         log_tw[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  57.         log_tw[6] = ((addr >> 4) <= 9 )?'0'+(addr >> 4):'A'+(addr >> 4)-10;
  58.         log_tw[7] = ((addr & 0x0F) <= 9 )?'0'+(addr & 0x0F):'A'+(addr & 0x0F)-10;
  59.         to_log(log_tw);
  60. #endif
  61.         //return status
  62.    return TWSR&0xF8;
  63. }
  64.  
  65. static UBYTE tw_send_data(UBYTE data)
  66. {
  67.         //set data
  68.         TWDR = data;
  69.  
  70.         //enable transmit
  71.         TWCR = (1<<TWINT)|(1<<TWEN);
  72.  
  73.         //wait for end transmit
  74.         while (!(TWCR & (1<<TWINT)));
  75.  
  76. #ifdef LOGENABLE
  77.         char log_tw[] = "TWD.. ..\r\n";
  78.         UBYTE b = TWSR;
  79.         log_tw[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  80.         log_tw[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  81.         log_tw[6] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+(data >> 4)-10;
  82.         log_tw[7] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+(data & 0x0F)-10;
  83.         to_log(log_tw);
  84. #endif
  85.         //return status
  86.    return TWSR&0xF8;
  87. }
  88.  
  89. static UBYTE tw_read_data(UBYTE* data)
  90. {
  91.         //enable
  92.         TWCR = (1<<TWINT)|(1<<TWEN);
  93.  
  94.         //wait for flag set
  95.         while (!(TWCR & (1<<TWINT)));
  96.  
  97. #ifdef LOGENABLE
  98.         char log_tw[] = "TWR.. ..\r\n";
  99.         UBYTE b = TWSR;
  100.         log_tw[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  101.         log_tw[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  102.         log_tw[6] = ((TWDR >> 4) <= 9 )?'0'+(TWDR >> 4):'A'+(TWDR >> 4)-10;
  103.         log_tw[7] = ((TWDR & 0x0F) <= 9 )?'0'+(TWDR & 0x0F):'A'+(TWDR & 0x0F)-10;
  104.         to_log(log_tw);
  105. #endif
  106.         //get data
  107.         *data = TWDR;
  108.  
  109.         //return status
  110.    return TWSR & 0xF8;
  111. }
  112.  
  113. static UBYTE bcd_to_hex(UBYTE data)
  114. {
  115.         //convert BCD to HEX
  116.         return  (data>>4)*10 + (data&0x0F);
  117. }
  118.  
  119. static UBYTE hex_to_bcd(UBYTE data)
  120. {
  121.         //convert HEX to BCD
  122.         return  ((data/10)<<4) + (data%10);
  123. }
  124.  
  125. static UBYTE days_of_months()
  126. {
  127.         //return number of days in month
  128.         static const UBYTE days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
  129.         UBYTE tmp = gluk_regs[GLUK_REG_MONTH]-1;
  130.  
  131.         if ( tmp > sizeof(days)-1 ) tmp = 0; //check range
  132.  
  133.         tmp = days[tmp];
  134.  
  135.         //check leap-year
  136.         if ( (tmp == 28) && ( ( gluk_regs[GLUK_REG_YEAR]&0x03 ) == 0 ) ) tmp++;
  137.  
  138.         return tmp;
  139. }
  140.  
  141. void rtc_init(void)
  142. {
  143.         //SCL frequency = CPU clk/ ( 16 + 2* (TWBR) * 4^(TWPS) )
  144.         // 11052000 / (16 + 2*48 ) = 98678,5Hz (100000Hz recommended for PCF8583)
  145.         TWBR = 48;
  146.         TWSR = 0;
  147.  
  148.         //reset RTC
  149.         //write 0 to control/status register [0] on PCF8583
  150.         rtc_write(0, 0);
  151.  
  152.         //set Gluk clock registers
  153.         gluk_init();
  154.         if ( gluk_regs[GLUK_REG_SEC] == 0 ) gluk_init();
  155.  
  156.         //restore mode register from NVRAM
  157.         modes_register = rtc_read(RTC_COMMON_MODE_REG);
  158.  
  159.         //set modes on fpga
  160.         //zx_spi_send(SPI_CONFIG_REG, modes_register&MODE_VGA, 0);
  161.         zx_set_config(0);
  162. }
  163.  
  164. void rtc_write(UBYTE addr, UBYTE data)
  165. {
  166.         //set address
  167.         if ( tw_send_start() & (TW_START|TW_REP_START) )
  168.         {
  169.                 if ( tw_send_addr(RTC_ADDRESS) == TW_MT_SLA_ACK )
  170.                 {
  171.                         if ( tw_send_data(addr) == TW_MT_DATA_ACK )
  172.                         {
  173.                                 //write data
  174.                                 tw_send_data(data);
  175.                         }
  176.                 }
  177.         }
  178.         tw_send_stop();
  179. }
  180.  
  181. UBYTE rtc_read(UBYTE addr)
  182. {
  183.         UBYTE ret = 0;
  184.         //set address
  185.         if ( tw_send_start() & (TW_START|TW_REP_START) )
  186.         {
  187.                 if ( tw_send_addr(RTC_ADDRESS) == TW_MT_SLA_ACK )
  188.                 {
  189.                         if ( tw_send_data(addr) == TW_MT_DATA_ACK )
  190.                         {
  191.                                 //read data
  192.                                 if ( tw_send_start() == TW_REP_START )
  193.                                 {
  194.                                         if ( tw_send_addr(RTC_ADDRESS|0x01) == TW_MR_SLA_ACK )
  195.                                         {
  196.                                                 tw_read_data(&ret);
  197.                                         }
  198.                                 }
  199.                         }
  200.                 }
  201.         }
  202.         tw_send_stop();
  203.         return ret;
  204. }
  205.  
  206. void gluk_init(void)
  207. {
  208.         UBYTE tmp;
  209.         //default values
  210.         gluk_regs[GLUK_REG_A] = 0x00;
  211.         gluk_regs[GLUK_REG_B] = 0x02;
  212.         gluk_regs[GLUK_REG_C] = 0x00;
  213.         gluk_regs[GLUK_REG_D] = 0x80;
  214.  
  215.         //setup
  216.  
  217.         //read month and day of week
  218.         tmp = rtc_read(6);
  219.         gluk_regs[GLUK_REG_MONTH] = bcd_to_hex(0x1F&tmp);
  220.         gluk_regs[GLUK_REG_DAY_WEEK] = tmp>>5;
  221.  
  222.         //read year and day of month
  223.         tmp = rtc_read(5);
  224.         gluk_regs[GLUK_REG_DAY_MONTH] = bcd_to_hex(0x3F&tmp);
  225.         gluk_regs[GLUK_REG_YEAR] = tmp>>6;
  226.         tmp = rtc_read(RTC_YEAR_ADD_REG);
  227.         if ( (tmp&0x03) > gluk_regs[GLUK_REG_YEAR] )
  228.         {
  229.                 //count of year over - correct year
  230.                 tmp += 4;
  231.                 if ( tmp >= 100 ) tmp = 0;
  232.         }
  233.         gluk_regs[GLUK_REG_YEAR] += tmp&0xFC;
  234.         rtc_write(RTC_YEAR_ADD_REG,gluk_regs[GLUK_REG_YEAR]); //save year
  235.  
  236.         //read time
  237.         gluk_regs[GLUK_REG_HOUR] = bcd_to_hex(0x3F&rtc_read(4)); //TODO 12/24 format
  238.         gluk_regs[GLUK_REG_MIN] = bcd_to_hex(rtc_read(3));
  239.         gluk_regs[GLUK_REG_SEC] = bcd_to_hex(rtc_read(2));
  240. }
  241.  
  242. void gluk_inc(void)
  243. {
  244.         if ( ++gluk_regs[GLUK_REG_SEC] >= 60 )
  245.         {
  246.                 gluk_regs[GLUK_REG_SEC] = 0;
  247.                 if ( ++gluk_regs[GLUK_REG_MIN] >= 60 )
  248.                 {
  249.                         gluk_regs[GLUK_REG_MIN] = 0;
  250.                         if ( ++gluk_regs[GLUK_REG_HOUR] >= 24 )
  251.                         {
  252.                                 gluk_regs[GLUK_REG_HOUR] = 0;
  253.                                 if ( ++gluk_regs[GLUK_REG_DAY_WEEK] > 7  )
  254.                                 {
  255.                                         gluk_regs[GLUK_REG_DAY_WEEK] = 1;
  256.                                 }
  257.                                 if ( ++gluk_regs[GLUK_REG_DAY_MONTH] > days_of_months() )
  258.                                 {
  259.                                         gluk_regs[GLUK_REG_DAY_MONTH] = 1;
  260.                                         if ( ++gluk_regs[GLUK_REG_MONTH] > 12 )
  261.                                         {
  262.                                                 gluk_regs[GLUK_REG_MONTH] = 1;
  263.                                                 if( ++gluk_regs[GLUK_REG_YEAR] >= 100 )
  264.                                                 {
  265.                                                         gluk_regs[GLUK_REG_YEAR] = 0;
  266.                                                 }
  267.                                         }
  268.                                 }
  269.                         }
  270.                 }
  271.         }
  272.  
  273.         //set update flag
  274.         gluk_regs[GLUK_REG_C] |= GLUK_C_UPDATE_FLAG;
  275.  
  276. //#ifdef LOGENABLE
  277. //{
  278. //      char log_int_rtc[] = "00.00.00\r\n";
  279. //      log_int_rtc[0] = '0' + gluk_regs[GLUK_REG_HOUR]/10;
  280. //      log_int_rtc[1] = '0' + gluk_regs[GLUK_REG_HOUR]%10;
  281. //      log_int_rtc[3] = '0' + gluk_regs[GLUK_REG_MIN]/10;
  282. //      log_int_rtc[4] = '0' + gluk_regs[GLUK_REG_MIN]%10;
  283. //      log_int_rtc[6] = '0' + gluk_regs[GLUK_REG_SEC]/10;
  284. //      log_int_rtc[7] = '0' + gluk_regs[GLUK_REG_SEC]%10;
  285. //      to_log(log_int_rtc);
  286. //}
  287. //#endif
  288. }
  289.  
  290. UBYTE gluk_get_reg(UBYTE index)
  291. {
  292.         if( index < sizeof(gluk_regs)/sizeof(gluk_regs[0]) )
  293.         {
  294.                 //clock registers from array
  295.                 UBYTE tmp = gluk_regs[index];
  296.                 if ( ( index<10 ) && ( (gluk_regs[GLUK_REG_B]&GLUK_B_DATA_MODE) == 0 ) )
  297.                 {
  298.                         //clock registers mast be in BCD if HEX-bit not set in reg B
  299.                         tmp = hex_to_bcd(tmp);
  300.                 }
  301.  
  302.                 if ( index == GLUK_REG_C )
  303.                 {
  304.                         //clear update flag
  305.                         gluk_regs[GLUK_REG_C] &= ~GLUK_C_UPDATE_FLAG;
  306.                 }
  307.  
  308.                 return tmp;
  309.         }
  310.         else
  311.         {
  312.                 if ( index >= 0xF0 )
  313.                 {
  314.                         //read version
  315.                         return GetVersionByte( index&0x0F );
  316.                 }
  317.  
  318.                 //other from nvram
  319.                 //- on PCF8583 nvram started from #10
  320.                 //- on 512vi1[DS12887] nvram started from #0E
  321.                 return rtc_read( (index&0x3F)+2 );
  322.         }
  323. }
  324.  
  325. void gluk_set_reg(UBYTE index, UBYTE data)
  326. {
  327.         if( index < sizeof(gluk_regs)/sizeof(gluk_regs[0]) )
  328.         {
  329.                 if ( index<10 )
  330.                 {
  331.                         //write to clock registers
  332.                         if ( (gluk_regs[GLUK_REG_B]&GLUK_B_DATA_MODE) == 0 )
  333.                         {
  334.                                 //array of registers must be in Hex, but data in BCD if HEX-bit not set in reg B
  335.                                 data = bcd_to_hex(data);
  336.                         }
  337.                         gluk_regs[index] = data;
  338.  
  339.                         //write to nvram if need
  340.                         switch( index )
  341.                         {
  342.                                 case GLUK_REG_SEC:
  343.                                         rtc_write(2, hex_to_bcd(gluk_regs[GLUK_REG_SEC]));
  344.                                         break;
  345.                                 case GLUK_REG_MIN:
  346.                                         rtc_write(3, hex_to_bcd(gluk_regs[GLUK_REG_MIN]));
  347.                                         break;
  348.                                 case GLUK_REG_HOUR:
  349.                                         rtc_write(4, 0x3F&hex_to_bcd(gluk_regs[GLUK_REG_HOUR]));
  350.                                         break;
  351.                                 case GLUK_REG_MONTH:
  352.                                 case GLUK_REG_DAY_WEEK:
  353.                                         rtc_write(6, (hex_to_bcd(gluk_regs[GLUK_REG_DAY_WEEK])<<5)+(0x1F&hex_to_bcd(gluk_regs[GLUK_REG_MONTH])));
  354.                                         break;
  355.                                 case GLUK_REG_YEAR:
  356.                                         rtc_write(RTC_YEAR_ADD_REG, gluk_regs[GLUK_REG_YEAR]);
  357.                                 case GLUK_REG_DAY_MONTH:
  358.                                         rtc_write(5, (gluk_regs[GLUK_REG_YEAR]<<6)+(0x3F&hex_to_bcd(gluk_regs[GLUK_REG_DAY_MONTH])));
  359.                                         break;
  360.                         }
  361.                 }
  362.         }
  363.         else
  364.         {
  365.                 if ( index >= 0xF0 )
  366.                 {
  367.                         //set version data type
  368.                         SetVersionType( data );
  369.                 }
  370.                 else
  371.                 {
  372.                         //write to nvram
  373.                         //- on PCF8583 nvram started from #10
  374.                         //- on 512vi1[DS12887] nvram started from #0E
  375.                         rtc_write( (index&0x3F)+2, data);
  376.                 }
  377.         }
  378. }
  379.