diff --git a/bsp/ls2kdev/drivers/drv_rtc.c b/bsp/ls2kdev/drivers/drv_rtc.c new file mode 100644 index 0000000000..3a873cc6fc --- /dev/null +++ b/bsp/ls2kdev/drivers/drv_rtc.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2020, Du Huanpeng <548708880@qq.com> + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-01-30 armink the first version + * 2020-06-23 Du Huanpeng based on components/drivers/rtc/soft_rtc.c + */ + + +#include +#include +#include +#include +#include "ls2k1000.h" + +struct loongson_rtc { + rt_uint32_t sys_toytrim; + rt_uint32_t sys_toywrite0; + rt_uint32_t sys_toywrite1; + rt_uint32_t sys_toyread0; + rt_uint32_t sys_toyread1; + rt_uint32_t sys_toymatch0; + rt_uint32_t sys_toymatch1; + rt_uint32_t sys_toymatch2; + rt_uint32_t sys_rtcctrl; + rt_uint32_t __pad4[3]; + rt_uint32_t __pad5[4]; + rt_uint32_t sys_rtctrim; + rt_uint32_t sys_rtcwrite0; + rt_uint32_t sys_rtcread0; + rt_uint32_t sys_rtcmatch0; + rt_uint32_t sys_rtcmatch1; + rt_uint32_t sys_rtcmatch2; +}; + +/* bit field helpers. */ +#define __M(n) (~(~0<<(n))) +#define __RBF(number, n) ((number)&__M(n)) +#define __BF(number, n, m) __RBF((number>>m), (n-m+1)) +#define BF(number, n, m) (msys_toyread0, 3, 0); + msec *= 100; + + time.tm_sec = BF(rtctp->sys_toyread0, 9, 4); + time.tm_min = BF(rtctp->sys_toyread0, 15, 10); + time.tm_hour = BF(rtctp->sys_toyread0, 20, 16); + time.tm_mday = BF(rtctp->sys_toyread0, 21, 25); + time.tm_mon = BF(rtctp->sys_toyread0, 26, 31); + /* struct tm has three more members: + time.tm_isdst + time.tm_wday + time.tm_yday + */ + time.tm_mon -= 1; + time.tm_year = rtctp->sys_toyread1; + return &time; +} + +rtctime_t mkrtctime(struct tm *tm) +{ + rtctime_t rtctm; + struct tm tmptime; + + rtctm.sys_toyread0 <<= 31 - 26 + 1; + rtctm.sys_toyread0 |= tm->tm_mon + 1; + rtctm.sys_toyread0 <<= 25 - 21 + 1; + rtctm.sys_toyread0 |= tm->tm_mday; + rtctm.sys_toyread0 <<= 20 - 16 + 1; + rtctm.sys_toyread0 |= tm->tm_hour; + rtctm.sys_toyread0 <<= 15 - 10 + 1; + rtctm.sys_toyread0 |= tm->tm_min; + rtctm.sys_toyread0 <<= 9 - 4 + 1; + rtctm.sys_toyread0 |= tm->tm_sec; + /* Fixme: 0.1 second */ + rtctm.sys_toyread0 <<= 3 - 0 + 1; + rtctm.sys_toyread0 |= 0; + + rtctm.sys_toyread1 = tm->tm_year; + + tmptime = *localrtctime(&rtctm); + + return rtctm; +} + +static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_size_t rt_rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + return 0; +} + +static rt_err_t rt_rtc_ioctl(rt_device_t dev, int cmd, void *args) +{ + rt_err_t err = RT_ENOSYS; + + static int count = 0; + + struct loongson_rtc *hw_rtc; + rtctime_t rtctm; + struct tm time; + struct tm tmptime; + time_t *t; + + hw_rtc = dev->user_data; + + t = (time_t *)args; + time = *localtime(t); + + rtctm.sys_toyread0 = hw_rtc->sys_toyread0; + rtctm.sys_toyread1 = hw_rtc->sys_toyread1; + rtctm.sys_rtcread0 = hw_rtc->sys_rtcread0; + tmptime = *localrtctime(&rtctm); + + switch (cmd) { + case RT_DEVICE_CTRL_RTC_GET_TIME: + *t = mktime(&tmptime); + break; + case RT_DEVICE_CTRL_RTC_SET_TIME: + tmptime.tm_hour = time.tm_hour; + tmptime.tm_min = time.tm_min; + tmptime.tm_sec = time.tm_sec; + + tmptime.tm_year = time.tm_year; + tmptime.tm_mon = time.tm_mon; + tmptime.tm_mday = time.tm_mday; + + rtctm = mkrtctime(&tmptime); + /* write to hw RTC */ + hw_rtc->sys_toywrite0 = rtctm.sys_toyread0; + hw_rtc->sys_toywrite1 = rtctm.sys_toyread1; + break; + case RT_DEVICE_CTRL_RTC_GET_ALARM: + break; + case RT_DEVICE_CTRL_RTC_SET_ALARM: + break; + default: + break; + } + + return RT_EOK; +} + +int rt_hw_rtc_init(void) +{ + static struct rt_device rtc = { + .type = RT_Device_Class_RTC, + .init = RT_NULL, + .open = rt_rtc_open, + .close = RT_NULL, + .read = rt_rtc_read, + .write = RT_NULL, + .control = rt_rtc_ioctl, + .user_data = (void *)RTC_BASE, + }; + rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR); +} + +INIT_DEVICE_EXPORT(rt_hw_rtc_init); diff --git a/bsp/ls2kdev/drivers/ls2k1000.h b/bsp/ls2kdev/drivers/ls2k1000.h index 90adf4a6ed..8e8adce899 100644 --- a/bsp/ls2kdev/drivers/ls2k1000.h +++ b/bsp/ls2kdev/drivers/ls2k1000.h @@ -9,6 +9,7 @@ #define GPIO_BASE 0xFFFFFFFFBFE10500 #define PLL_SYS_BASE 0xFFFFFFFFBFE10480 +#define RTC_BASE 0xFFFFFFFFBFE07820 void rt_hw_timer_handler(void); void rt_hw_uart_init(void);