diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_rtc.c b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_rtc.c new file mode 100644 index 00000000000..533132b7884 --- /dev/null +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_rtc.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-06-18 wenzhi346 add NS800 rtc driver + */ +#include +#include +#include +#include "ds1307.h" + +static struct rt_device g_rtc_dev; + +static rt_err_t ns800_rtc_init(struct rt_device *dev) +{ + uint8_t sec; + rt_err_t ret; + + ret = ds1307_init(); + if (ret != RT_EOK) + { + rt_kprintf("ds1307: i2c bus not found\n"); + return ret; + } + + return RT_EOK; +} + +static rt_err_t ns800_rtc_control(struct rt_device *dev, int cmd, void *args) +{ + rt_err_t result = RT_EOK; + struct tm time_struct; + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + result = ds1307_get_time(&time_struct); + if (result == RT_EOK) + *(time_t *)args = mktime(&time_struct); + break; + + case RT_DEVICE_CTRL_RTC_SET_TIME: + result = ds1307_set_time(localtime((const time_t *)args)); + break; + + default: + result = -RT_ENOSYS; + break; + } + + return result; +} + +int rt_hw_rtc_init(void) +{ + rt_err_t result; + + g_rtc_dev.type = RT_Device_Class_RTC; + g_rtc_dev.init = ns800_rtc_init; + g_rtc_dev.open = RT_NULL; + g_rtc_dev.close = RT_NULL; + g_rtc_dev.read = RT_NULL; + g_rtc_dev.write = RT_NULL; + g_rtc_dev.control = ns800_rtc_control; + + result = rt_device_register(&g_rtc_dev, "rtc", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE); + if (result != RT_EOK) + { + rt_kprintf("rtc register failed\n"); + return -1; + } + + result = ns800_rtc_init(&g_rtc_dev); + if (result != RT_EOK) + { + rt_kprintf("ds1307 init failed\n"); + return -1; + } + + rt_kprintf("ds1307 rtc ready\n"); + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_rtc_init); diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_rtc.h b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_rtc.h new file mode 100644 index 00000000000..151f1ba5617 --- /dev/null +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_rtc.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#ifndef __DRV_RTC_H__ +#define __DRV_RTC_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +int rt_hw_rtc_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __DRV_RTC_H__ */ diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/ds1307.c b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/ds1307.c new file mode 100644 index 00000000000..8592af92722 --- /dev/null +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/ds1307.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-06-18 coworkspace first version + */ + +#include +#include +#include +#include "ds1307.h" + +#define DS1307_ADDR 0x68 + +static struct rt_i2c_bus_device *ds1307_i2c = RT_NULL; + +rt_err_t ds1307_init(void) +{ + ds1307_i2c = (struct rt_i2c_bus_device *)rt_device_find("i2c1"); + if (ds1307_i2c == RT_NULL) + return -RT_ERROR; + + return RT_EOK; +} + +static rt_err_t read_regs(uint8_t reg, uint8_t *buf, uint8_t len) +{ + struct rt_i2c_msg msgs[2]; + + msgs[0].addr = DS1307_ADDR; + msgs[0].flags = RT_I2C_WR; + msgs[0].len = 1; + msgs[0].buf = ® + + msgs[1].addr = DS1307_ADDR; + msgs[1].flags = RT_I2C_RD; + msgs[1].len = len; + msgs[1].buf = buf; + + return (rt_i2c_transfer(ds1307_i2c, msgs, 2) == 2) ? RT_EOK : -RT_ERROR; +} + +static rt_err_t write_reg(uint8_t reg, uint8_t val) +{ + uint8_t buf[2] = {reg, val}; + + return (rt_i2c_master_send(ds1307_i2c, DS1307_ADDR, 0, buf, 2) == 2) + ? RT_EOK : -RT_ERROR; +} + +static uint8_t bcd2bin(uint8_t bcd) +{ + return ((bcd >> 4) * 10) + (bcd & 0x0F); +} + +static uint8_t bin2bcd(uint8_t val) +{ + return ((val / 10) << 4) | (val % 10); +} + +rt_err_t ds1307_get_time(struct tm *tm) +{ + uint8_t buf[7]; + + if (read_regs(0x00, buf, 7) != RT_EOK) + return -RT_ERROR; + + memset(tm, 0, sizeof(*tm)); + tm->tm_sec = bcd2bin(buf[0] & 0x7F); + tm->tm_min = bcd2bin(buf[1] & 0x7F); + tm->tm_hour = bcd2bin(buf[2] & 0x3F); + tm->tm_mday = bcd2bin(buf[3] & 0x3F); + tm->tm_wday = buf[4] & 0x07; + tm->tm_mon = bcd2bin(buf[5] & 0x1F) - 1; + tm->tm_year = bcd2bin(buf[6]) + 100; + + return RT_EOK; +} + +rt_err_t ds1307_set_time(struct tm *tm) +{ + uint8_t v; + + v = bin2bcd(tm->tm_year - 100); + if (write_reg(0x06, v) != RT_EOK) return -RT_ERROR; + + v = bin2bcd(tm->tm_mon + 1); + if (write_reg(0x05, v) != RT_EOK) return -RT_ERROR; + + v = bin2bcd(tm->tm_mday); + if (write_reg(0x04, v) != RT_EOK) return -RT_ERROR; + + v = tm->tm_wday & 0x07; + if (write_reg(0x03, v) != RT_EOK) return -RT_ERROR; + + v = bin2bcd(tm->tm_hour); + if (write_reg(0x02, v) != RT_EOK) return -RT_ERROR; + + v = bin2bcd(tm->tm_min); + if (write_reg(0x01, v) != RT_EOK) return -RT_ERROR; + + v = bin2bcd(tm->tm_sec); + if (write_reg(0x00, v) != RT_EOK) return -RT_ERROR; + + return RT_EOK; +} diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/ds1307.h b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/ds1307.h new file mode 100644 index 00000000000..4e3bc04db37 --- /dev/null +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/ds1307.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-06-18 coworkspace first version + */ +#ifndef __DS1307_H__ +#define __DS1307_H__ + +#include +#include + +rt_err_t ds1307_init(void); +rt_err_t ds1307_get_time(struct tm *time); +rt_err_t ds1307_set_time(struct tm *time); + +#endif