Nav apraksta

rtc.c 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include <pokeagb/pokeagb.h>
  2. #include <rtc.h>
  3. #define HIGH 1
  4. #define LOW 0
  5. #define IN 0
  6. #define OUT 1
  7. #define SCK 0
  8. #define SIO 1
  9. #define CS 2
  10. struct RtcGpioDataStruct {
  11. u16 sck : 1;
  12. u16 sio : 1;
  13. u16 cs : 1;
  14. u16 unused : 1;
  15. u16 free : 12;
  16. };
  17. union RtcGpioData {
  18. struct RtcGpioDataStruct ports;
  19. u16 packed;
  20. };
  21. ASSERT_SIZEOF(union RtcGpioData, 2);
  22. struct RtcGpioDirectionStruct {
  23. u16 sck : 1;
  24. u16 sio : 1;
  25. u16 cs : 1;
  26. u16 unused : 1;
  27. u16 free : 12;
  28. };
  29. union RtcGpioDirection {
  30. struct RtcGpioDirectionStruct ports;
  31. u16 packed;
  32. };
  33. ASSERT_SIZEOF(union RtcGpioDirection, 2);
  34. extern union RtcGpioData rtc_data;
  35. extern union RtcGpioDirection rtc_direction;
  36. extern u16 rtc_control;
  37. void rtc_wait_cycles(volatile u16 cycles);
  38. void rtc_write(u8 b);
  39. void rtc_block_wait(void);
  40. void rtc_gpio_set_data(bool sck, bool sio, bool cs);
  41. u8 rtc_read(void);
  42. void rtc_get_time(struct RtcTimestamp* out)
  43. {
  44. rtc_control = 1;
  45. //rtc_direction.sck = OUT;
  46. //rtc_direction.cs = OUT;
  47. rtc_direction.packed = 5;
  48. rtc_control = 1;
  49. rtc_direction.packed = 7;
  50. rtc_gpio_set_data(HIGH, LOW, LOW);
  51. //rtc_data.cs = LOW;
  52. //rtc_data.sck = HIGH;
  53. rtc_block_wait();
  54. rtc_gpio_set_data(HIGH,LOW,HIGH);
  55. rtc_block_wait();
  56. //rtc_direction.packed = ( (OUT << SCK) | (OUT << CS) | (OUT << SIO));
  57. //rtc_direction.sck = OUT;
  58. //rtc_direction.cs = OUT;
  59. rtc_write(0x65);
  60. out->year = rtc_read();
  61. out->month = rtc_read();
  62. out->day = rtc_read();
  63. out->day_of_week = rtc_read();
  64. out->hour = rtc_read();
  65. out->minute = rtc_read();
  66. out->second = rtc_read();
  67. rtc_data.packed = 0;
  68. //rtc_data.sck = LOW;
  69. //rtc_data.sio = LOW;
  70. //rtc_data.cs = LOW;
  71. }
  72. void rtc_write(u8 b){
  73. //all out
  74. rtc_direction.packed = 7;
  75. for(u8 i = 8; i > 0; ++i) {
  76. u8 bit = (u8) ((b & 0x80) >> 7);
  77. b <<= 1;
  78. rtc_gpio_set_data(LOW,bit,LOW);
  79. rtc_block_wait();
  80. rtc_gpio_set_data(HIGH,bit,LOW);
  81. rtc_block_wait();
  82. }
  83. }
  84. u8 rtc_read(void){
  85. u16 val = 0;
  86. rtc_direction.packed = 5;
  87. //rtc_direction.sio = IN;
  88. //rtc_direction.sck = OUT;
  89. for(u8 i = 0; i < 8; ++i) {
  90. rtc_gpio_set_data(LOW,LOW,LOW);
  91. //rtc_data.sck = LOW;
  92. rtc_block_wait();
  93. rtc_gpio_set_data(HIGH,LOW,LOW);
  94. //rtc_data.sck = HIGH;
  95. rtc_block_wait();
  96. val |= ((rtc_data.ports.sio) << i);
  97. }
  98. return (u8)(val >> 1);
  99. }
  100. void rtc_block_wait(void) {
  101. u8 i = 100;
  102. while (i--) {
  103. __asm__ __volatile__
  104. (
  105. "nop\n\r"
  106. );
  107. }
  108. }
  109. //this is a blocking wait, because fk IRQ
  110. void rtc_wait_cycles(volatile u16 cycles)
  111. {
  112. while(cycles > 0)
  113. {
  114. cycles--;
  115. }
  116. }
  117. void rtc_gpio_set_data(bool sck, bool sio, bool cs) {
  118. u16 value = (u16) (sck | (sio << 1) | (cs << 2));
  119. rtc_data.packed = value;
  120. }