S3C2440驱动篇—RTC驱动分析

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

Linux-2.6.32.2内核自带RTC驱动,但mach_smdk2440.c中没有添加该设备集,因此没有被激活,加入该平台设备,RTC平台设备定义在arch/arm/plat-s3c24xx/devs.c。

static struct platform_device *smdk2440_devices[] __initdata = {

       &s3c_device_usb,          /* arch/arm/mach-s3c2440/mach-smdk2440.c */

       &s3c_device_lcd,

       &s3c_device_wdt,

       &s3c_device_i2c0,

       &s3c_device_iis,

       &s3c_device_rtc,

};

驱动实现:

  1. #include    

  2. #include    

  3. #include    

  4. #include    

  5. #include    

  6. #include    

  7. #include    

  8. #include    

  9. #include    

  10. #include    

  11.   

  12. #include    

  13. #include    

  14. #include    

  15. #include    

  16. #include    

  17.   

  18. /* I have yet to find an S3C implementation with more than one 

  19.  * of these rtc blocks in */  

  20.   

  21. static struct resource *s3c_rtc_mem;  

  22.   

  23. static void __iomem *s3c_rtc_base;  

  24. static int s3c_rtc_alarmno = NO_IRQ;  

  25. static int s3c_rtc_tickno  = NO_IRQ;  

  26.   

  27. static DEFINE_SPINLOCK(s3c_rtc_pie_lock);  

  28.   

  29. /* IRQ Handlers */  

  30.   

  31. static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)  

  32. {  

  33.     struct rtc_device *rdev = id;  

  34.   

  35.     /* 报警中断到来时,设定报警相关信息,函数实现位于drivers/rtc/interface.c */  

  36.     rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);  

  37.     return IRQ_HANDLED;  

  38. }  

  39.   

  40. static irqreturn_t s3c_rtc_tickirq(int irq, void *id)  

  41. {  

  42.     struct rtc_device *rdev = id;  

  43.   

  44.     rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);  

  45.     return IRQ_HANDLED;  

  46. }  

  47.   

  48. /* Update control registers 设置RTCALM全局报警使能位*/  

  49. static void s3c_rtc_setaie(int to)  

  50. {  

  51.     unsigned int tmp;  

  52.   

  53.     pr_debug('%s: aie=%dn', __func__, to);  

  54.   

  55.     tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;  

  56.   

  57.     if (to)  

  58.         tmp |= S3C2410_RTCALM_ALMEN;  

  59.   

  60.     writeb(tmp, s3c_rtc_base + S3C2410_RTCALM);  

  61. }  

  62.   

  63. /* 节拍时间计数器使能 */  

  64. static int s3c_rtc_setpie(struct device *dev, int enabled)  

  65. {  

  66.     unsigned int tmp;  

  67.   

  68.     pr_debug('%s: pie=%dn', __func__, enabled);  

  69.   

  70.     spin_lock_irq(&s3c_rtc_pie_lock);  

  71.     tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE;  

  72.   

  73.     if (enabled)  

  74.         tmp |= S3C2410_TICNT_ENABLE;  

  75.   

  76.     writeb(tmp, s3c_rtc_base + S3C2410_TICNT);  

  77.     spin_unlock_irq(&s3c_rtc_pie_lock);  

  78.   

  79.     return 0;  

  80. }  

  81.   

  82. /* 节拍时间计数值设置*/  

  83. static int s3c_rtc_setfreq(struct device *dev, int freq)  

  84. {  

  85.     unsigned int tmp;  

  86.   

  87.     if (!is_power_of_2(freq))  

  88.         return -EINVAL;  

  89.   

  90.     spin_lock_irq(&s3c_rtc_pie_lock);  

  91.   

  92.     tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE;  

  93.     tmp |= (128 / freq)-1;  

  94.   

  95.     writeb(tmp, s3c_rtc_base + S3C2410_TICNT);  

  96.     spin_unlock_irq(&s3c_rtc_pie_lock);  

  97.   

  98.     return 0;  

  99. }  

  100.   

  101. /* Time read/write */  

  102. /* 读取RTC中时间:分、时、日期、月、年、秒 */  

  103. static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)  

  104. {  

  105.     unsigned int have_retried = 0;  

  106.     void __iomem *base = s3c_rtc_base;  

  107.   

  108.  retry_get_time:  

  109.     rtc_tm->tm_min  = readb(base + S3C2410_RTCMIN);  

  110.     rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);  

  111.     rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);  

  112.     rtc_tm->tm_mon  = readb(base + S3C2410_RTCMON);  

  113.     rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);  

  114.     rtc_tm->tm_sec  = readb(base + S3C2410_RTCSEC);  

  115.   

  116.     /* the only way to work out wether the system was mid-update 

  117.      * when we read it is to check the second counter, and if it 

  118.      * is zero, then we re-try the entire read 

  119.      */  

  120.     /* 如果读到秒为0,可能有进位,根据2440手册知道,要重新读一次 */  

  121.     if (rtc_tm->tm_sec == 0 && !have_retried) {  

  122.         have_retried = 1;  

  123.         goto retry_get_time;  

  124.     }  

  125.   

  126.     pr_debug('read time %02x.%02x.%02x %02x/%02x/%02xn',  

  127.          rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,  

  128.          rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);  

  129.   

  130.     /* 将BCD码转换为二进制数 */  

  131.     rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);  

  132.     rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);  

  133.     rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);  

  134.     rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);  

  135.     rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);  

  136.     rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);  

  137.   

  138.     /*这里为什么要加100年和减1月,查看数据手册得知区别1900年和2000年闰年的因素,1900年不是闰年而2000年是闰年*/  

  139.     rtc_tm->tm_year += 100;  

  140.     rtc_tm->tm_mon -= 1;  

  141.   

  142.     return 0;  

  143. }  

  144.   

  145. /* 与s3c_rtc_gettime功能相反 */  

  146. static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)  

  147. {  

  148.     void __iomem *base = s3c_rtc_base;  

  149.     int year = tm->tm_year - 100;  

  150.   

  151.     pr_debug('set time %02d.%02d.%02d %02d/%02d/%02dn',  

  152.          tm->tm_year, tm->tm_mon, tm->tm_mday,  

  153.          tm->tm_hour, tm->tm_min, tm->tm_sec);  

  154.   

  155.     /* we get around y2k by simply not supporting it */  

  156.   

  157.     if (year < 0 || year >= 100) {  

  158.         dev_err(dev, 'rtc only supports 100 yearsn');  

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

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

推荐阅读最新更新时间:2024-11-03 12:13

S3C2440的SPI解析
S3C2440A的串行外设接口(SPI)可以与串行数据传输连接。S3C2440A包含了2个SPI,每个都有2个分别用于发送和接收的8位移位寄存器。一次SPI传输期间,同时发送(串行移出)和接收(串行移入)数据。由相应控制寄存器设置指定8位串行数据的频率。如果只希望发送,则接收数据可以保持伪位(dummy)。此外如果只希望接收,则需要发送伪位'1'数据 使用SPI主要需要以下寄存器 选择SPI模式,中断模式,查询模式等SCK选择,主从机选择以及GPOL GPOA选择,关于GPOL与GPOA的描述请查看SPI协议手册 选择SPI时钟,SPI挂在PCLK上,具体计算公式如下 针对数据传输完成之后的SPI总线状
[单片机]
<font color='red'>S3C2440</font>的SPI解析
基于S3C2440的LWIP-1.3.0和DM9000在UCOS-II-2.8.6上的移植
经常在Linux上跑,一时间跳到UCOS,感觉有点不习惯。首先是编译器,GCC是个不错的选择,但GDB调试太麻烦。ADS和仿真器结合是个十分不错的调试环境,于是,将代码就搬到ADS上,这下完全脱离Linux,整个开发过程都在Windows进行。其实是UCOS太简洁了,时钟、接口很多都需要自己开发…小弟对UCOS不是很熟,下面是移植过程的一些小结,希望对有需要的朋友带来些帮助。关于UCOS在S3C2440上的移植,可以参考《uCOS-II在S3C2440上的移植》一文。 1. 寻找最新代码,总结前辈经验,就是下载LWIP的源代码和Michael Anburaj基于S3C2410的移植版。 http://download.savann
[单片机]
基于<font color='red'>S3C2440</font>的LWIP-1.3.0和DM9000在UCOS-II-2.8.6上的移植
S3C2440 测试程序(三) ADC实验
该实验比较简单,就是使用了S3C2440上的ADC硬件接口AIN2。 下面看下设置。 根据Datasheet,A/D转换的频率为50MHz/(prescaler+1) eg. A/D converter freq. = 50MHz/(49+1) = 1MHz Conversion time = 1/(1MHz / 5cycles) = 1/200KHz = 5 us 看下程序,我们使用了2.5MHz,所有prescaler=19 代码如下: prescaler=19; ADCCON=(1 14)|(prescaler 6)|(2 3); 注: bit :Read only, 0--A/D conversion in
[单片机]
S3C2440的camera接口特性及WinCE 下的驱动
  S3C2440是应用十分广泛且适用于嵌入式系统的一款嵌入式处理器。winCE 5.0/6.O是微软公司开发的一款专用于嵌入式系统的实时操作系统。其模块化设计使开发人员可以根据需求定制设备。目前,国内大部分OEM商都提供了对S3C2440的camera接口在WinCE5.O/6.0下的驱动支持。遗憾的是,目前国内OEM商提供的驱动仅限于对几款微型摄像头(如ov9650等)的驱动支持。当用户采用CCD摄像头作为图像采集的前端设备时,原来的驱动已经不能使用了,而CCD摄像头因其优越的性能,在监控领域扮演着主力军角色。本文从分析S3C2440的camera接口特性出发,详细介绍当摄像设备为CCD摄像头时,在WinCE 5.O/6.0操
[嵌入式]
S3C2440内存组成
大家好,我们这回来讨论下S3C2440内存组成。 先来张图吧: 图1 S3C2440是32bit的单片机(请允许我叫它单片,因为我觉得它和普通的单片机真的没有本质的区别),那么按道理它的地址范围就是0~0xFFFFFFFF,也就是4GB的寻址空间。但是,实际上很多是保留的,0~0x3FFFFFFF的地址部分是分配给用户的NandFlash、NorFlash、SDRAM等存储器件,0x40000000开始有一部分是内部寄存器,绝大部分是保留不使用的。 NandFlash:我们可以把它当作PC机的硬盘。 NorFlash:也是FLASH,但是其读的速度很快。 SDRAM:中文全称是同步随机动态存储,类似于SRAM,但是造价啥的比较
[单片机]
s3c2440裸机-代码重定位(1.重定位的引入,为什么要代码重定位)
1.重定位的引入(为什么要代码重定位) 我们知道s3c2440的cpu从0地址开始取指令执行,当从nor启动时,0地址对应nor,nor可以像内存一样读,但不能像内存一样写。我们能够从nor上取指令执行。 例子1:当nand启动的时候,我们nand中的前4K指令会变自动加载到sram中去,这时的0地址对应sram。 那么我们的程序如果大于4K,要从nand启动,sram只拷贝了nand中的前4K代码,那么如何解决这个问题呢? 那么就需要重定位代码到sdram中去,sdram的容量较大,又可以直接被cpu访问。 例子2:我们知道,程序含有: 代码段(.text) 数据段(.data):存放初始值不为0的全局变量/静态变量
[单片机]
<font color='red'>s3c2440</font>裸机-代码重定位(1.重定位的引入,为什么要代码重定位)
S3C2440 开发板实战(1): 烧录程序篇(纯Ubuntu环境)
为了学习方便就买了韦老师的JZ2440开发板,因为有做过关于STM32以及51单片机的项目,并且参加过三次电子设计大赛。但是感觉自己都是只学了个皮毛(学习嵌入式之后感觉自己真的只学了个皮毛),这里建议如果要往这个方向发展的大学生在校期间应该把微机学好(真的很有用),废话不多说,直接开始第一次简单的复习。 1.使用oflash烧写程序(慢) 插线方式:EOP和serial连上计算机。 oflash主要应用于2440和2410的程序烧写,他利用了JPAG口进行烧写,我是用了一个专门的电脑,装了一个Ubuntu 20.4系统,(我超推荐电脑装单系统,在之后的学习中超方便,就算是看完这一篇你都会觉得:去TM的
[单片机]
s3c2440之IIS(2)I2S音频总线学习-数字音频技术
IIS音频总线学习(一)数字音频技术 一、声音的基本概念 声音是通过一定介质传播的连续的波。 重要指标: 振幅:音量的大小 周期:重复出现的时间间隔 频率:指信号每秒钟变化的次数 声音按频率分类: 声音的传播携带了信息,它是人类传播信息的一种主要媒体。 声音的三种类型: 波形声音:包含了所有声音形式 语音:不仅是波形声音,而且还有丰富的语言内涵(抽象→提取特征→意义理解) 音乐:与语音相比,形式更规范。音乐是符号化的声音。 二、声音的数字化 1.声音信号的类型 模拟信号(自然界、物理) 数字信号(计算机) 2.声音数字化过程 3.声音数字化过程示意图 4.声音数字
[单片机]
<font color='red'>s3c2440</font>之IIS(2)I2S音频总线学习-数字音频技术
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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