|
2 | 2 | #include "bcp.h"
|
3 | 3 | #include "macros.h"
|
4 | 4 |
|
| 5 | +#define RTC_MASK ((PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)) |
| 6 | + |
| 7 | +#define RTC_ADDR 0xD0 |
| 8 | +#define RTC_WR 0 |
| 9 | +#define RTC_RD 1 |
| 10 | + |
5 | 11 | void __osBbDelay(u32 usec);
|
6 | 12 |
|
7 | 13 | static void write_rtc(u32 x) {
|
8 |
| - IO_WRITE(PI_60_REG, x); |
| 14 | + IO_WRITE(PI_GPIO_REG, x); |
9 | 15 | __osBbDelay(2);
|
10 | 16 | }
|
11 | 17 |
|
12 | 18 | static void send_start(u8 write) {
|
13 | 19 | u32 i;
|
14 | 20 | u32 j;
|
15 |
| - u32 mask = IO_READ(PI_60_REG) & ~0xCC; |
| 21 | + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; |
16 | 22 | u8 byte[2];
|
17 | 23 |
|
18 |
| - byte[0] = (!write) ? 0xD1 : 0xD0; |
| 24 | + byte[0] = (!write) ? (RTC_ADDR | RTC_RD) : (RTC_ADDR | RTC_WR); |
19 | 25 | byte[1] = 0;
|
20 | 26 |
|
21 |
| - write_rtc(mask | 0xC4); |
22 |
| - write_rtc(mask | 0xC0); |
| 27 | + // Send start signal (DAT HIGH -> LOW while CLK HIGH) assuming both CLK and DAT were initially HIGH |
| 28 | + // Cyc -1 | 0 | 1 |
| 29 | + // CLK ‾‾‾|‾‾‾|___ |
| 30 | + // DAT ‾‾‾|___|___ |
| 31 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
| 32 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
23 | 33 |
|
24 | 34 | for (i = 0; i < write + 1; i++) {
|
| 35 | + // Send address in byte[0], for writes also send word address in byte[1] |
25 | 36 | for (j = 0; j < 8; j++) {
|
26 |
| - u32 b = ((byte[i] >> (7 - j)) & 1) ? 8 : 0; |
27 |
| - |
28 |
| - write_rtc(mask | (0x80 | b) | 0x40); |
29 |
| - write_rtc(mask | (0x80 | b) | 0x44); |
30 |
| - write_rtc(mask | (0x80 | b) | 0x40); |
| 37 | + u32 b = ((byte[i] >> (7 - j)) & 1) ? PI_GPIO_RTC_DAT_HI : PI_GPIO_RTC_DAT_LO; |
| 38 | + |
| 39 | + // Transmit single bit to the RTC |
| 40 | + // Cyc 0 | 1 | 2 |
| 41 | + // CLK ___|‾‾‾|___ |
| 42 | + // DAT b | b | b |
| 43 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 44 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
| 45 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
31 | 46 | }
|
32 |
| - write_rtc(mask | 0x40); |
33 |
| - write_rtc(mask | 0x44); |
| 47 | + |
| 48 | + // Toggle CLK to receive ACK from the RTC, but don't read it |
| 49 | + // Cyc 0 | 1 |
| 50 | + // CLK ___|‾‾‾ |
| 51 | + // DAT x | x |
| 52 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 53 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
34 | 54 | }
|
35 |
| - write_rtc(mask | 0x40); |
| 55 | + |
| 56 | + // End on CLK LOW |
| 57 | + // Cyc 0 |
| 58 | + // CLK ___ |
| 59 | + // DAT x |
| 60 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
36 | 61 | }
|
37 | 62 |
|
38 | 63 | static void send_stop(void) {
|
39 |
| - u32 mask = IO_READ(PI_60_REG) & ~0xCC; |
40 |
| - write_rtc(mask | 0x80 | 0x40); |
41 |
| - write_rtc(mask | 0x80 | 0x44); |
42 |
| - write_rtc(mask | 0x80 | 0x4C); |
| 64 | + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; |
| 65 | + |
| 66 | + // Send stop signal (DAT LOW -> HIGH while CLK HIGH) |
| 67 | + // Cyc 0 | 1 | 2 |
| 68 | + // CLK ___|‾‾‾|‾‾‾ |
| 69 | + // DAT ___|___|‾‾‾ |
| 70 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 71 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
| 72 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
43 | 73 | }
|
44 | 74 |
|
45 | 75 | static void read_bytes(u8* bytes, u8 len) {
|
46 | 76 | u32 ack;
|
47 | 77 | u32 i;
|
48 |
| - u32 mask = IO_READ(PI_60_REG) & ~0xCC; |
| 78 | + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; |
49 | 79 |
|
50 | 80 | while (len-- > 0) {
|
51 | 81 | u32 x = 0;
|
52 | 82 |
|
| 83 | + // Read 1 byte |
53 | 84 | for (i = 0; i < 8; i++) {
|
54 |
| - write_rtc(mask | 0x40); |
55 |
| - write_rtc(mask | 0x44); |
| 85 | + // Toggle CLK to receive the bit from the RTC |
| 86 | + // Cyc 0 | 1 |
| 87 | + // CLK ___|‾‾‾ |
| 88 | + // DAT x | x |
| 89 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 90 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
| 91 | + |
| 92 | + // Read the bit sent by the RTC |
56 | 93 | x <<= 1;
|
57 |
| - x |= (IO_READ(PI_60_REG) >> 3) & 1; |
| 94 | + x |= PI_GPIO_GET_RTC_DAT(IO_READ(PI_GPIO_REG)); |
58 | 95 | }
|
59 | 96 | *(bytes++) = x;
|
60 | 97 |
|
61 |
| - ack = (len == 0) ? 0x88 : 0x80; |
| 98 | + ack = (len == 0) ? (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) : (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO); |
62 | 99 |
|
63 |
| - write_rtc(mask | 0x40 | 0x80); |
64 |
| - write_rtc(mask | 0x44 | ack); |
| 100 | + // Send ACK or NACK, DAT HIGH is NACK while DAT LOW is ACK. NACK is sent at th end. |
| 101 | + // Cyc 0 | 1 |
| 102 | + // CLK ___|‾‾‾ |
| 103 | + // DAT ___| a |
| 104 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 105 | + write_rtc(mask | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI) | ack); |
65 | 106 | }
|
66 | 107 | send_stop();
|
67 | 108 | }
|
68 | 109 |
|
69 | 110 | static void write_bytes(u8* bytes, u8 len) {
|
70 | 111 | u32 i;
|
71 |
| - u32 mask = IO_READ(PI_60_REG) & ~0xCC; |
| 112 | + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; |
72 | 113 |
|
73 | 114 | while (len-- > 0) {
|
74 | 115 | u32 x = *(bytes++);
|
75 | 116 |
|
76 | 117 | for (i = 0; i < 8; i++) {
|
77 |
| - u32 b = (x & 0x80) ? 8 : 0; |
78 |
| - |
79 |
| - write_rtc(mask | (0x80 | b) | 0x40); |
80 |
| - write_rtc(mask | (0x80 | b) | 0x44); |
81 |
| - write_rtc(mask | (0x80 | b) | 0x44); |
| 118 | + u32 b = (x & 0x80) ? PI_GPIO_RTC_DAT_HI : PI_GPIO_RTC_DAT_LO; |
| 119 | + |
| 120 | + // Transmit single bit to the RTC |
| 121 | + // Cyc 0 | 1 | 2 |
| 122 | + // CLK ___|‾‾‾|‾‾‾ |
| 123 | + // DAT b | b | b |
| 124 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 125 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
| 126 | + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
82 | 127 | x <<= 1;
|
83 | 128 | }
|
84 |
| - write_rtc(mask | 0x40); |
85 |
| - write_rtc(mask | 0x44); |
86 |
| - IO_READ(PI_60_REG); |
87 |
| - write_rtc(mask | 0x40); |
| 129 | + |
| 130 | + // Toggle CLK to receive ACK from the RTC, read but don't check? |
| 131 | + // Cyc 0 | 1 | 2 | 3 |
| 132 | + // CLK ___|‾‾‾|‾‾‾|___ |
| 133 | + // DAT x | x | x | x |
| 134 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
| 135 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
| 136 | + IO_READ(PI_GPIO_REG); |
| 137 | + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); |
88 | 138 | }
|
89 | 139 | send_stop();
|
90 | 140 | }
|
91 | 141 |
|
92 | 142 | void osBbRtcInit(void) {
|
93 |
| - write_rtc(IO_READ(PI_60_REG) | 0xCC); |
| 143 | + // Set line state to idle (both CLK and DAT HIGH) |
| 144 | + // Cyc 0 |
| 145 | + // CLK ‾‾‾ |
| 146 | + // DAT ‾‾‾ |
| 147 | + write_rtc(IO_READ(PI_GPIO_REG) | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); |
94 | 148 | }
|
95 | 149 |
|
96 | 150 | void osBbRtcSet(u8 year, u8 month, u8 day, u8 dow, u8 hour, u8 min, u8 sec) {
|
|
0 commit comments