移植DS1302模块到MT7621

首先需要打开内核的时钟模块配置。

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)

猜你喜欢

转载自www.cnblogs.com/schen007/p/10281453.html
今日推荐