1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author         Notes
8  * 2019-07-29     zdzn           first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <sys/time.h>
14 #include "drv_rtc.h"
15 
16 #ifdef BSP_USING_RTC
17 
18 #define RTC_I2C_BUS_NAME      "i2c0"
19 #define RTC_ADDR               0x68
20 
21 static struct rt_device rtc_device;
22 static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
23 
24 rt_uint8_t buf[]=
25 {
26     0x00, 0x00, 0x43, 0x15, 0x05, 0x01, 0x03, 0x19
27 };
28 
29 
i2c_write_read_rs(char * cmds,rt_uint32_t cmds_len,char * buf,rt_uint32_t buf_len)30 rt_uint8_t i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len)
31 {
32     rt_uint32_t remaining = cmds_len;
33     rt_uint32_t i = 0;
34     rt_uint8_t reason = BCM283X_I2C_REASON_OK;
35 
36     /* Clear FIFO */
37     BCM283X_BSC_C(BCM283X_BSC0_BASE) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1);
38 
39     /* Clear Status */
40     BCM283X_BSC_S(BCM283X_BSC0_BASE) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
41 
42     /* Set Data Length */
43     BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = cmds_len;
44 
45     /* pre populate FIFO with max buffer */
46     while (remaining && (i < BSC_FIFO_SIZE))
47     {
48         BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = cmds[i];
49         i++;
50         remaining--;
51     }
52 
53     /* Enable device and start transfer */
54     BCM283X_BSC_C(BCM283X_BSC0_BASE) |= BSC_C_I2CEN | BSC_C_ST;
55 
56     /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */
57     while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_TA))
58     {
59         /* Linux may cause us to miss entire transfer stage */
60         if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE)
61             break;
62     }
63 
64     remaining = buf_len;
65     i = 0;
66 
67     /* Send a repeated start with read bit set in address */
68     BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = buf_len;
69     BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_C_I2CEN | BSC_C_ST  | BSC_C_READ;
70 
71     /* Wait for write to complete and first byte back. */
72   //  DELAYMICROS(i2c_byte_wait_us * (cmds_len + 1));
73 
74     /* wait for transfer to complete */
75     while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE))
76     {
77         /* we must empty the FIFO as it is populated and not use any delay */
78         while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_RXD))
79         {
80         /* Read from FIFO, no barrier */
81         buf[i] = BCM283X_BSC_FIFO(BCM283X_BSC0_BASE);
82         i++;
83         remaining--;
84         }
85     }
86 
87     /* transfer has finished - grab any remaining stuff in FIFO */
88     while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_RXD))
89     {
90         /* Read from FIFO */
91         buf[i] = BCM283X_BSC_FIFO(BCM283X_BSC0_BASE);
92         i++;
93         remaining--;
94     }
95 
96     /* Received a NACK */
97     if (BCM283X_BSC_S(BCM283X_BSC0_BASE)  & BSC_S_ERR)
98     {
99         reason = BCM283X_I2C_REASON_ERROR_NACK;
100     }
101 
102     /* Received Clock Stretch Timeout */
103     else if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_CLKT)
104     {
105         reason = BCM283X_I2C_REASON_ERROR_CLKT;
106     }
107 
108     /* Not all data is sent */
109     else if (remaining)
110     {
111         reason = BCM283X_I2C_REASON_ERROR_DATA;
112     }
113 
114     BCM283X_BSC_C(BCM283X_BSC0_BASE) = (BSC_S_DONE &BSC_S_DONE);
115 
116     return reason;
117 }
118 
i2c_write(rt_uint8_t * buf,rt_uint32_t len)119 rt_uint8_t i2c_write(rt_uint8_t* buf, rt_uint32_t len)
120 {
121     rt_uint32_t remaining = len;
122     rt_uint32_t i = 0;
123     rt_uint8_t reason = BCM283X_I2C_REASON_OK;
124 
125     /* Clear FIFO */
126     BCM283X_BSC_C(BCM283X_BSC0_BASE)  |= BSC_C_CLEAR_1 & BSC_C_CLEAR_1;
127     /* Clear Status */
128     BCM283X_BSC_S(BCM283X_BSC0_BASE) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
129     /* Set Data Length */
130     BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = len;
131     /* pre populate FIFO with max buffer */
132     while (remaining && (i < BSC_FIFO_SIZE))
133     {
134         BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = buf[i];
135         i++;
136         remaining--;
137     }
138 
139     /* Enable device and start transfer */
140     BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_C_I2CEN | BSC_C_ST;
141 
142     /* Transfer is over when BCM2835_BSC_S_DONE */
143     while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE))
144     {
145         while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_TXD))
146         {
147         /* Write to FIFO */
148         BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = buf[i];
149         i++;
150         remaining--;
151         }
152     }
153 
154     /* Received a NACK */
155     if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_ERR)
156     {
157         reason = BCM283X_I2C_REASON_ERROR_NACK;
158     }
159 
160     /* Received Clock Stretch Timeout */
161     else if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_CLKT)
162     {
163         reason = BCM283X_I2C_REASON_ERROR_CLKT;
164     }
165 
166     /* Not all data is sent */
167     else if (remaining)
168     {
169         reason = BCM283X_I2C_REASON_ERROR_DATA;
170     }
171 
172     BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_S_DONE & BSC_S_DONE;
173     return reason;
174 }
175 
176 
raspi_get_timestamp(void)177 static time_t raspi_get_timestamp(void)
178 {
179     struct tm tm_new = {0};
180     buf[0] = 0;
181 
182     i2c_write_read_rs((char*)buf, 1, (char*)buf, 7);
183 
184     tm_new.tm_year = ((buf[6] / 16) + 0x30) * 10 + (buf[6] % 16) + 0x30;
185     tm_new.tm_mon  = ((buf[5] & 0x1F) / 16 + 0x30) + (buf[5] & 0x1F) % 16+ 0x30;
186     tm_new.tm_mday = ((buf[4] & 0x3F) / 16 + 0x30) + (buf[4] & 0x3F) % 16+ 0x30;
187     tm_new.tm_hour = ((buf[2] & 0x3F) / 16 + 0x30) + (buf[2] & 0x3F) % 16+ 0x30;
188     tm_new.tm_min  = ((buf[1] & 0x7F) / 16 + 0x30) + (buf[1] & 0x7F) % 16+ 0x30;
189     tm_new.tm_sec  = ((buf[0] & 0x7F) / 16 + 0x30) + (buf[0] & 0x7F) % 16+ 0x30;
190 
191     return timegm(&tm_new);
192 }
193 
raspi_set_timestamp(time_t timestamp)194 static int raspi_set_timestamp(time_t timestamp)
195 {
196     struct tm tblock;
197     gmtime_r(&timestamp, &tblock);
198     buf[0] = 0;
199     buf[1] = tblock.tm_sec;
200     buf[2] = tblock.tm_min;
201     buf[3] = tblock.tm_hour;
202     buf[4] = tblock.tm_wday;
203     buf[5] = tblock.tm_mday;
204     buf[6] = tblock.tm_mon;
205     buf[7] = tblock.tm_year;
206 
207     i2c_write(buf, 8);
208 
209     return RT_EOK;
210 }
211 
raspi_rtc_init(rt_device_t dev)212 static rt_err_t raspi_rtc_init(rt_device_t dev)
213 {
214     i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(RTC_I2C_BUS_NAME);
215     raspi_set_timestamp(0);
216     return RT_EOK;
217 }
218 
raspi_rtc_open(rt_device_t dev,rt_uint16_t oflag)219 static rt_err_t raspi_rtc_open(rt_device_t dev, rt_uint16_t oflag)
220 {
221     GPIO_FSEL(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_ALT0); /* SDA */
222     GPIO_FSEL(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_ALT0); /* SCL */
223     return RT_EOK;
224 }
225 
raspi_rtc_close(rt_device_t dev)226 static rt_err_t raspi_rtc_close(rt_device_t dev)
227 {
228     GPIO_FSEL(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_INPT); /* SDA */
229     GPIO_FSEL(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_INPT); /* SCL */
230     return RT_EOK;
231 }
232 
raspi_rtc_control(rt_device_t dev,int cmd,void * args)233 static rt_err_t raspi_rtc_control(rt_device_t dev, int cmd, void *args)
234 {
235 
236     RT_ASSERT(dev != RT_NULL);
237 
238     switch (cmd)
239     {
240     case RT_DEVICE_CTRL_RTC_GET_TIME:
241         *(rt_uint32_t *)args = raspi_get_timestamp();
242         break;
243     case RT_DEVICE_CTRL_RTC_SET_TIME:
244         raspi_set_timestamp(*(time_t *)args);
245         break;
246     default:
247         return -RT_EINVAL;
248     }
249     return RT_EOK;
250 }
251 
raspi_rtc_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)252 static rt_ssize_t raspi_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
253 {
254     raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
255     return size;
256 }
257 
raspi_rtc_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)258 static rt_ssize_t raspi_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
259 {
260     raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
261     return size;
262 }
263 
264 #ifdef RT_USING_DEVICE_OPS
265 const static struct rt_device_ops raspi_rtc_ops =
266 {
267     .init = raspi_rtc_init,
268     .open = raspi_rtc_open,
269     .close = raspi_rtc_close,
270     .read = raspi_rtc_read,
271     .write = raspi_rtc_write,
272     .control = raspi_rtc_control
273 };
274 #endif
275 
rt_hw_rtc_init(void)276 int rt_hw_rtc_init(void)
277 {
278     rt_err_t ret = RT_EOK;
279 
280     rtc_device.type        = RT_Device_Class_RTC;
281     rtc_device.rx_indicate = RT_NULL;
282     rtc_device.tx_complete = RT_NULL;
283 
284 #ifdef RT_USING_DEVICE_OPS
285     rtc_device.ops        = &raspi_rtc_ops;
286 #else
287     rtc_device.init    = raspi_rtc_init;
288     rtc_device.open    = raspi_rtc_open;
289     rtc_device.close   = raspi_rtc_close;
290     rtc_device.read    = raspi_rtc_read;
291     rtc_device.write   = raspi_rtc_write;
292     rtc_device.control = raspi_rtc_control;
293 #endif
294 
295     rtc_device.user_data   = RT_NULL;
296 
297     /* register a rtc device */
298     ret = rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
299 
300     return ret;
301 }
302 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
303 #endif /* BSP_USING_RTC */
304 
305