海思HI3521DV100平台集成内部RTC,也支持外部RTC,这里先探究一下内部RTC的硬件设计和驱动程序设计;虽然在之前的项目中没有用过这种内部RTC,但是比较好奇这种内部RTC性能和效果如何,这次的项目也没有机会用到内部RTC,遗憾了。
原理图
官方demo板内部RTC晶振设计图如下,AVDD33_RTC接的是3V3常电,AVDD_BAT没有接电池,应该需要接电池的吧。
项目中的RTC设计图如下,没有加晶振器件。
芯片逻辑框图
看驱动代码得知,内部的RTC应该是走SPI协议,需要读写RTC寄存器,操作RTC寄存器其实就是通过SPI总线发送数据到内部RTC寄存器。
驱动程序
官方内部RTC测试程序代码目录位置:Hi3521DV100_SDK_V2.0.4.0/drv/rtc
hi_rtc.c hi_rtc.h 驱动,RTC寄存器读写方法,走SPI协议,注册杂项字符设备驱动方式,提供设备节点:/dev/hi_rtc
/* RTC Control over SPI */
#define RTC_SPI_BASE_ADDR IO_ADDRESS(0x120b0000)
#define SPI_CLK_DIV (RTC_SPI_BASE_ADDR + 0x000)
#define SPI_RW (RTC_SPI_BASE_ADDR + 0x004)
/* RTC REG */
#define RTC_10MS_COUN 0x00
#define RTC_S_COUNT 0x01
#define RTC_M_COUNT 0x02
#define RTC_H_COUNT 0x03
crw------- 1 root root 10, 135 Jan 1 00:01 /dev/hi_rtc
测试程序
rtc_test.c 测试程序,通过对字符设备文件的读写操作RTC寄存器
# ./test
Usage: ./test [options] [parameter1] ...
Options:
-s(set) Set time/alarm, e.g '-s time 2012/7/15/13/37/59'
-g(get) Get time/alarm, e.g '-g alarm'
-w(write) Write RTC register, e.g '-w <reg> <val>'
-r(ead) Read RTC register, e.g '-r <reg>'
-a(alarm) Alarm ON/OFF', e.g '-a ON'
-reset RTC reset
-b(battery monitor) battery ON/OFF, e.g '-b ON'
-f(requency) frequency precise adjustment, e.g '-f <val>'
由于项目中没有焊接晶振,所以无法驱动内部RTC进行计时。
测试发现时间没有设置下去,不知为何?
/mnt/sda # ./test -s time 2012/7/15/13/37/59
set time
year:2012
month:7
date:15
hour:13
minute:37
second:59
/mnt/sda #
/mnt/sda # ./test -g time
[RTC_RD_TIME]
Current time value:
year 1970
month 1
date 1
hour 0
minute 0
second 0
weekday 4
EBAINA开发板
由于只拿到开发板,没有原理图和源码SDK,看到板子有电池座,所以猜想使用了内部RTC,通过万用表测试电池座与核心板引出接口,接在了AVDD_BAT管脚上。
猜想电路图如下:
烧写ebaina的boot和kernel文件,烧写自己的rootfs(libc库不一致,导致自己编译的程序不能运行),加载hi_rtc.ko模块,运行测试程序rtc_test,设置和获取时间成功,掉电后时间依然保持。
遗留问题:
怎么把时间更新到系统时间?
内部RTC功耗是多少?【实测1.5uA】
电池能撑多长时间?【电池容量mAh/0.0015mA就是小时,再除24就是天数;以CR1220电池40mAh,可以撑1111天,就是3年】
海思外部I2C RTC pcf8563调试失败,需要按照海思的规则使用特殊的I2C,需要改代码进行适配比较麻烦。