S3C2440驱动篇—RTC驱动分析

发布者:MagicalSerenade最新更新时间:2024-06-14 来源: elecfans关键字:S3C2440  RTC驱动 手机看文章 扫描二维码
随时随地手机看文章
  •         return -EINVAL;  

  •     }  

  •   

  •     writeb(bin2bcd(tm->tm_sec),  base + S3C2410_RTCSEC);  

  •     writeb(bin2bcd(tm->tm_min),  base + S3C2410_RTCMIN);  

  •     writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR);  

  •     writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE);  

  •     writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON);  

  •     writeb(bin2bcd(year), base + S3C2410_RTCYEAR);  

  •   

  •     return 0;  

  • }  

  •   

  • /* 读取RTC报警时间值 */  

  • static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)  

  • {  

  •     struct rtc_time *alm_tm = &alrm->time;  

  •     void __iomem *base = s3c_rtc_base;  

  •     unsigned int alm_en;  

  •   

  •     alm_tm->tm_sec  = readb(base + S3C2410_ALMSEC);  

  •     alm_tm->tm_min  = readb(base + S3C2410_ALMMIN);  

  •     alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR);  

  •     alm_tm->tm_mon  = readb(base + S3C2410_ALMMON);  

  •     alm_tm->tm_mday = readb(base + S3C2410_ALMDATE);  

  •     alm_tm->tm_year = readb(base + S3C2410_ALMYEAR);  

  •   

  •     alm_en = readb(base + S3C2410_RTCALM);  

  •   

  •     alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;  

  •   

  •     pr_debug('read alarm %02x %02x.%02x.%02x %02x/%02x/%02xn',  

  •          alm_en,  

  •          alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,  

  •          alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);  

  •   

  •   

  •     /* decode the alarm enable field */  

  •   

  •     if (alm_en & S3C2410_RTCALM_SECEN)  

  •         alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);  

  •     else  

  •         alm_tm->tm_sec = 0xff;  

  •   

  •     if (alm_en & S3C2410_RTCALM_MINEN)  

  •         alm_tm->tm_min = bcd2bin(alm_tm->tm_min);  

  •     else  

  •         alm_tm->tm_min = 0xff;  

  •   

  •     if (alm_en & S3C2410_RTCALM_HOUREN)  

  •         alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);  

  •     else  

  •         alm_tm->tm_hour = 0xff;  

  •   

  •     if (alm_en & S3C2410_RTCALM_DAYEN)  

  •         alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);  

  •     else  

  •         alm_tm->tm_mday = 0xff;  

  •   

  •     if (alm_en & S3C2410_RTCALM_MONEN) {  

  •         alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);  

  •         alm_tm->tm_mon -= 1;   //这里减1有待研究,为什么只有月没有年减1   

  •     } else {  

  •         alm_tm->tm_mon = 0xff;  

  •     }  

  •   

  •     if (alm_en & S3C2410_RTCALM_YEAREN)  

  •         alm_tm->tm_year = bcd2bin(alm_tm->tm_year);  

  •     else  

  •         alm_tm->tm_year = 0xffff;  

  •   

  •     return 0;  

  • }  

  • /* 与s3c_rtc_getalarm功能相反 */  

  • static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)  

  • {  

  •     struct rtc_time *tm = &alrm->time;  

  •     void __iomem *base = s3c_rtc_base;  

  •     unsigned int alrm_en;  

  •   

  •     pr_debug('s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02xn',  

  •          alrm->enabled,  

  •          tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,  

  •          tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);  

  •   

  •   

  •     alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;  

  •     writeb(0x00, base + S3C2410_RTCALM);  

  •   

  •     if (tm->tm_sec < 60 && tm->tm_sec >= 0) {  

  •         alrm_en |= S3C2410_RTCALM_SECEN;  

  •         writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC);  

  •     }  

  •   

  •     if (tm->tm_min < 60 && tm->tm_min >= 0) {  

  •         alrm_en |= S3C2410_RTCALM_MINEN;  

  •         writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN);  

  •     }  

  •   

  •     if (tm->tm_hour < 24 && tm->tm_hour >= 0) {  

  •         alrm_en |= S3C2410_RTCALM_HOUREN;  

  •         writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR);  

  •     }  

  •   

  •     pr_debug('setting S3C2410_RTCALM to %08xn', alrm_en);  

  •   

  •     writeb(alrm_en, base + S3C2410_RTCALM);  

  •   

  •     s3c_rtc_setaie(alrm->enabled);  

  •   

  •     /*根据全局报警使能的状态来决定是唤醒RTC报警中断还是睡眠RTC报警中断*/  

  •     if (alrm->enabled)  

  •         enable_irq_wake(s3c_rtc_alarmno);  

  •     else  

  •         disable_irq_wake(s3c_rtc_alarmno);  

  •   

  •     return 0;  

  • }  

  •   

  • static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)  

  • {  

  •     unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT);  

  •   

  •     seq_printf(seq, 'periodic_IRQt: %sn',  

  •              (ticnt & S3C2410_TICNT_ENABLE) ? 'yes' : 'no' );  

  •     return 0;  

  • }  

  •   

  • /*RTC设备类打开接口函数*/  

  • static int s3c_rtc_open(struct device *dev)  

  • {  

  •     /*这里主要的目的是从系统平台设备中获取RTC设备类的数据,和RTC探测函数rtc_probe中 

  •         的platform_set_drvdata(pdev, rtc)的操作刚好相反。定义在platform_device.h中*/  

  •     struct platform_device *pdev = to_platform_device(dev);  

  •     struct rtc_device *rtc_dev = platform_get_drvdata(pdev);  

  •     int ret;  

  •   

  •     ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,  

  •               IRQF_DISABLED,  's3c2410-rtc alarm', rtc_dev);  

  •   

  •     if (ret) {  

  • [1] [2] [3] [4]
    关键字:S3C2440  RTC驱动 引用地址:S3C2440驱动篇—RTC驱动分析

    上一篇:S3C2440驱动篇—Linux平台设备驱动
    下一篇:S3C2440-SDRAM连线分析

    推荐阅读最新更新时间:2024-11-13 16:51

    S3C2440时钟电源管理
    S3C2440的时钟可以选用晶振(XTAL),也可以使用外部时钟(EXTCLK),由系统复位时,在复位信号上升沿对引脚OM3、OM2所测的状态来确定。由于我所用的开发板这两个引脚接地,故外部晶振作为主锁相环(MPLL)和usb锁相环(UPLL)的时钟源。 含有两个锁相环MPLL、UPLL产生系统所需要的不同频率的时钟 MPLL: 为CPU产生FCLK时钟 为AHB产生HCLK时钟 为APB产生PCLK时钟 UPLL: 为usb(Host and Device)产生UCLK(48M) FCLK,HCLK和 PCLK FCLK是提供给ARM920T 的时钟。 HCLK 是提供给用于 ARM920T,存储器控制器,中断控
    [单片机]
    <font color='red'>S3C2440</font>时钟电源管理
    RT3070 在S3C2440平台上的移植
    1.从官方下载原驱动程序 http://www.ralinktech.com/en/04_support/license.php?sn=5016 然后把驱动代码放到/home/tango/code/linux-2.6.32.2/drivers/net/wireless/目录下 其中/home/tango/code/linux-2.6.32.2 是 linux2.6.32.2内核源码路径。 2.在rt3070驱动程序根目录的Makefile文件的修改 2.1.定义芯片类型及头文件包含路径以及选择硬件运行平台 CHIPSET = 3070 C_INCLUDE_PATH ?= $(PWD)/include PLATFORM = SMDK
    [单片机]
    基于S3C2440嵌入式系统的以太网接口电路设计方案
    文章主要介绍了一个基于三星ARM9芯片S3C2440嵌入式系统的以太网接口电路设计方案,采用了工业级以太网控制器DM9000AEP成功实现了嵌入式系统网络数据交换。论文在重点阐述了网络接口电路基础之上,对Windows CE系统控制软件部分DM9000AEP的驱动程序和注册表项进行了具体分析。 随着微电子技术和计算机技术的发展,嵌入式技术得到广阔的发展,已成为现代工业控制、通信类和消费类产品发展的方向。以太网在实时操作、可靠传输、标准统一等方面的卓越性能及其便于安装、维护简单、不受通信距离限制等优点,已经被国内外很多监控、控制领域的研究人员广泛关注,并在实际应用中展露出显着的优势。本文提出了一种基于DM9000AE网络接口
    [单片机]
    基于<font color='red'>S3C2440</font>嵌入式系统的以太网接口电路设计方案
    新版U-boot2012.04.01移植(一)(JZ2440-S3C2440)
    新版U-boot2012.04.01移植(一)(JZ2440-S3C2440) u-boot下载地址:http://www.denx.de/wiki/U-Boot/ 我们这里要下载的u-boot版本为:u-boot-2012.04.01tar.bz2 下载步骤如下: 下载完成后,在linux下进行试验: 1、初试 进行解压缩:tar xjf u-boot-2012.04.01.tar.bz2 进入目录: cd u-boot-2012.04.01/ cd u-boot-2012.04.01/ 进行配置: make smdk2410_config 编译: make 最后会出现编译错误:“arm
    [单片机]
    新版U-boot2012.04.01移植(一)(JZ2440-S3C2440)
    s3c2440裸机-代码重定位-4-清bss的优化和位置无关码
    1.代码重定位的改进 用ldr、str代替ldrb, strb加快代码重定位的速度。 前面重定位时,我们使用的是ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDRAM里面。 我们2440开发板的Nor Flash是16位,SDRAM是32位。 假设现在需要复制16byte数据。 不同的读写指令 cpu读取nor的次数 cpu写入sdram的次数 ldrb、strb 16 16 ldr、str 8 4 可以看出我们更换读写指令后读写次数变少了,提升了cpu的访问效率。 修改后的start.s代码如下图所示,这里我只简单的列出了重定位的实现: ... cpy: ldr r4, str
    [单片机]
    ARM Linux S3C2440之ADC驱动实现
    硬件描述: S3c2440有一个10-bit的CMOS ADC 模数转换器,支持8个模拟通道输入,10位的分辨率,最高速度可达500KSPS(500 千次/每秒)。 从图中可知:模拟ADC,包含了2部分功能,一部分是触屏功能,另一部分就是普通ADC功能,分别可以产生INT_TC和INT_ADC 两个中断。8个AIN模拟输入(A ,YM,YP,XM,XP)通过一个8路模拟开关MUX进行通道片选。 ADC模块共有20个寄存器。对于普通ADC转换,使用ADCCON 和 ADCDAT0即可完成控制。ADCCON用于控制设置,ADCDAT0保存了转换结果。 驱动程序ADC_DEV.ko: #include linux/err
    [单片机]
    ARM Linux <font color='red'>S3C2440</font>之ADC<font color='red'>驱动</font>实现
    S3C2440看门狗解析
    S3C2440A的看门狗定时器是用于当其由于噪声和系统错误引起的故障干扰时恢复控制器的工作。它可以被用作普通16位内部定时器来请求中断服务。看门狗定时器产生128个PCLK周期的复位信号 也就是说,在某些环境下,看门狗可以当做定时器使用,当他中断的时候并不发生复位,只发生中断,我看看图 看门狗的中断和复位信号是可以依靠wtcon来切断的(看门狗的时钟是无法切断的) 使用看门狗主要靠这几个寄存器 用来选择时钟源,分频系数,启动看门狗以及看门狗中断和复位的连接 流程基本上就是,第一次对wtcnt赋值之后启动看门狗,看门狗自动减,到达0的时候触发中断,如果连接了复位则触发复位 未连接则触发中断,另外, 看门狗定时
    [单片机]
    <font color='red'>S3C2440</font>看门狗解析
    S3C2440定时器4中断测试程序
    __irq为一个标识,用来表示一个函数是否为中断函数。对于不同的编译器,__irq在函数名中的位置不一样,例如: ADS编译器中 : void __irq IRQ_Eint0(void); Keil编译器中 : void IRQ_Eint0(void) __irq; 但是其意义一样,它所完成的任务是标识该函数为中断函数,在编译器编译是调用此函数时,先保护函数入口现场,然后执行中断函数,函数执行完毕,恢复中断现场,这整个过程不需要用户重新编写代码来完成,由编译器自动完成。因而这也给不具备中断嵌套功能的ARM系统带来了问题,若使用 __irq 时有中断嵌套产生,这现场保护就会混乱。中断嵌套处理可以自己编写中断入口现场保护代码,并不使用
    [单片机]
    小广播
    设计资源 培训 开发板 精华推荐

    最新单片机文章
    何立民专栏 单片机及嵌入式宝典

    北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

     
    EEWorld订阅号

     
    EEWorld服务号

     
    汽车开发圈

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved