Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  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.         //set modes on fpga
  159.         zx_spi_send(SPI_CONFIG_REG, modes_register&MODE_VGA, 0);
  160. }
  161.  
  162. void rtc_write(UBYTE addr, UBYTE data)
  163. {
  164.         //set address
  165.         if ( tw_send_start() & (TW_START|TW_REP_START) )
  166.         {
  167.                 if ( tw_send_addr(RTC_ADDRESS) == TW_MT_SLA_ACK )
  168.                 {
  169.                         if ( tw_send_data(addr) == TW_MT_DATA_ACK )
  170.                         {
  171.                                 //write data
  172.                                 tw_send_data(data);
  173.                         }
  174.                 }
  175.         }
  176.         tw_send_stop();
  177. }
  178.  
  179. UBYTE rtc_read(UBYTE addr)
  180. {
  181.         UBYTE ret = 0;
  182.         //set address
  183.         if ( tw_send_start() & (TW_START|TW_REP_START) )
  184.         {
  185.                 if ( tw_send_addr(RTC_ADDRESS) == TW_MT_SLA_ACK )
  186.                 {
  187.                         if ( tw_send_data(addr) == TW_MT_DATA_ACK )
  188.                         {
  189.                                 //read data
  190.                                 if ( tw_send_start() == TW_REP_START )
  191.                                 {
  192.                                         if ( tw_send_addr(RTC_ADDRESS|0x01) == TW_MR_SLA_ACK )
  193.                                         {
  194.                                                 tw_read_data(&ret);
  195.                                         }
  196.                                 }
  197.                         }
  198.                 }
  199.         }
  200.         tw_send_stop();
  201.         return ret;
  202. }
  203.  
  204. void gluk_init(void)
  205. {
  206.         UBYTE tmp;
  207.         //default values
  208.         gluk_regs[GLUK_REG_A] = 0x00;
  209.         gluk_regs[GLUK_REG_B] = 0x02;
  210.         gluk_regs[GLUK_REG_C] = 0x00;
  211.         gluk_regs[GLUK_REG_D] = 0x80;
  212.  
  213.         //setup
  214.  
  215.         //read month and day of week
  216.         tmp = rtc_read(6);
  217.         gluk_regs[GLUK_REG_MONTH] = bcd_to_hex(0x1F&tmp);
  218.         gluk_regs[GLUK_REG_DAY_WEEK] = tmp>>5;
  219.  
  220.         //read year and day of month
  221.         tmp = rtc_read(5);
  222.         gluk_regs[GLUK_REG_DAY_MONTH] = bcd_to_hex(0x3F&tmp);
  223.         gluk_regs[GLUK_REG_YEAR] = tmp>>6;
  224.         tmp = rtc_read(RTC_YEAR_ADD_REG);
  225.         if ( (tmp&0x03) > gluk_regs[GLUK_REG_YEAR] )
  226.         {
  227.                 //count of year over - correct year
  228.                 tmp += 4;
  229.                 if ( tmp >= 100 ) tmp = 0;
  230.         }
  231.         gluk_regs[GLUK_REG_YEAR] += tmp&0xFC;
  232.         rtc_write(RTC_YEAR_ADD_REG,gluk_regs[GLUK_REG_YEAR]); //save year
  233.  
  234.         //read time
  235.         gluk_regs[GLUK_REG_HOUR] = bcd_to_hex(0x3F&rtc_read(4)); //TODO 12/24 format
  236.         gluk_regs[GLUK_REG_MIN] = bcd_to_hex(rtc_read(3));
  237.         gluk_regs[GLUK_REG_SEC] = bcd_to_hex(rtc_read(2));
  238. }
  239.  
  240. void gluk_inc(void)
  241. {
  242.         if ( ++gluk_regs[GLUK_REG_SEC] >= 60 )
  243.         {
  244.                 gluk_regs[GLUK_REG_SEC] = 0;
  245.                 if ( ++gluk_regs[GLUK_REG_MIN] >= 60 )
  246.                 {
  247.                         gluk_regs[GLUK_REG_MIN] = 0;
  248.                         if ( ++gluk_regs[GLUK_REG_HOUR] >= 24 )
  249.                         {
  250.                                 gluk_regs[GLUK_REG_HOUR] = 0;
  251.                                 if ( ++gluk_regs[GLUK_REG_DAY_WEEK] > 7  )
  252.                                 {
  253.                                         gluk_regs[GLUK_REG_DAY_WEEK] = 1;
  254.                                 }
  255.                                 if ( ++gluk_regs[GLUK_REG_DAY_MONTH] > days_of_months() )
  256.                                 {
  257.                                         gluk_regs[GLUK_REG_DAY_MONTH] = 1;
  258.                                         if ( ++gluk_regs[GLUK_REG_MONTH] > 12 )
  259.                                         {
  260.                                                 gluk_regs[GLUK_REG_MONTH] = 1;
  261.                                                 if( ++gluk_regs[GLUK_REG_YEAR] >= 100 )
  262.                                                 {
  263.                                                         gluk_regs[GLUK_REG_YEAR] = 0;
  264.                                                 }
  265.                                         }
  266.                                 }
  267.                         }
  268.                 }
  269.         }
  270.  
  271.         //set update flag
  272.         gluk_regs[GLUK_REG_C] |= GLUK_C_UPDATE_FLAG;
  273.  
  274. //#ifdef LOGENABLE
  275. //{
  276. //      char log_int_rtc[] = "00.00.00\r\n";
  277. //      log_int_rtc[0] = '0' + gluk_regs[GLUK_REG_HOUR]/10;
  278. //      log_int_rtc[1] = '0' + gluk_regs[GLUK_REG_HOUR]%10;
  279. //      log_int_rtc[3] = '0' + gluk_regs[GLUK_REG_MIN]/10;
  280. //      log_int_rtc[4] = '0' + gluk_regs[GLUK_REG_MIN]%10;
  281. //      log_int_rtc[6] = '0' + gluk_regs[GLUK_REG_SEC]/10;
  282. //      log_int_rtc[7] = '0' + gluk_regs[GLUK_REG_SEC]%10;
  283. //      to_log(log_int_rtc);
  284. //}
  285. //#endif
  286. }
  287.  
  288. UBYTE gluk_get_reg(UBYTE index)
  289. {
  290.         if( index < sizeof(gluk_regs)/sizeof(gluk_regs[0]) )
  291.         {
  292.                 //clock registers from array
  293.                 UBYTE tmp = gluk_regs[index];
  294.                 if ( ( index<10 ) && ( (gluk_regs[GLUK_REG_B]&GLUK_B_DATA_MODE) == 0 ) )
  295.                 {
  296.                         //clock registers mast be in BCD if HEX-bit not set in reg B
  297.                         tmp = hex_to_bcd(tmp);
  298.                 }
  299.  
  300.                 if ( index == GLUK_REG_C )
  301.                 {
  302.                         //clear update flag
  303.                         gluk_regs[GLUK_REG_C] &= ~GLUK_C_UPDATE_FLAG;
  304.                 }
  305.  
  306.                 return tmp;
  307.         }
  308.         else
  309.         {
  310.                 if ( index >= 0xF0 )
  311.                 {
  312.                         //read version
  313.                         return GetVersionByte( index&0x0F );
  314.                 }
  315.  
  316.                 //other from nvram
  317.                 //- on PCF8583 nvram started from #10
  318.                 //- on 512vi1[DS12887] nvram started from #0E
  319.                 return rtc_read( (index&0x3F)+2 );
  320.         }
  321. }
  322.  
  323. void gluk_set_reg(UBYTE index, UBYTE data)
  324. {
  325.         if( index < sizeof(gluk_regs)/sizeof(gluk_regs[0]) )
  326.         {
  327.                 if ( index<10 )
  328.                 {
  329.                         //write to clock registers
  330.                         if ( (gluk_regs[GLUK_REG_B]&GLUK_B_DATA_MODE) == 0 )
  331.                         {
  332.                                 //array of registers must be in Hex, but data in BCD if HEX-bit not set in reg B
  333.                                 data = bcd_to_hex(data);
  334.                         }
  335.                         gluk_regs[index] = data;
  336.  
  337.                         //write to nvram if need
  338.                         switch( index )
  339.                         {
  340.                                 case GLUK_REG_SEC:
  341.                                         rtc_write(2, hex_to_bcd(gluk_regs[GLUK_REG_SEC]));
  342.                                         break;
  343.                                 case GLUK_REG_MIN:
  344.                                         rtc_write(3, hex_to_bcd(gluk_regs[GLUK_REG_MIN]));
  345.                                         break;
  346.                                 case GLUK_REG_HOUR:
  347.                                         rtc_write(4, 0x3F&hex_to_bcd(gluk_regs[GLUK_REG_HOUR]));
  348.                                         break;
  349.                                 case GLUK_REG_MONTH:
  350.                                 case GLUK_REG_DAY_WEEK:
  351.                                         rtc_write(6, (hex_to_bcd(gluk_regs[GLUK_REG_DAY_WEEK])<<5)+(0x1F&hex_to_bcd(gluk_regs[GLUK_REG_MONTH])));
  352.                                         break;
  353.                                 case GLUK_REG_YEAR:
  354.                                         rtc_write(RTC_YEAR_ADD_REG, gluk_regs[GLUK_REG_YEAR]);
  355.                                 case GLUK_REG_DAY_MONTH:
  356.                                         rtc_write(5, (gluk_regs[GLUK_REG_YEAR]<<6)+(0x3F&hex_to_bcd(gluk_regs[GLUK_REG_DAY_MONTH])));
  357.                                         break;
  358.                         }
  359.                 }
  360.         }
  361.         else
  362.         {
  363.                 if ( index >= 0xF0 )
  364.                 {
  365.                         //set version data type
  366.                         SetVersionType( data );
  367.                 }
  368.                 else
  369.                 {
  370.                         //write to nvram
  371.                         //- on PCF8583 nvram started from #10
  372.                         //- on 512vi1[DS12887] nvram started from #0E
  373.                         rtc_write( (index&0x3F)+2, data);
  374.                 }
  375.         }
  376. }
  377.