首先需要打开内核的时钟模块配置。
DS1302模块需要将CE,I/O,SCLK引脚接到CPU上,我的方案是CE接到MT7621的GPIO#16,SCLK接到GPIO#4,I/O接到GPIO#3。
查看MT7621编程手册,GPIO#0~GPIO#31的控制寄存器为0x1E000600,数据寄存器为0x1E000620,查看代码可知在MT7621上将寄存器remap到了0xBE000600和0xBE000620。
查找内核(3.10.14)代码,发现文件drivers/rtc/rtc-ds1302.c,这是为sh平台编写的驱动,需要做修改。驱动主要是通过GPIO模拟时钟信号,同时设置或者读取I/O引脚的值,达到读取DS1302模块时间的目的
static volatile unsigned long *gpio_con = 0xBE000600; static volatile unsigned long *gpio_dat = 0xBE000620; #define RTC_RESET (1<<16) #define RTC_IODATA (1<<3) #define RTC_SCLK (1<<4) #define set_dp(x) *gpio_dat=(x) #define get_dp() *gpio_dat
static inline int ds1302_hw_init(void)
{
*gpio_con |= (RTC_SCLK | RTC_RESET); //set sclk and ce pin as output
set_dp(get_dp() & ~RTC_SCLK); //set sclk low
return 0;
}
编译后加载驱动失败,经过打印读取信息,发现写入0x42到RAM,读取到0x84,就可知道以下代码出了问题
static unsigned int ds1302_recvbits(void) { unsigned int val; int i; ds1302_set_rx(); for (i = 0, val = 0; (i < 8); i++) { ds1302_clock(); val |= (ds1302_rxbit() << i); //ds1302_clock(); //时钟应该放在读取之前,否则会多读一个0 } return val; }
再次编译,驱动加载成功,可以在/dev下看到rtc0设备。
接下来就可以通过busybox的hwclock命令设置和读取ds1302模块的时钟了
# hwclock --help
BusyBox v1.13.4 (2009-09-18 16:05:03 CST) multi-call binary
Usage: hwclock [-r|--show] [-s|--hctosys] [-w|--systohc] [-l|--localtime] [-u|--utc] [-f FILE]
Query and set hardware clock (RTC)
Options:
-r Show hardware clock time
-s Set system time from hardware clock
-w Set hardware clock to system time
-u Hardware clock is in UTC
-l Hardware clock is in local time
-f FILE Use specified device (e.g. /dev/rtc2)
原文:https://www.cnblogs.com/schen007/p/10281453.html