This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335X RTC 不能保持時間

Other Parts Discussed in Thread: TPS65910

我客製板使用 u-boot-2013.01.01-psp06.00.00.00,linux-3.2.0-psp04.06.00.11。filesystem 是 ubuntu

我下 date 030217302015

          hwclock -w

          hwclock -s

          hwclock

可以寫入硬體RTC。但 reboot 之後,時間一樣 reset 到 2000年 1月1號。 我確認過 rtc_pwronrstn , pmic_power_en, rtc_kaldo_enn, rtc_pwronrstn 了,也用別的BSP驗證電池是有電的,硬體沒有問題,是軟體問題,請問我還可以去哪裡修改? 謝謝。以下為開機訊息。

[    0.000000] Linux version 3.2.0-g4ea3cc5 (bernie@ubuntu) (gcc version 4.7.3 20130226 (prerelease) (crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro GCC 2013.03) ) #2 Mon Mar 2 17:14:40 CST 2015
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine: am335xevm
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] On node 0 totalpages: 65536
[    0.000000] free_area_init_node: node 0, pgdat c0655c20, node_mem_map c068f000
[    0.000000]   Normal zone: 512 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 65024 pages, LIFO batch:15
[    0.000000] AM335X ES2.1 (neon )
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
[    0.000000] Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p2 mem=256M rootwait
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Memory: 256MB = 256MB total
[    0.000000] Memory: 253140k/253140k available, 9004k reserved, 0K highmem
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     vmalloc : 0xd0800000 - 0xff000000   ( 744 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc05bb000   (5836 kB)
[    0.000000]       .init : 0xc05bb000 - 0xc05f5000   ( 232 kB)
[    0.000000]       .data : 0xc05f6000 - 0xc065ef20   ( 420 kB)
[    0.000000]        .bss : 0xc065ef44 - 0xc068e024   ( 189 kB)
[    0.000000] NR_IRQS:396
[    0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
[    0.000000] Total of 128 interrupts on 1 active controller
[    0.000000] OMAP clockevent source: GPTIMER2 at 24000000 Hz
[    0.000000] OMAP clocksource: GPTIMER1 at 32768 Hz
[    0.000000] sched_clock: 32 bits at 32kHz, resolution 30517ns, wraps every 131071999ms
[    0.000000] Console: colour dummy device 80x30
[    0.000091] Calibrating delay loop... 718.02 BogoMIPS (lpj=3590144)
[    0.058929] pid_max: default: 32768 minimum: 301
[    0.059051] Security Framework initialized
[    0.059143] Mount-cache hash table entries: 512
[    0.059539] CPU: Testing write buffer coherency: ok
[    0.079986] omap_hwmod: gfx: failed to hardreset
[    0.096252] omap_hwmod: pruss: failed to hardreset
[    0.097351] print_constraints: dummy:
[    0.097717] NET: Registered protocol family 16
[    0.099914] OMAP GPIO hardware version 0.1
[    0.102539] omap_mux_init: Add partition: #1: core, flags: 0
[    0.104492]  omap_i2c.2: alias fck already exists
[    0.105407]  omap2_mcspi.1: alias fck already exists
[    0.105651]  omap2_mcspi.2: alias fck already exists
[    0.105895]  edma.0: alias fck already exists
[    0.105926]  edma.0: alias fck already exists
[    0.105957]  edma.0: alias fck already exists
[    0.131835] bio: create slab <bio-0> at 0
[    0.134033] SCSI subsystem initialized
[    0.135711] usbcore: registered new interface driver usbfs
[    0.136016] usbcore: registered new interface driver hub
[    0.136230] usbcore: registered new device driver usb
[    0.136505] registerd cppi-dma Intr @ IRQ 17
[    0.136535] Cppi41 Init Done Qmgr-base(d087a000) dma-base(d0878000)
[    0.136535] Cppi41 Init Done
[    0.136566] musb-ti81xx musb-ti81xx: musb0, board_mode=0x11, plat_mode=0x1
[    0.136871] musb-ti81xx musb-ti81xx: musb1, board_mode=0x11, plat_mode=0x1
[    0.138000] omap_i2c omap_i2c.2: bus 2 rev2.4.0 at 100 kHz
[    0.139282] tps65910 2-002d: JTAGREVNUM 0x39
[    0.139282] tps65910 2-002d: unknown version
[    0.140441] Advanced Linux Sound Architecture Driver Version 1.0.24.
[    0.141540] Switching to clocksource gp timer
[    0.157104] musb-hdrc: version 6.0, ?dma?, otg (peripheral+host)
[    0.157287] musb-hdrc musb-hdrc.0: dma type: dma-cppi41
[    0.157623] MUSB0 controller's USBSS revision = 4ea20800
[    0.157653] TxFifo Empty intr disabled
[    0.157653] musb0: Enabled SW babble control
[    0.157958] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[    0.157989] musb-hdrc: MHDRC RTL version 2.0
[    0.157989] musb-hdrc: setup fifo_mode 4
[    0.158020] musb-hdrc: 28/31 max ep, 16384/16384 memory
[    0.158020] musb-hdrc.0: bulk split disabled
[    0.158050] musb-hdrc.0: bulk combine disabled
[    0.158142] musb-hdrc musb-hdrc.0: MUSB HDRC host driver
[    0.158233] musb-hdrc musb-hdrc.0: new USB bus registered, assigned bus number 1
[    0.158386] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    0.158386] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    0.158416] usb usb1: Product: MUSB HDRC host driver
[    0.158416] usb usb1: Manufacturer: Linux 3.2.0-g4ea3cc5 musb-hcd
[    0.158416] usb usb1: SerialNumber: musb-hdrc.0
[    0.159301] hub 1-0:1.0: USB hub found
[    0.159332] hub 1-0:1.0: 1 port detected
[    0.159912] musb-hdrc musb-hdrc.0: USB Host mode controller at d083c000 using DMA, IRQ 18
[    0.160095] musb-hdrc musb-hdrc.1: dma type: dma-cppi41
[    0.160400] MUSB1 controller's USBSS revision = 4ea20800
[    0.160430] TxFifo Empty intr disabled
[    0.160430] musb1: Enabled SW babble control
[    0.160736] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[    0.160736] musb-hdrc: MHDRC RTL version 2.0
[    0.160766] musb-hdrc: setup fifo_mode 4
[    0.160766] musb-hdrc: 28/31 max ep, 16384/16384 memory
[    0.160797] musb-hdrc.1: bulk split disabled
[    0.160797] musb-hdrc.1: bulk combine disabled
[    0.160888] musb-hdrc musb-hdrc.1: MUSB HDRC host driver
[    0.160949] musb-hdrc musb-hdrc.1: new USB bus registered, assigned bus number 2
[    0.161041] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[    0.161041] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    0.161071] usb usb2: Product: MUSB HDRC host driver
[    0.161071] usb usb2: Manufacturer: Linux 3.2.0-g4ea3cc5 musb-hcd
[    0.161102] usb usb2: SerialNumber: musb-hdrc.1
[    0.161956] hub 2-0:1.0: USB hub found
[    0.161987] hub 2-0:1.0: 1 port detected
[    0.162567] musb-hdrc musb-hdrc.1: USB Host mode controller at d083e800 using DMA, IRQ 19
[    0.162994] NET: Registered protocol family 2
[    0.163177] IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.163482] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[    0.163635] TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
[    0.163726] TCP: Hash tables configured (established 8192 bind 8192)
[    0.163757] TCP reno registered
[    0.163757] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.163787] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.163970] NET: Registered protocol family 1
[    0.164245] RPC: Registered named UNIX socket transport module.
[    0.164245] RPC: Registered udp transport module.
[    0.164276] RPC: Registered tcp transport module.
[    0.164276] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.164520] NetWinder Floating Point Emulator V0.97 (double precision)
[    0.175689] VFS: Disk quotas dquot_6.5.2
[    0.175750] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[    0.176300] msgmni has been set to 494
[    0.179443] alg: No test for stdrng (krng)
[    0.179504] io scheduler noop registered
[    0.179534] io scheduler deadline registered
[    0.179626] io scheduler cfq registered (default)
[    0.181701] omap_uart.0: ttyO0 at MMIO 0x44e09000 (irq = 72) is a OMAP UART0
[    0.819122] console [ttyO0] enabled
[    0.823486] omap_uart.1: ttyO1 at MMIO 0x48022000 (irq = 73) is a OMAP UART1
[    0.831298] omap_uart.2: ttyO2 at MMIO 0x48024000 (irq = 74) is a OMAP UART2
[    0.839111] omap_uart.3: ttyO3 at MMIO 0x481a6000 (irq = 44) is a OMAP UART3
[    0.846893] omap_uart.4: ttyO4 at MMIO 0x481a8000 (irq = 45) is a OMAP UART4
[    0.854675] omap_uart.5: ttyO5 at MMIO 0x481aa000 (irq = 46) is a OMAP UART5
[    0.862823] [drm] Initialized drm 1.1.0 20060810
[    0.876922] brd: module loaded
[    0.885223] loop: module loaded
[    0.888671] i2c-core: driver [tsl2550] using legacy suspend method
[    0.895141] i2c-core: driver [tsl2550] using legacy resume method
[    0.901580] at24 2-0050: 32768 byte 24c256 EEPROM, writable, 64 bytes/write
[    0.908843] The board is a AM335x Starter Kit.
[    0.914215]  omap_hsmmc.0: alias fck already exists
[    0.919647]  omap_hsmmc.1: alias fck already exists
[    0.926116] omap-gpmc omap-gpmc: GPMC revision 6.0
[    0.931121] Registering NAND on CS0
[    0.935729]  da8xx_lcdc.0: alias fck already exists
[    0.941162] da8xx_lcdc da8xx_lcdc.0: GLCD: Found NHD-4.3-ATXI#-T-1 panel
[    0.960571] Console: switching to colour frame buffer device 100x37
[    0.974761] failed to get adapter i2c1
[    0.978729] Configure Bluetooth Enable pin...
[    0.984100] _regulator_get: l3_main.0 supply vdd_core not found, using dummy regulator
[    0.992492] am335x_opp_update: physical regulator not present for core(-22)
[    1.002319] mtdoops: mtd device (mtddev=name/number) must be supplied
[    1.009582] omap2-nand driver initializing
[    1.014221] ONFI flash detected
[    1.017822] NAND device: Manufacturer ID: 0xad, Chip ID: 0xda (Hynix NAND 256MiB 3,3V 8-bit)
[    1.026916] Creating 8 MTD partitions on "omap2-nand.0":
[    1.032501] 0x000000000000-0x000000020000 : "SPL"
[    1.038879] 0x000000020000-0x000000040000 : "SPL.backup1"
[    1.044952] usb 1-1: new high-speed USB device number 2 using musb-hdrc
[    1.053253] 0x000000040000-0x000000060000 : "SPL.backup2"
[    1.060211] 0x000000060000-0x000000080000 : "SPL.backup3"
[    1.067230] 0x000000080000-0x000000260000 : "U-Boot"
[    1.074554] 0x000000260000-0x000000280000 : "U-Boot Env"
[    1.081359] 0x000000280000-0x000000780000 : "Kernel"
[    1.089874] 0x000000780000-0x000010000000 : "File System"
[    1.199951] OneNAND driver initializing
[    1.205535] CAN device driver interface
[    1.209564] CAN bus driver for Bosch D_CAN controller 1.0
[    1.262176] davinci_mdio davinci_mdio.0: davinci mdio revision 1.6
[    1.268615] davinci_mdio davinci_mdio.0: detected phy mask f00fff00
[    1.277435] usb 1-1: New USB device found, idVendor=05e3, idProduct=0608
[    1.284484] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[    1.291931] usb 1-1: Product: USB2.0 Hub
[    1.298828] hub 1-1:1.0: USB hub found
[    1.303100] hub 1-1:1.0: 4 ports detected
[    1.316040] davinci_mdio.0: probed
[    1.319610] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver unknown
[    1.326995] davinci_mdio davinci_mdio.0: phy[1]: device 0:01, driver unknown
[    1.334350] davinci_mdio davinci_mdio.0: phy[2]: device 0:02, driver unknown
[    1.341705] davinci_mdio davinci_mdio.0: phy[3]: device 0:03, driver unknown
[    1.349090] davinci_mdio davinci_mdio.0: phy[4]: device 0:04, driver unknown
[    1.356445] davinci_mdio davinci_mdio.0: phy[5]: device 0:05, driver unknown
[    1.363830] davinci_mdio davinci_mdio.0: phy[6]: device 0:06, driver unknown
[    1.371185] davinci_mdio davinci_mdio.0: phy[7]: device 0:07, driver AR8035 Gigabit Ethernet
[    1.380004] davinci_mdio davinci_mdio.0: phy[20]: device 0:14, driver unknown
[    1.387451] davinci_mdio davinci_mdio.0: phy[21]: device 0:15, driver unknown
[    1.394897] davinci_mdio davinci_mdio.0: phy[22]: device 0:16, driver unknown
[    1.402343] davinci_mdio davinci_mdio.0: phy[23]: device 0:17, driver unknown
[    1.409790] davinci_mdio davinci_mdio.0: phy[24]: device 0:18, driver unknown
[    1.417266] davinci_mdio davinci_mdio.0: phy[25]: device 0:19, driver unknown
[    1.424713] davinci_mdio davinci_mdio.0: phy[26]: device 0:1a, driver unknown
[    1.432159] davinci_mdio davinci_mdio.0: phy[27]: device 0:1b, driver unknown
[    1.439849] PPP generic driver version 2.4.2
[    1.445465] PPP MPPE Compression module registered
[    1.450775] usbcore: registered new interface driver zd1201
[    1.456848] usbcore: registered new interface driver cdc_ether
[    1.463134] usbcore: registered new interface driver cdc_eem
[    1.469177] usbcore: registered new interface driver dm9601
[    1.475067] cdc_ncm: 04-Aug-2011
[    1.478607] usbcore: registered new interface driver cdc_ncm
[    1.484527] Initializing USB Mass Storage driver...
[    1.489868] usbcore: registered new interface driver usb-storage
[    1.496154] USB Mass Storage support registered.
[    1.501342] usbcore: registered new interface driver usbserial
[    1.507598] USB Serial support registered for generic
[    1.513153] usbcore: registered new interface driver usbserial_generic
[    1.519958] usbserial: USB Serial Driver core
[    1.524719] USB Serial support registered for GSM modem (1-port)
[    1.531402] usbcore: registered new interface driver option
[    1.537231] option: v0.7.2:USB Driver for GSM modems
[    1.543029] mousedev: PS/2 mouse device common for all mice
[    1.549865] input: ti-tsc as /devices/platform/omap/ti_tscadc/tsc/input/input0
[    1.558593] omap_rtc am33xx-rtc: rtc core: registered am33xx-rtc as rtc0
[    1.565856] i2c /dev entries driver
[    1.569885] Linux video capture interface: v2.00
[    1.575042] usbcore: registered new interface driver uvcvideo
[    1.581054] USB Video Class driver (1.1.1)
[    1.587432] OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
[    1.594024] _regulator_get: deviceless supply vdd_mpu not found, using dummy regulator
[    1.602752] cpuidle: using governor ladder
[    1.607543] cpuidle: using governor menu
[    1.615264] Registered led device: am335x:EVM_SK:usr0
[    1.615509] Registered led device: am335x:EVM_SK:usr1
[    1.615722] Registered led device: am335x:EVM_SK:mmc0
[    1.615905] Registered led device: am335x:EVM_SK:heartbeat
[    1.618286] usbcore: registered new interface driver usbhid
[    1.624145] usbhid: USB HID core driver
[    1.628753] tiadc tiadc: attached adc driver
[    1.634246] usbcore: registered new interface driver snd-usb-audio
[    1.642395] ALSA device list:
[    1.645477]   No soundcards found.
[    1.649017] oprofile: hardware counters not available
[    1.654327] oprofile: using timer interrupt.
[    1.658813] nf_conntrack version 0.5.0 (3955 buckets, 15820 max)
[    1.665588] ip_tables: (C) 2000-2006 Netfilter Core Team
[    1.671234] TCP cubic registered
[    1.674652] NET: Registered protocol family 17
[    1.679290] can: controller area network core (rev 20090105 abi 8)
[    1.685852] NET: Registered protocol family 29
[    1.690521] can: raw protocol (rev 20090105)
[    1.694976] can: broadcast manager protocol (rev 20090105 t)
[    1.700927] Registering the dns_resolver key type
[    1.705902] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
[    1.713928] ThumbEE CPU extension supported.
[    1.718444] mux: Failed to setup hwmod io irq -22
[    1.724029] Power Management for AM33XX family
[    1.728881] Trying to load am335x-pm-firmware.bin (60 secs timeout)
[    1.735565] Copied the M3 firmware to UMEM
[    1.739929] Cortex M3 Firmware Version = 0x181
[    1.753051] clock: disabling unused clocks to save power
[    1.760711] Detected MACID=1c:ba:8c:96:51:7d
[    1.766448] cpsw: Detected MACID = 1c:ba:8c:96:51:7f
[    1.773925] omap_rtc am33xx-rtc: setting system clock to 2000-01-01 00:00:00 UTC (946684800)
[    1.783325] Waiting for root device /dev/mmcblk0p2...
[    1.856140] mmc0: host does not support reading read-only switch. assuming write-enable.
[    1.864898] usb 1-1.3: new high-speed USB device number 3 using musb-hdrc
[    1.872100] mmc0: new high speed SDHC card at address e624
[    1.878601] mmcblk0: mmc0:e624 SU04G 3.69 GiB
[    1.886871]  mmcblk0: p1 p2
[    1.972656] kjournald starting.  Commit interval 5 seconds
[    1.988159] EXT3-fs (mmcblk0p2): using internal journal
[    1.993652] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
[    2.000885] VFS: Mounted root (ext3 filesystem) on device 179:2.
[    2.007598] Freeing init memory: 232K
[    2.016143] mmc1: card claims to support voltages below the defined range. These will be ignored.
[    2.034271] usb 1-1.3: New USB device found, idVendor=05c6, idProduct=9003
[    2.041473] usb 1-1.3: New USB device strings: Mfr=3, Product=2, SerialNumber=0
[    2.049133] usb 1-1.3: Product: UMTS/HSPA Module
[    2.053955] usb 1-1.3: Manufacturer: Quectel, Incorporated
[    2.062103] mmc1: queuing unknown CIS tuple 0x91 (3 bytes)
[    2.069183] option 1-1.3:1.0: GSM modem (1-port) converter detected
[    2.076873] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB0
[    2.085388] option 1-1.3:1.1: GSM modem (1-port) converter detected
[    2.093261] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB1
[    2.101470] option 1-1.3:1.2: GSM modem (1-port) converter detected
[    2.108856] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB2
[    2.117767] option 1-1.3:1.3: GSM modem (1-port) converter detected
[    2.125640] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB3
[    2.134094] option 1-1.3:1.4: GSM modem (1-port) converter detected
[    2.142211] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB4
[    2.150665] mmc1: new SDIO card at address 0001
[    2.609405] init: ureadahead main process (745) terminated with status 5
[    3.298583] udevd[811]: starting version 175
[    6.756866] init: failsafe main process (1271) killed by TERM signal
[   11.739288] Disabling lock debugging due to kernel taint
[   11.744964] Compat-wireless backport release: ol_R5.SP7.01
[   11.744995] Backport based on wl12xx.git ol_R5.SP4.01-2-g1aa2c8e
[   11.793487] cfg80211: Calling CRDA to update world regulatory domain
[   11.905487] wl12xx: driver version: ol_R5.SP4.01-2-g1aa2c8e
[   11.905487] wl12xx: compilation time: Wed Oct 15 11:39:19 2014
[   13.314483] wl12xx: loaded
[   13.327880] wl12xx: state: 0
[   14.066162] wl12xx: firmware booted (Rev 6.3.10.0.135)
[   24.106903] net eth0: CPSW phy found : id is : 0x0
[   26.103881] PHY: 0:05 - Link is Up - 100/Half

  • 供你参考:

    RTC模块为设备提供一个长的记时模式。基本上是每秒一次。时间可以设定为 12 或 24 小时模式 。时间寄存器有缓冲区,不会因为更改设定值而影响记时的准确性。而且可以设置中断来响应CPU事件,在某一特定的时间间隔如每分钟或每天中断一次。可编程的记时周期等,
    对它的寄存器定义我们可以查看库的RTC.h头文件。

           使用RTC模块的步骤:
    1、 为 RTC 配置主系统时钟。如果需要,需要开启其端口的多路复用功能。
    2、RTC 寄存器一般是写保护的。若要禁用此写保护,编程 RTC 寄存器,必须写入一个特定值到KICK寄存器 (KICK0 和 KICK1)。要执行此操作可以使用 RTCWriteProtectDisable() 这个 API函数。
    3、调用 RTC32KClkSourceSelect() API 函数传递相应的参数,以选择使用内部时钟源或提供 32 KHz 时钟 的外部时钟源。我们的开发板就是外接的32K时钟,如下图所示


    4、调用 RTC32KClkClockControl() API函数传递适当的参数以使能 RTC选择从上一部选定的时钟源输入。
    5、调用 RTCEnable() 来启用 RTC模块。这可确保输入到 RTC 的 32 KHz 时钟有效。
    6、我们可以使用 RTCTimeSet() 函数来设定时间。我们要设定的时间作为一个参数传递给此函数。此函数设置有关寄存器如分钟、 小时、 AM 或 PM。也有 单独的API函数设置这些值。
    7、调用 RTCRun() 后应立即调用 API RTCTimeSet() 来启动时钟,这样可以减少误差。
    8、使用 RTCCalendarSet() 可以设置指定的日期信息。日期信息作为一个参数传递给此函数。此函数设置天、 月份和年份值。也有 Api 来单独设置这些值。
    9、可以通过调用 RTCTimeGet() 和 RTCCalendarGet() 从有关寄存器分别读取当前时间和日期信息。
    10、用户还可以使能在发生特定事件时产生中断。使用 RTCIntTimerEnable() 启用中断。中断事件可以是一秒、 分钟、 小时或一天。
    11、RTC模块也可以在它达到一定的时间或读取日期时生成中断。这些称为报警中断,如果想启用它们使用 RTCIntAlarmEnable() 函数将报警时间写入 RTC 的报警寄存器。


    从以上说明可见RTC模块的强大,完全可以作为一个全功能的时钟使用。

    下面这份例程运行时在串口要求用户输入时间和日期,并把他们写入RTC相关寄存器,然后就会在串口同步显示出当前日期信息

    1. #include "evmskAM335x.h"
    2. #include "soc_AM335x.h"
    3. #include "interrupt.h"
    4. #include "uartStdio.h"
    5. #include "cache.h"
    6. #include "rtc.h"
    7. #include "mmu.h"
    8. /*****************************************************************************
    9. **                 INTERNAL MACRO DEFINITIONS
    10. *****************************************************************************/
    11. #define MASK_HOUR               (0xFF000000u)
    12. #define MASK_MINUTE             (0x00FF0000u)
    13. #define MASK_SECOND             (0x0000FF00u)
    14. #define MASK_MERIDIEM           (0x000000FFu)
    15. #define HOUR_SHIFT              (24u)
    16. #define MINUTE_SHIFT            (16u)
    17. #define SECOND_SHIFT            (8u)
    18. #define MASK_DAY                (0xFF000000u)
    19. #define MASK_MONTH              (0x00FF0000u)
    20. #define MASK_YEAR               (0x0000FF00u)
    21. #define MASK_DOTW               (0x000000FFu)
    22. #define DAY_SHIFT               (24u)
    23. #define MONTH_SHIFT             (16u)
    24. #define YEAR_SHIFT              (8u)
    25. #define RTC_INST_BASE           (SOC_RTC_0_REGS)
    26. #define RTC_INT_NUM             (SYS_INT_RTCINT)
    27. /* Definitions related to MMU Configuration. */
    28. #define START_ADDR_DDR          (0x80000000u)
    29. #define START_ADDR_DEV          (0x44000000u)
    30. #define START_ADDR_OCMC         (0x40300000u)
    31. #define NUM_SECTIONS_DDR        (512u)
    32. #define NUM_SECTIONS_DEV        (960u)
    33. #define NUM_SECTIONS_OCMC       (1u)
    34. /******************************************************************************
    35. **                 INTERNAL FUNCTION PROTOTYPES
    36. ******************************************************************************/
    37. static void CalendarResolve(unsigned int calendarValue);
    38. static unsigned char ASCIIToInt(unsigned char byte);
    39. static unsigned int IntToASCII(unsigned char byte);
    40. static void TimeResolve(unsigned int timeValue);
    41. static unsigned int UserCalendarInfoGet(void);
    42. static unsigned int UserTimeInfoGet(void);
    43. static void MMUConfigAndEnable(void);
    44. static void RTCINTCConfigure(void);
    45. static void RTCIsr(void);
    46. /******************************************************************************
    47. **                 INTERNAL VARIABLE DEFINITIONS
    48. ******************************************************************************/
    49. /* Page tables start must be aligned in 16K boundary */
    50. #ifdef __TMS470__
    51. #pragma DATA_ALIGN(pageTable, MMU_PAGETABLE_ALIGN_SIZE);
    52. static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY];
    53. #elif defined(__IAR_SYSTEMS_ICC__)
    54. #pragma data_alignment=MMU_PAGETABLE_ALIGN_SIZE
    55. static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY];
    56. #elif defined(gcc)
    57. static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY]
    58. __attribute__((aligned(MMU_PAGETABLE_ALIGN_SIZE)));
    59. #else
    60. #error "Unsupported Compiler. \r\n"
    61. #endif
    62. /******************************************************************************
    63. **                 INTERNAL FUNCTION DEFINITIONS
    64. ******************************************************************************/
    65. /*
    66. ** This function will setup the MMU. The function maps three regions -
    67. ** 1. DDR
    68. ** 2. OCMC RAM
    69. ** 3. Device memory
    70. ** The function also enables the MMU.
    71. */
    72. static void MMUConfigAndEnable(void)
    73. {
    74.     /*
    75.     ** Define DDR memory region of AM335x. DDR can be configured as Normal
    76.     ** memory with R/W access in user/privileged modes. The cache attributes
    77.     ** specified here are,
    78.     ** Inner - Write through, No Write Allocate
    79.     ** Outer - Write Back, Write Allocate
    80.     */
    81.     REGION regionDdr = {
    82.                         MMU_PGTYPE_SECTION, START_ADDR_DDR, NUM_SECTIONS_DDR,
    83.                         MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
    84.                                                          MMU_CACHE_WB_WA),
    85.                         MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
    86.                         (unsigned int*)pageTable
    87.                        };
    88.     /*
    89.     ** Define OCMC RAM region of AM335x. Same Attributes of DDR region given.
    90.     */
    91.     REGION regionOcmc = {
    92.                          MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,
    93.                          MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
    94.                                                           MMU_CACHE_WB_WA),
    95.                          MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
    96.                          (unsigned int*)pageTable
    97.                         };
    98.     /*
    99.     ** Define Device Memory Region. The region between OCMC and DDR is
    100.     ** configured as device memory, with R/W access in user/privileged modes.
    101.     ** Also, the region is marked 'Execute Never'.
    102.     */
    103.     REGION regionDev = {
    104.                         MMU_PGTYPE_SECTION, START_ADDR_DEV, NUM_SECTIONS_DEV,
    105.                         MMU_MEMTYPE_DEVICE_SHAREABLE,
    106.                         MMU_REGION_NON_SECURE,
    107.                         MMU_AP_PRV_RW_USR_RW  | MMU_SECTION_EXEC_NEVER,
    108.                         (unsigned int*)pageTable
    109.                        };
    110.     /* Initialize the page table and MMU */
    111.     MMUInit((unsigned int*)pageTable);
    112.     /* Map the defined regions */
    113.     MMUMemRegionMap(®ionDdr);
    114.     MMUMemRegionMap(®ionOcmc);
    115.     MMUMemRegionMap(®ionDev);
    116.     /* Now Safe to enable MMU */
    117.     MMUEnable((unsigned int*)pageTable);
    118. }
    119. /*
    120. ** Main function.
    121. */
    122. int main(void)
    123. {
    124.     unsigned int userCalendar = 0;
    125.     unsigned int userTime = 0;
    126.     /* Configure and enable the MMU. */
    127.     MMUConfigAndEnable();
    128.     /* Enable all levels of Cache. */
    129.     CacheEnable(CACHE_ALL);
    130.    
    131.     /* Configuring the UART STDIO instance. */
    132.     UARTStdioInit();
    133.     /* Performing the System Clock configuration for RTC. */
    134.     RTCModuleClkConfig();
    135.    
    136.     /* Disabling Write Protection for RTC registers.*/
    137.     RTCWriteProtectDisable(RTC_INST_BASE);
    138.     /* Selecting Internal Clock source for RTC. */
    139.     RTC32KClkSourceSelect(RTC_INST_BASE, RTC_INTERNAL_CLK_SRC_SELECT);
    140.     /* Enabling RTC to receive the Clock inputs. */
    141.     RTC32KClkClockControl(RTC_INST_BASE, RTC_32KCLK_ENABLE);
    142.     /* Enable the RTC module. */
    143.     RTCEnable(RTC_INST_BASE);
    144.     UARTPuts("StarterWare AM335x RTC Application.\r\n", -2);
    145.     /* Receiving Time related information from the user. */
    146.     userTime = UserTimeInfoGet();
    147.     /* Receiving Calendar related information from the user. */
    148.     userCalendar = UserCalendarInfoGet();
    149.    
    150.     /* Programming calendar information in the Calendar registers. */
    151.     RTCCalendarSet(RTC_INST_BASE, userCalendar);
    152.     /* Programming the time information in the Time registers. */
    153.     RTCTimeSet(RTC_INST_BASE, userTime);
    154.    
    155.     /* Set the 32KHz counter to run. */
    156.     RTCRun(RTC_INST_BASE);
    157.     UARTPuts("\r\n\r\n", -2);
    158.     UARTPuts("Current Time And Date:\r\n", -1);
    159.     /* Enabling IRQ in CPSR of ARM processor. */
    160.     IntMasterIRQEnable();
    161.     /* Configure the AINTC to receive RTC interrupts. */
    162.     RTCINTCConfigure();
    163.     /* Enabling RTC interrupts. Configuring RTC to interrupt every second.*/
    164.     RTCIntTimerEnable(RTC_INST_BASE, RTC_INT_EVERY_SECOND);
    165.     while(1);
    166. }
    167. /*
    168. ** This function receives time related information from the user.
    169. */
    170. static unsigned int UserTimeInfoGet()
    171. {
    172.     unsigned char minute[2] = {0};
    173.     unsigned char second[2] = {0};
    174.     unsigned char hour[2] = {0};
    175.     unsigned int hourTime = 0;
    176.     unsigned int minTime = 0;
    177.     unsigned int secTime = 0;
    178.     unsigned int lIndex = 0;
    179.     unsigned int time = 0;
    180.     UARTPuts("\nEnter the time in 24 hour format.\r\n", -1);
    181.     UARTPuts("Example (hh:mm:ss) 20:15:09\r\n", -1);
    182.     UARTPuts("\r\nEnter Hours: \r\n", -2);
    183.     /*
    184.     ** Collecting the 'Hour' information. The values collected shall be in
    185.     ** the ASCII form of the numbers entered.
    186.     */
    187.     do
    188.     {
    189.         hour[lIndex] = UARTGetc();
    190.         UARTPutc(hour[lIndex]);
    191.         lIndex++;
    192.     }while((lIndex < 2) && (hour[lIndex - 1] != '\r'));
    193.     UARTPuts("\r\nEnter Minutes:\r\n", -2);
    194.     lIndex = 0;
    195.     /*
    196.     ** Collecting the 'Minute' information. The values collected shall be in
    197.     ** the ASCII form of the numbers entered.
    198.     */
    199.     do
    200.     {
    201.         minute[lIndex] = UARTGetc();
    202.         UARTPutc(minute[lIndex]);
    203.         lIndex++;
    204.     }while((lIndex < 2) && (minute[lIndex - 1] != '\r'));
    205.     UARTPuts("\r\nEnter Seconds:\r\n", -1);
    206.     lIndex = 0;
    207.     /*
    208.     ** Collecting the 'Second' information. The values collected shall be in
    209.     ** the ASCII form of the numbers entered.
    210.     */
    211.     do
    212.     {
    213.         second[lIndex] = UARTGetc();
    214.         UARTPutc(second[lIndex]);
    215.         lIndex++;
    216.     }while((lIndex < 2) && (second[lIndex - 1] != '\r'));
    217.     /* Converting the ASCII value of 'Hours' to its equivalent decimal value. */
    218.     if(hour[0] != '\r')
    219.     {
    220.         hourTime = (ASCIIToInt(hour[0]) << 0x04);
    221.         if(hour[1] != '\r')
    222.         {
    223.             hourTime |= ASCIIToInt(hour[1]);
    224.         }
    225.         else
    226.         {
    227.             hourTime = hourTime >> 0x04;
    228.         }
    229.     }
    230.     /* Converting the ASCII value of 'Minutes' to its equivalent decimal value. */
    231.     if(minute[0] != '\r')
    232.     {
    233.         minTime = (ASCIIToInt(minute[0]) << 0x04);
    234.         if(minute[1] != '\r')
    235.         {
    236.             minTime |= ASCIIToInt(minute[1]);
    237.         }
    238.         else
    239.         {
    240.             minTime = minTime >> 0x04;
    241.         }
    242.     }
    243.     /* Converting the ASCII value of 'Seconds' to its equivalent decimal value. */
    244.     if(second[0] != '\r')
    245.     {
    246.         secTime = (ASCIIToInt(second[0]) << 0x04);
    247.         if(second[1] != '\r')
    248.         {
    249.             secTime |= ASCIIToInt(second[1]);
    250.         }
    251.         else
    252.         {
    253.             secTime = secTime >> 0x04;
    254.         }
    255.     }
    256.     /*
    257.     ** Consolidating the decimal values of Hours, Minutes and Seconds to
    258.     ** obtain the Time.
    259.     */
    260.     time = (hourTime << HOUR_SHIFT);
    261.     time |= (minTime << MINUTE_SHIFT);
    262.     time |= (secTime << SECOND_SHIFT);
    263.     return time;
    264. }
    265. /*
    266. ** This function receives calendar related information from the user.
    267. */
    268. static unsigned int UserCalendarInfoGet()
    269. {
    270.     unsigned char monthArr[2] = {0};
    271.     unsigned char yearArr[2] = {0};
    272.     unsigned char dotwArr[2] = {0};
    273.     unsigned char dayArr[2] = {0};
    274.     unsigned int calendar = 0;
    275.     unsigned int lIndex = 0;
    276.     unsigned int month = 0;
    277.     unsigned int year = 0;
    278.     unsigned int dotw = 0;
    279.     unsigned int day = 0;
    280.     UARTPuts("\r\n\r\nEnter the calendar information.\r\n", -2);
    281.     UARTPuts("Example (DD:MM:YY) 31:03:73\r\n", -2);
    282.    
    283.     UARTPuts("\r\nEnter the day of the month: \r\n", -2);
    284.    
    285.     /*
    286.     ** Collecting the 'Day of the Month' information. The values collected
    287.     ** shall be in the ASCII form of the numbers entered.
    288.     */
    289.     do
    290.     {
    291.         dayArr[lIndex] = UARTGetc();
    292.         UARTPutc(dayArr[lIndex]);
    293.         lIndex++;
    294.     }while((lIndex < 2) && (dayArr[lIndex - 1] != '\r'));
    295.     UARTPuts("\r\nEnter the month (Jan=01, Dec=12):\r\n", -2);
    296.     lIndex = 0;
    297.     /*
    298.     ** Collecting the 'Month' information. The values collected
    299.     ** shall be in the ASCII form of the numbers entered.
    300.     */
    301.     do
    302.     {
    303.         monthArr[lIndex] = UARTGetc();
    304.         UARTPutc(monthArr[lIndex]);
    305.         lIndex++;        
    306.     }while((lIndex < 2) && (monthArr[lIndex - 1] != '\r'));
    307.     UARTPuts("\r\nEnter the year (Ex: 2010=10, 1987=87:):\r\n", -1);
    308.     lIndex = 0;
    309.     /*
    310.     ** Collecting the 'Year' information. The values collected
    311.     ** shall be in the ASCII form of the numbers entered.
    312.     */
    313.     do
    314.     {
    315.         yearArr[lIndex] = UARTGetc();
    316.         UARTPutc(yearArr[lIndex]);
    317.         lIndex++;
    318.     }while((lIndex < 2) && (yearArr[lIndex - 1] != '\r'));
    319.     UARTPuts("\r\nEnter the Day of the Week (Ex:Sun=00, Sat=06):\r\n", -3);
    320.     lIndex = 0;
    321.     /*
    322.     ** Collecting the 'Day of the Week' information. The values collected
    323.     ** shall be in the ASCII form of the numbers entered.
    324.     */
    325.     do
    326.     {
    327.         dotwArr[lIndex] = UARTGetc();
    328.         UARTPutc(dotwArr[lIndex]);
    329.         lIndex++;
    330.     }while((lIndex < 2) && (dotwArr[lIndex - 1] != '\r'));
    331.     /*
    332.     ** Converting the ASCII value of 'Day of the Month' to its equivalent
    333.     ** decimal value.
    334.     */
    335.     if(dayArr[0] != '\r')
    336.     {
    337.         day = (ASCIIToInt(dayArr[0]) << 0x04);
    338.         if(dayArr[1] != '\r')
    339.         {
    340.             day |= ASCIIToInt(dayArr[1]);
    341.         }
    342.         else
    343.         {
    344.             day = day  >> 0x04;
    345.         }
    346.     }
    347.     /* Converting the ASCII value of 'Month' to its equivalent decimal value. */
    348.     if(monthArr[0] != '\r')
    349.     {
    350.         month = (ASCIIToInt(monthArr[0]) << 0x04);
    351.         if(monthArr[1] != '\r')
    352.         {
    353.             month |= ASCIIToInt(monthArr[1]);
    354.         }
    355.         else
    356.         {
    357.             month = month >> 0x04;
    358.         }
    359.     }
    360.     /* Converting the ASCII value of 'Year' to its equivalent decimal value. */
    361.     if(yearArr[0] != '\r')
    362.     {
    363.         year = (ASCIIToInt(yearArr[0]) << 0x04);
    364.         if(yearArr[1] != '\r')
    365.         {
    366.             year |= ASCIIToInt(yearArr[1]);
    367.         }
    368.         else
    369.         {
    370.             year = year >> 0x04;
    371.         }
    372.     }
    373.     /*
    374.     ** Converting the ASCII value of 'Day of the Week' to its equivalent
    375.     ** decimal value.
    376.     */
    377.     if(dotwArr[0] != '\r')
    378.     {
    379.         dotw = (ASCIIToInt(dotwArr[0]) << 0x04);
    380.         if(dotwArr[1] != '\r')
    381.         {
    382.             dotw |= ASCIIToInt(dotwArr[1]);
    383.         }
    384.         else
    385.         {
    386.             dotw = dotw >> 0x04;
    387.         }
    388.     }
    389.     /*
    390.     ** Consolidating the decimal values of Day of the Month, Month, Year
    391.     ** and Day of the Week to obtain the Date.
    392.     */
    393.     calendar =  day << DAY_SHIFT;     
    394.     calendar |= month << MONTH_SHIFT;
    395.     calendar |= year << YEAR_SHIFT;
    396.     calendar |= dotw;
    397.     return calendar;
    398. }  
    399. /*
    400. ** This function prints the current time read from the RTC registers.
    401. */
    402. static void TimeResolve(unsigned int timeValue)
    403. {
    404.     unsigned char timeArray[3] = {0};              
    405.     unsigned char bytePrint[2] = {0};
    406.     unsigned int asciiTime = 0;
    407.     unsigned int lIndex = 0;
    408.     unsigned int count = 0;
    409.    
    410.     /*
    411.     ** The variable 'timeValue' will have the time in the format
    412.     ** . Now, obtaining the individual fields
          ** to facilitate their display.
    413.     */
    414.     timeArray[0] = (unsigned char)((timeValue & MASK_HOUR) >> HOUR_SHIFT);
    415.     timeArray[1] = (unsigned char)((timeValue & MASK_MINUTE) >> MINUTE_SHIFT);
    416.     timeArray[2] = (unsigned char)((timeValue & MASK_SECOND) >> SECOND_SHIFT);
    417.     /* Prints the time in the format: . */
          while(count < 3)
    418.     {
    419.         lIndex = 0;
    420.         asciiTime = IntToASCII(timeArray[count]);
    421.         bytePrint[0] = (unsigned char)((asciiTime & 0x0000FF00) >> 0x08);
    422.         bytePrint[1] = (unsigned char)(asciiTime & 0x000000FF);
    423.         while(lIndex < 2)
    424.         {   
    425.             UARTPutc(bytePrint[lIndex]);
    426.             lIndex++;
    427.         }
    428.         count++;
    429.         if(count != 3)
    430.         {
    431.             UARTPutc(':');
    432.         }
    433.         else
    434.         {
    435.             UARTPutc(' ');
    436.         }
    437.     }
    438. }
    439. /*
    440. ** This function prints the calendar information read from the RTC registers.
    441. */
    442. static void CalendarResolve(unsigned int calendarValue)
    443. {
    444.     unsigned char calendarArray[3] = {0};
    445.     unsigned char dotwString[4] = {0};
    446.     unsigned char bytePrint[2] = {0};
    447.     unsigned int asciiCalendar = 0;
    448.     unsigned int dotwValue = 0;
    449.     unsigned int lIndex = 0;
    450.     unsigned int count = 0;
    451.     /*
    452.     ** The variable 'calendarValue' will have the date in the format
    453.     ** . Now, obtaining the individual fields
          ** to facilitate their display.
    454.     */
    455.     calendarArray[0] = (unsigned char)((calendarValue & MASK_DAY) >> DAY_SHIFT);
    456.     calendarArray[1] = (unsigned char)((calendarValue & MASK_MONTH) >> MONTH_SHIFT);
    457.     calendarArray[2] = (unsigned char)((calendarValue & MASK_YEAR) >> YEAR_SHIFT);
    458.     dotwValue = (calendarValue & MASK_DOTW);
    459.     switch(dotwValue)
    460.     {
    461.         case 0x00:
    462.              dotwString[0] = 'S';
    463.              dotwString[1] = 'u';
    464.              dotwString[2] = 'n';
    465.              dotwString[3] = '\0';
    466.         break;
    467.         case 0x01:
    468.              dotwString[0] = 'M';
    469.              dotwString[1] = 'o';
    470.              dotwString[2] = 'n';
    471.              dotwString[3] = '\0';
    472.         break;
    473.         case 0x02:
    474.              dotwString[0] = 'T';
    475.              dotwString[1] = 'u';
    476.              dotwString[2] = 'e';
    477.              dotwString[3] = '\0';
    478.         break;
    479.         case 0x03:
    480.              dotwString[0] = 'W';
    481.              dotwString[1] = 'e';
    482.              dotwString[2] = 'd';
    483.              dotwString[3] = '\0';
    484.         break;
    485.         case 0x04:
    486.              dotwString[0] = 'T';
    487.              dotwString[1] = 'h';
    488.              dotwString[2] = 'u';
    489.              dotwString[3] = '\0';
    490.         break;
    491.         case 0x05:
    492.              dotwString[0] = 'F';
    493.              dotwString[1] = 'r';
    494.              dotwString[2] = 'i';
    495.              dotwString[3] = '\0';
    496.         break;
    497.         case 0x06:
    498.              dotwString[0] = 'S';
    499.              dotwString[1] = 'a';
    500.              dotwString[2] = 't';
    501.              dotwString[3] = '\0';
    502.         default:
    503.         break;
    504.     }
    505.    
    506.     /* Prints the date in the format: . */
          while(count < 3)
    507.     {
    508.         lIndex = 0;
    509.         asciiCalendar = IntToASCII(calendarArray[count]);
    510.         bytePrint[0] = (unsigned char)((asciiCalendar & 0x0000FF00) >> 0x08);
    511.         bytePrint[1] = (unsigned char)(asciiCalendar & 0x000000FF);
    512.         while(lIndex < 2)
    513.         {
    514.             UARTPutc(bytePrint[lIndex]);
    515.             lIndex++;
    516.         }
    517.         count++;
    518.         if(count != 3)
    519.         {
    520.             UARTPutc('-');
    521.         }
    522.         else
    523.         {
    524.             UARTPutc(' ');
    525.         }
    526.     }  
    527.     UARTPuts((char *)dotwString, -2);
    528. }
    529. /*
    530. ** This function converts the nibbles of an 8-bit number to their ASCII
    531. ** equivalent value. The 8-bit number is passed as a parameter to this
    532. ** function.
    533. ** For Example, if a number 19 is given to this function, this function
    534. ** returns 0x3139. Here, 0x31 is the ASCII value of 1 and 0x39 is the
    535. ** ASCII value of 9.
    536. */
    537. static unsigned int IntToASCII(unsigned char byte)
    538. {
    539.     unsigned char highNibble = 0;
    540.     unsigned char lowNibble = 0;
    541.     unsigned int retVal = 0;
    542.     lowNibble = (byte & 0x0F);
    543.     highNibble = (byte & 0xF0) >> 0x04;
    544.     retVal = (lowNibble + 0x30);
    545.     retVal |= ((highNibble + 0x30) << 0x08);
    546.     return retVal;
    547. }
    548. /*
    549. ** This function converts the ASCII value of a hexadecimal number to its
    550. ** corresponding hexadecimal value.
    551. */
    552. static unsigned char ASCIIToInt(unsigned char byte)
    553. {
    554.     unsigned char retVal = 0;
    555.     /* For numbers from 0x0 to 0x9.*/
    556.     if((byte >= 0x30) && (byte <= 0x39))
    557.     {
    558.         retVal = byte - 0x30;
    559.     }
    560.     /* For alphabets from A to F.*/
    561.     else if((byte >= 0x41) && (byte <= 0x46))
    562.     {
    563.         retVal = byte - 0x37;
    564.     }
    565.    
    566.     return retVal;
    567. }
    568. /*
    569. ** This function configures the Interrupt Controller(INTC) to receive
    570. ** RTC interrupts.
    571. */
    572. static void RTCINTCConfigure(void)
    573. {
    574.     /* Initializing the ARM Interrupt Controller. */
    575.     IntAINTCInit();
    576.     /* Registering the Interrupt Service Routine(ISR). */
    577.     IntRegister(RTC_INT_NUM, RTCIsr);
    578.     /* Setting the priority for the system interrupt in AINTC. */
    579.     IntPrioritySet(RTC_INT_NUM, 0, AINTC_HOSTINT_ROUTE_IRQ);
    580.     /* Enabling the system interrupt in AINTC. */
    581.     IntSystemEnable(RTC_INT_NUM);   
    582. }
    583. /*
    584. ** This is the Interrupt Service Routine(ISR) for RTC.
    585. */
    586. static void RTCIsr(void)
    587. {
    588.     unsigned int calendarValue = 0;   
    589.     unsigned int timeValue = 0;
    590.         
    591.     /* Read the current time from RTC time registers. */
    592.     timeValue = RTCTimeGet(RTC_INST_BASE);
    593.     /* Decode the time in 'timeValue' and display it on console.*/
    594.     TimeResolve(timeValue);
    595.     /* Read the current date from the RTC calendar registers. */
    596.     calendarValue = RTCCalendarGet(RTC_INST_BASE);
    597.    
    598.     UARTPuts("   ", -2);
    599.     /* Decode  the date in 'calendarValue' and display it on console.*/
    600.     CalendarResolve(calendarValue);
    601.     UARTPuts("\r", -2);   
    602. }

  • 对于你反应的这个问题,可否确认一下,你制版所使用的芯片版本号,是PG1.0还是PG2.1?

    参考AM335x的ERRATA: http://www.ti.com/lit/er/sprz360f/sprz360f.pdf

    如果是芯片1.0版本的话,这个问题是已经发现了的。

    Advisory 1.0.5 RTC: 32.768-kHZ Clock is Gating Off

  • 我查看了文件和我們的 CPU-AM3352BZCZ30

    它是屬於2.1 的.....

    謝謝。

  • 看到你的log中有:[    1.773925] omap_rtc am33xx-rtc: setting system clock to 2000-01-01 00:00:00 UTC (946684800)

    应该是在这里重置了你的RTC时间,需要根据这个log追代码了。

  • 关于AM335x的RTC部分,我做了一个总结,看看对你有没有什么参考:

    http://www.deyisupport.com/question_answer/dsp_arm/sitara_arm/f/25/t/78281.aspx

  • Hi Jian

    看了一些介紹,知道有兩種RTC模組,我們是使用 tps65910,但看 kernel 訊息

    omap_rtc am33xx-rtc: rtc core: registered am33xx-rtc as rtc0

    而不是

     tps65910-rtc tps65910-rtc: rtc core: registered tps65910-rtc as rtc0

    請問這和我RTC不能保持時間也有關係?

    我將 CONFIG_RTC_DRV_OMAP 注解掉,kernel 訊息出現

    drivers/rtc/hctosys.c: unable to open rtc device (rtc0)

    最後不能 hwclock -r

    請問是不是有專門的 tps65910 driver? 謝謝。

  • 应该是用的芯片内部的RTC,如果不能保持时间,先要看一下RTC这部分的供电电路。

  • Hi Jian

    謝謝。

    我明天會再去確認供電電路,因為我有試過別的BSP, 開機訊息是有

      tps65910-rtc tps65910-rtc: rtc core: registered tps65910-rtc as rtc0

    這訊息,所以我才懷疑是這樣才讓鈕扣電池(測量有電)無法關機後繼續保持RTC。

    謝謝。

  • 出现RTC时间不能掉电保存,大部分都是供电电路出问题了

    仔细检查一下吧

  • Hi Leo

    我們這邊有別的BSP可以做測試,它是可以用電池保持時間,所以我想硬體部分,應該是沒問題的...

    只是我不確定是不是因為 rtc core: 不是由tps65910 as rtc0 的關係,查看電路,電池供應 3.0V 給 PMIC & RTC (tps65910)。

    另外,我很怕是kernel 版本,因為我們是使用linux-3.2.0-psp04.06.00.11 這個版本。

    http://www.360doc.com/content/12/0705/15/9305922_222419815.shtml   --> 這是我找尋相關的網址,是否能協助我修改。

    萬分感謝。

  • 我在網路上有搜尋到 tps65910 增加 RTC 功能的 driver ,下禮拜來試看看

  • Hi TI

    我還沒放棄RTC,我試著將網路上的rtc-tps65910 build 進 3.2 kernel,但出現此 error

      CHK     include/linux/version.h
      CHK     include/generated/utsrelease.h
    make[2]: `include/generated/mach-types.h' is up to date.
      CALL    scripts/checksyscalls.sh
      CHK     include/generated/compile.h
      CHK     kernel/config_data.h
    make[3]: *** No rule to make target `drivers/rtc/rtc-tps65910.o', needed by `drivers/rtc/built-in.o'.  Stop.
    make[2]: *** [drivers/rtc] Error 2
    make[1]: *** [drivers] Error 2
    ========================================================================================

    這是我的 patch

    diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
    index 34a7129..d629125 100644
    --- a/drivers/rtc/Kconfig
    +++ b/drivers/rtc/Kconfig
    @@ -1070,4 +1070,14 @@ config RTC_DRV_PUV3
              This drive can also be built as a module. If so, the module
              will be called rtc-puv3.
     
    +config RTC_DRV_TPS65910
    +       tristate "TI TPS65910 RTC driver"
    +       depends on RTC_CLASS
    +       help
    +         If you say yes here you get support for the RTC on the
    +         TPS65910 chips.
    +
    +         This driver can also be built as a module. If so, the module
    +         will be called rtc-tps65910.
    +
     endif # RTC_CLASS
    diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
    index 6e69823..cb3c29f 100644
    --- a/drivers/rtc/Makefile
    +++ b/drivers/rtc/Makefile
    @@ -109,3 +109,4 @@ obj-$(CONFIG_RTC_DRV_VT8500)        += rtc-vt8500.o
     obj-$(CONFIG_RTC_DRV_WM831X)   += rtc-wm831x.o
     obj-$(CONFIG_RTC_DRV_WM8350)   += rtc-wm8350.o
     obj-$(CONFIG_RTC_DRV_X1205)    += rtc-x1205.o
    +obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o
    diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
    index cfc1f76..174b192 100644
    --- a/include/linux/mfd/tps65910.h
    +++ b/include/linux/mfd/tps65910.h
    @@ -136,6 +136,16 @@
      *
      */
     
    +/* RTC_CTRL_REG bitfields */
    +#define TPS65910_RTC_CTRL_STOP_RTC                     0x01 /*0=stop, 1=run */
    +#define TPS65910_RTC_CTRL_GET_TIME                     0x40
    +
    +/* RTC_STATUS_REG bitfields */
    +#define TPS65910_RTC_STATUS_ALARM               0x40
    +
    +/* RTC_INTERRUPTS_REG bitfields */
    +#define TPS65910_RTC_INTERRUPTS_EVERY           0x03
    +#define TPS65910_RTC_INTERRUPTS_IT_ALARM        0x08
    ================================================================================

    還有另一個疑問是,我在u-boot 嘗試寫 value 到在 0x2d 的 tps65910 的 SECONDS_REG MINUTES_REG 和  HOURS_REG 都沒辦法寫入, RTC_PWDN 我看預設是 1 ( 0x3f=70 ),但我把0x3f 值設為 50 ,也就是 RTC_PWDN 設為 0 ,仍然無法改變 SECONDS_REG MINUTES_REG 和  HOURS_REG 這些值,請問這甚麼狀況呢? 謝謝。

  • Hi TI

    我需要求救。

    這是我在網路上參考的patch,我大致上知道他的意思。就是 tps65910 的 RTC module 他是在 rtc-twl.c 裡面實現。但我trace code 看不太出來 tps65910怎麼和他做連結,是在這邊嗎?

    static struct mfd_cell tps65910s[] = {
         {
             .name = "tps65910-pmic",
         },
         {
    -        .name = "tps65910-rtc",
    +        .name = "twl_rtc",
         },
         {
             .name = "tps65910-power",

    只要我改 tps65910-rtc 變成 twl-rtc 板子就會出現 crash,我不知道從何修改了,或者我這方向錯誤? 謝謝。  我們的 kernel 版本為 linux-3.2.0-psp04.06.00.11

    拜託我需要方向,謝謝。

    這是 crash 訊息

    760498] Unable to handle kernel NULL pointer dereference at virtual address 00000000
    [    1.768981] pgd = c0004000
    [    1.771789] [00000000] *pgd=00000000
    [    1.775543] Internal error: Oops: 5 [#1]
    [    1.779632] Modules linked in:
    [    1.782836] CPU: 0    Not tainted  (3.2.0-g6736e09-dirty #40)
    [    1.788818] PC is at twl_rtc_probe+0x24/0x214
    [    1.793365] LR is at twl_rtc_probe+0x24/0x214
    [    1.797912] pc : [<c04272f0>]    lr : [<c04272f0>]    psr: 60000013
    [    1.797912] sp : cf01de30  ip : cf01de30  fp : cf01de64
    [    1.809906] r10: c05de220  r9 : 00000000  r8 : 00000000
    [    1.815338] r7 : cf0d3808  r6 : c0658ed8  r5 : cf0d3800  r4 : 00000000
    [    1.822143] r3 : c04272cc  r2 : 00000000  r1 : 00000000  r0 : fffffffa
    [    1.828948] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
    [    1.836578] Control: 10c5387d  Table: 80004019  DAC: 00000015
    [    1.842590] Process swapper (pid: 1, stack limit = 0xcf01c2f0)
    [    1.848663] Stack: (0xcf01de30 to 0xcf01e000)
    [    1.853210] de20:                                     00000000 c05de220 cf01de54 cf01de48
    [    1.861724] de40: c00fb824 cf0d3808 c0682e1c c0658ed8 c064546c 00000000 cf01de74 cf01de68
    [    1.870269] de60: c022d47c c04272d8 cf01dea4 cf01de78 c022be90 c022d46c cf01dea4 cf01de88
    [    1.878814] de80: c022dd10 cf0d3808 c064546c cf0d383c cf292b40 00000000 cf01dec4 cf01dea8
    [    1.887329] dea0: c022c130 c022bde8 c022c09c 00000000 c064546c c022c09c cf01deec cf01dec8
    [    1.895874] dec0: c022abec c022c0a8 cf006ef8 cf0bb170 c01bb8b4 c064546c c064546c c0638e40
    [    1.904418] dee0: cf01defc cf01def0 c022bab8 c022abac cf01df2c cf01df00 c022b70c c022baa0
    [    1.912933] df00: c054f4e0 cf01df10 c064546c c05f5924 c065ef00 cf01c000 00000000 c05de220
    [    1.921478] df20: cf01df54 cf01df30 c022c64c c022b590 c0684a6c c05f5924 c065ef00 cf01c000
    [    1.930023] df40: 00000000 c05de220 cf01df64 cf01df58 c022d82c c022c5d8 cf01df7c cf01df68
    [    1.938537] df60: c05de268 c022d7ec 00000000 c05f57b0 cf01dfd4 cf01df80 c000876c c05de22c
    [    1.947082] df80: c00741d4 c00f2cd8 0000007f 00000000 cf01dfb4 323169c0 00000037 00000000
    [    1.955627] dfa0: cf01dfbc 0000018c c0625420 c05f57b0 c05f5924 c00408d0 00000013 00000000
    [    1.964141] dfc0: 00000000 00000000 cf01dff4 cf01dfd8 c05bc88c c0008650 00000000 00000000
    [    1.972686] dfe0: 00000000 c05bc808 00000000 cf01dff8 c00408d0 c05bc814 755955c5 4dc77ffd
    [    1.981201] Backtrace:
    [    1.983795] [<c04272cc>] (twl_rtc_probe+0x0/0x214) from [<c022d47c>] (platform_drv_probe+0x1c/0x20)
    [    1.993225]  r8:00000000 r7:c064546c r6:c0658ed8 r5:c0682e1c r4:cf0d3808
    [    2.000244] [<c022d460>] (platform_drv_probe+0x0/0x20) from [<c022be90>] (driver_probe_device+0xb4/0x2c0)
    [    2.010223] [<c022bddc>] (driver_probe_device+0x0/0x2c0) from [<c022c130>] (__driver_attach+0x94/0x98)
    [    2.019927]  r8:00000000 r7:cf292b40 r6:cf0d383c r5:c064546c r4:cf0d3808
    [    2.026947] [<c022c09c>] (__driver_attach+0x0/0x98) from [<c022abec>] (bus_for_each_dev+0x4c/0x94)
    [    2.036285]  r6:c022c09c r5:c064546c r4:00000000 r3:c022c09c
    [    2.042205] [<c022aba0>] (bus_for_each_dev+0x0/0x94) from [<c022bab8>] (driver_attach+0x24/0x28)
    [    2.051391]  r6:c0638e40 r5:c064546c r4:c064546c
    [    2.056213] [<c022ba94>] (driver_attach+0x0/0x28) from [<c022b70c>] (bus_add_driver+0x188/0x270)
    [    2.065368] [<c022b584>] (bus_add_driver+0x0/0x270) from [<c022c64c>] (driver_register+0x80/0x144)
    [    2.074737] [<c022c5cc>] (driver_register+0x0/0x144) from [<c022d82c>] (platform_driver_register+0x4c/0x60)
    [    2.084899] [<c022d7e0>] (platform_driver_register+0x0/0x60) from [<c05de268>] (twl_rtc_init+0x48/0x60)
    [    2.094726] [<c05de220>] (twl_rtc_init+0x0/0x60) from [<c000876c>] (do_one_initcall+0x128/0x1a8)
    [    2.103881]  r4:c05f57b0 r3:00000000
    [    2.107604] [<c0008644>] (do_one_initcall+0x0/0x1a8) from [<c05bc88c>] (kernel_init+0x84/0x120)
    [    2.116699] [<c05bc808>] (kernel_init+0x0/0x120) from [<c00408d0>] (do_exit+0x0/0x65c)
    [    2.124969]  r5:c05bc808 r4:00000000
    [    2.128692] Code: e3a01000 e2807008 e1a05000 ebf8183e (e5942000)
    [    2.135131] ---[ end trace 2727f69f38b3eae1 ]---
    [    2.139953] Kernel panic - not syncing: Attempted to kill init!
    [    2.146148] Backtrace:
    [    2.148712] [<c0017dbc>] (dump_backtrace+0x0/0x10c) from [<c04293a8>] (dump_stack+0x18/0x1c)
    [    2.157531]  r6:cf01bc00 r5:c0527920 r4:c0661b48 r3:c061870c
    [    2.163452] [<c0429390>] (dump_stack+0x0/0x1c) from [<c04295a4>] (panic+0x64/0x194)
    [    2.171447] [<c0429540>] (panic+0x0/0x194) from [<c0040e80>] (do_exit+0x5b0/0x65c)
    [    2.179351]  r3:cf01bc00 r2:cf01dc30 r1:cf01dc30 r0:c0527920
    [    2.185272]  r7:00000001
    [    2.187927] [<c00408d0>] (do_exit+0x0/0x65c) from [<c0018098>] (die+0x11c/0x2c8)
    [    2.195648]  r7:00000001
    [    2.198303] [<c0017f7c>] (die+0x0/0x2c8) from [<c0429408>] (__do_kernel_fault.part.4+0x5c/0x7c)
    [    2.207397] [<c04293ac>] (__do_kernel_fault.part.4+0x0/0x7c) from [<c001a830>] (do_page_fault+0x1e8/0x1f8)
    [    2.217468]  r7:cf01bc00 r3:cf01dde8
    [    2.221221] [<c001a648>] (do_page_fault+0x0/0x1f8) from [<c001a96c>] (do_translation_fault+0xa0/0xa8)
    [    2.230834] [<c001a8cc>] (do_translation_fault+0x0/0xa8) from [<c00083b0>] (do_DataAbort+0x3c/0xa4)
    [    2.240295]  r7:00000000 r6:c05fc73c r5:c001a8cc r4:00000005
    [    2.246246] [<c0008374>] (do_DataAbort+0x0/0xa4) from [<c0014318>] (__dabt_svc+0x38/0x60)
    [    2.254760] Exception stack(0xcf01dde8 to 0xcf01de30)
    [    2.260040] dde0:                   fffffffa 00000000 00000000 c04272cc 00000000 cf0d3800
    [    2.268585] de00: c0658ed8 cf0d3808 00000000 00000000 c05de220 cf01de64 cf01de30 cf01de30
    [    2.277130] de20: c04272f0 c04272f0 60000013 ffffffff
    [    2.282409]  r8:00000000 r7:cf01de1c r6:ffffffff r5:60000013 r4:c04272f0
    [    2.289428] [<c04272cc>] (twl_rtc_probe+0x0/0x214) from [<c022d47c>] (platform_drv_probe+0x1c/0x20)
    [    2.298858]  r8:00000000 r7:c064546c r6:c0658ed8 r5:c0682e1c r4:cf0d3808
    [    2.305908] [<c022d460>] (platform_drv_probe+0x0/0x20) from [<c022be90>] (driver_probe_device+0xb4/0x2c0)
    [    2.315887] [<c022bddc>] (driver_probe_device+0x0/0x2c0) from [<c022c130>] (__driver_attach+0x94/0x98)
    [    2.325622]  r8:00000000 r7:cf292b40 r6:cf0d383c r5:c064546c r4:cf0d3808
    [    2.332641] [<c022c09c>] (__driver_attach+0x0/0x98) from [<c022abec>] (bus_for_each_dev+0x4c/0x94)
    [    2.341979]  r6:c022c09c r5:c064546c r4:00000000 r3:c022c09c
    [    2.347930] [<c022aba0>] (bus_for_each_dev+0x0/0x94) from [<c022bab8>] (driver_attach+0x24/0x28)
    [    2.357116]  r6:c0638e40 r5:c064546c r4:c064546c
    [    2.361938] [<c022ba94>] (driver_attach+0x0/0x28) from [<c022b70c>] (bus_add_driver+0x188/0x270)
    [    2.371124] [<c022b584>] (bus_add_driver+0x0/0x270) from [<c022c64c>] (driver_register+0x80/0x144)
    [    2.380493] [<c022c5cc>] (driver_register+0x0/0x144) from [<c022d82c>] (platform_driver_register+0x4c/0x60)
    [    2.390655] [<c022d7e0>] (platform_driver_register+0x0/0x60) from [<c05de268>] (twl_rtc_init+0x48/0x60)
    [    2.400482] [<c05de220>] (twl_rtc_init+0x0/0x60) from [<c000876c>] (do_one_initcall+0x128/0x1a8)
    [    2.409637]  r4:c05f57b0 r3:00000000
    [    2.413391] [<c0008644>] (do_one_initcall+0x0/0x1a8) from [<c05bc88c>] (kernel_init+0x84/0x120)
    [    2.422485] [<c05bc808>] (kernel_init+0x0/0x120) from [<c00408d0>] (do_exit+0x0/0x65c)
    [    2.430755]  r5:c05bc808 r4:00000000

  • 这个应该是对应的\drivers\rtc\rtc-twl.c,你有确定编译进内核么?

  • Hi TI

    obj-$(CONFIG_RTC_DRV_TWL4030)    += rtc-twl.o

    cat .config | grep "CONFIG_RTC_DRV_TWL4030"
    CONFIG_RTC_DRV_TWL4030=y

    \drivers\rtc\ 看也有把 .o build 出來

    謝謝。

  • 看了下你发的patch,貌似rtc-twl.c这个文件改动比较大的,你有没在probe()函数里trace下?

  • OK 他好像死在這一行

    static int __devinit twl_rtc_probe(struct platform_device *pdev)
    {
        struct rtc_device *rtc;
        struct pmic_data *pmic = dev_get_platdata(&pdev->dev);
        int ret = -EINVAL;
        int irq = platform_get_irq(pdev, 0);
        u8 rd_reg;

        dev_err(&pdev->dev, "%d\n", pmic->id);  <---------

  • 这就是一句打印啊,把它删掉试试呢。

    我怀疑你是不是有些数据结构没有赋值

  • 刪掉之後可以很穩的開進 filesystem

    我改的這些patch 並沒有對 RTC 有任何變化...,還有我另一個疑問是在 u-boot 或 kernel 下我無法寫入SECONDS_REG HOURS_REG 這些registers,但可以改其他 register例如: 0x3f (70->50) ,我不知道這是不是正常現象,會不會RTC module根本沒作用,這樣在 rtc-twl.c 的 register 填寫也會無法作用?

  • static int __devinit twl_rtc_probe(struct platform_device *pdev)
    {
        struct rtc_device *rtc;
        struct pmic_data *pmic = dev_get_platdata(&pdev->dev);
        int ret = -EINVAL;
        int irq = platform_get_irq(pdev, 0);
        u8 rd_reg;
        printk("%x iiiiiiissss\n",pmic);  ---> 印出為0

        printk("%d iiiiiiissss\n",pmic->id) --> 剛剛的 crash

  • AM335x的内部RTC初始化已经是注掉了吧?如果注掉RTC0就应该对应的TPS65910的RTC,在kernel下操作这个/dev/rtc0正常么?

  • AM335x的内部RTC初始化已经是注掉了吧 --> 請問在哪注釋?

    在 kernel 下 /dev/rtc0 有出來,但你說操作,可以舉例如何操作嗎? 謝謝。

    我在board-am335xevm.c   comment 掉

    static struct evm_dev_cfg evm_sk_dev_cfg[] = {
        //{am335x_rtc_init, DEV_ON_BASEBOARD, PROFILE_ALL},  
        {mmc1_wl12xx_init,    DEV_ON_BASEBOARD, PROFILE_ALL},
        {mmc0_init,    DEV_ON_BASEBOARD, PROFILE_ALL},
        {rgmii1_init,    DEV_ON_BASEBOARD, PROFILE_ALL},

    也把 driver 拿掉

    # on-CPU RTC drivers
    #
    # CONFIG_RTC_DRV_OMAP is not set


    最後開機訊息是

    1.808044] ThumbEE CPU extension supported.
    [    1.812591] mux: Failed to setup hwmod io irq -22
    [    1.818298] Power Management for AM33XX family
    [    1.823211] Trying to load am335x-pm-firmware.bin (60 secs timeout)
    [    1.829956] Copied the M3 firmware to UMEM
    [    1.834381] Cortex M3 Firmware Version = 0x181
    [    1.845428] clock: disabling unused clocks to save power
    [    1.853179] Detected MACID=d0:5f:b8:90:17:5c
    [    1.859161] cpsw: Detected MACID = d0:5f:b8:90:17:5e
    [    1.865661] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
    [    1.872894] Waiting for root device /dev/mmcblk0p2...
    [    1.914337] usb 1-1.3: new high-speed USB device number 3 using musb-hdrc
    [    1.921569] mmc0: host does not support reading read-only switch. assuming wr

  • Hello TI

    我盡可能找一些我懷疑的點,我還無法拼湊出為什麼我RTC無法運作的原因,希望能多給我點意見,謝謝。

    drivers/rtc/rtc-twl.c

    static int __devinit twl_rtc_probe(struct platform_device *pdev)
    {

        struct pmic_data *pmic = dev_get_platdata(&pdev->dev);    
        int irq = platform_get_irq(pdev, 0);
        u8 rd_reg;

        //dev_err(&pdev->dev, "%d\n", pmic->id);

        if (irq <= 0)
            goto out1;
    }

    1 沒有 IRQ,這是需要的嗎? 且 struct pmic_data *pmic = dev_get_platdata(&pdev->dev);  pmic->id  會造成 crash,感覺 struct platform_device *pdev 這邊裡面的 filed 應該沒有設對,這應該在哪設定?

    /driver/mfd/twl-core.c

    static int __devinit twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
    {
     2  沒有進入 probe,也就不能進入 add_children(pdata, id->driver_data); 函數,裡面有一個   if (twl_has_rtc()) 的判斷式。
    }


    請問還有甚麼要注意的地方,3Q

  • 明显这个probe()没有能够成功的执行到底,需要在tps65910的mfd驱动中加入更多信息。

  • probe() 要能夠被執行,它在 tps65910.c 滿足的條件是甚麼? 所以整體來說 tps65910.c  內的tps65910_i2c_probe() 要能夠正常---> 才可以執行 twl-core.c 的 probe ?

    我在參考的patch 中,tps65910_i2c_probe() 內的

    pmic_data->id = id->driver_data 印出來看是 "0"

    請這正確嗎....? 謝謝。


  • 有發現一個問題

    /* Check that the device is actually there */
        ret = tps65910_i2c_read(tps65910, 0x0, 1, &buff);  --> 0x0 改為 0x80  

    不過 rtc 還不能用..

  • 我參照這個 patch: https://lkml.org/lkml/2011/5/8/112,大致上 drivers/mfd/tps65910.c 與 board-am335xevb.c 裡面的 I2C_BOARD_INFO("tps65910", TPS65910_I2C_ID1) 匹配有關,tps65910.c 內的 tps65910_i2c_probe() 用來設定 tps65910 structure 裡的 members function

    tps65910.c 內的 static struct mfd_cell tps65910s[] ={

                      +             .name = "twl_rtc"          

     }

    因為和 drivers/rtc/rtc-twl.c 匹配,所以程式有執行到 twl_rtc_probe(struct platform_device *pdev),這個patch 似乎是想要在 twl_rtc_probe  內獲得在 tps65910.c 內的 probe 裡面的設定。

    static int tps65910_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)

    {

    +   pmic_data->pmic    = tps65910;

    }

    drivers/rtc/rtc-twl.c

    static int __devinit twl_rtc_probe(struct platform_device *pdev)

    {

    struct pmic_data *pmic = dev_get_platdata(&pdev->dev);

    + ret = rtc_read_u8(pmic, &rd_reg, REG_RTC_STATUS_REG);

    }

    接著透過 rtc_read_u8 去 call tps65910.c 內的 driver methods去對 rtc register 做存取..

    只是在twl_rtc_probe(platform_device *pdev) 內我把 pdev->name 印出來它是 twl_rtc,struct pmic_data *pmic = dev_get_platdata(&pdev->dev);  並非 tps65910.c 內的 probe內 預期的 pmic_data->pmic=tps65910 ,所以導致後面執行

    dev_err(&pdev->dev, "%d\n", pmic->id);  ---> 錯誤

    int irq = platform_get_irq(pdev, 0); --> 錯誤

    只是接下來我實在是不知道怎修改下去,我無法確定這個 patch 是否能對我 tps65910 沒有啟動 rtc issue 有幫助,求提示,謝謝。

  • Hi TI

    我已將網路上的 rtc-tps65910.c  移植到 SDK6 裡,可是我有註解 ㄧ些 tps65910_rtc_probe() 裡面的 irq 設定,除了要加上rtc-tps65910.c 所做的patch  還有參考 https://lkml.org/lkml/2012/2/8/75 提供的 patch。

    regmap.c 裡面的 regmap_raw_write() ,我把 //WARN_ON(map->cache_type != REGCACHE_NONE); comment  開機 log 才不會有 crash,有 crash 它還是能開到filesystem。以下附上我的移植 rtc-tps65910.c 的 patch 和 tps65910.c。

    input: ti-tsc as /devices/platform/omap/ti_tscadc/tsc/input/input0
    [    1.683898] tps65910-rtc tps65910-rtc: rtc core: registered tps65910-rtc as rtc0
    [    1.691833] i2c /dev entries driver
    [    1.695861] Linux video capture interface: v2.00
    [    1.701049] usbcore: registered new interface driver uvcvideo
    [    1.707061] USB Video Class driver (1.1.1)
    [    1.713409] OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
    [    1.724639] cpuidle: using governor ladder
    [    1.729522] cpuidle: using governor menu
    [    1.737579] Registered led device: am335x:EVM_SK:usr0
    [    1.737854] Registered led device: am335x:EVM_SK:usr1
    [    1.738128] Registered led device: am335x:EVM_SK:mmc0
    [    1.738372] Registered led device: am335x:EVM_SK:heartbeat
    [    1.741210] usbcore: registered new interface driver usbhid
    [    1.747070] usbhid: USB HID core driver
    [    1.752105] tiadc tiadc: attached adc driver
    [    1.757476] usbcore: registered new interface driver snd-usb-audio
    [    1.766479] ALSA device list:
    [    1.769653]   No soundcards found.
    [    1.773254] oprofile: hardware counters not available
    [    1.778564] oprofile: using timer interrupt.
    [    1.783081] nf_conntrack version 0.5.0 (3955 buckets, 15820 max)
    [    1.789978] ip_tables: (C) 2000-2006 Netfilter Core Team
    [    1.795715] TCP cubic registered
    [    1.799133] NET: Registered protocol family 17
    [    1.803833] can: controller area network core (rev 20090105 abi 8)
    [    1.810485] NET: Registered protocol family 29
    [    1.815155] can: raw protocol (rev 20090105)
    [    1.819671] can: broadcast manager protocol (rev 20090105 t)
    [    1.825683] Registering the dns_resolver key type
    [    1.830718] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
    [    1.838806] ThumbEE CPU extension supported.
    [    1.843383] mux: Failed to setup hwmod io irq -22
    [    1.849090] Power Management for AM33XX family
    [    1.854003] Trying to load am335x-pm-firmware.bin (60 secs timeout)
    [    1.860778] Copied the M3 firmware to UMEM
    [    1.865173] Cortex M3 Firmware Version = 0x181
    [    1.875885] clock: disabling unused clocks to save power
    [    1.883666] Detected MACID=54:4a:16:b1:b8:af
    [    1.889434] cpsw: Detected MACID = 54:4a:16:b1:b8:b1
    [    1.901397] tps65910-rtc tps65910-rtc: setting system clock to 2000-01-11 18:48:15 UTC (947616495)

    然後我下 hwclock -w 指令出現

    hwclock -w
    [ 2286.127655] tps65910-rtc tps65910-rtc: rtc_set_alarm error -22
    hwclock: Timed out waiting for time change.
    [ 2287.904113] tps65910-rtc tps65910-rtc: rtc_set_time error -22
    hwclock: ioctl(RTC_SET_TIME) to /dev/rtc0 to set the time failed.: Invalid argument

    trace code 之後,發現他死在 regmap.c 裡面的 regmap_bulk_write() 的 if (map->bus && !map->format.parse_inplace),這個 regmap_bulk_write() 是為了移植 rtc-tps65910.c 而加上的,我不清楚這個 function 它到底要幹嘛。

    能給我方向嗎? 萬分感謝。



  • Hi TI

    現在的狀況更新是 rtc-tps65910 註冊為 rtc1,這是進入 filesystem 時所下的命令

    root@ubuntu-armhf:/# hwclock -f /dev/rtc1
    [   32.861480] tps65910-rtc tps65910-rtc: rtc_set_alarm error -22
    Wed Jan 12 11:44:15 2000  -0.108887 seconds

    root@ubuntu-armhf:/# hwclock -w -f /dev/rtc1
    [   76.690521] tps65910-rtc tps65910-rtc: rtc_set_alarm error -22
    [   77.919647] tps65910-rtc tps65910-rtc: rtc_set_time error -22
    hwclock: ioctl(RTC_SET_TIME) to /dev/rtc1 to set the time failed.: Invalid argument

    root@ubuntu-armhf:/# hwclock -f /dev/rtc1
    [  104.109802] tps65910-rtc tps65910-rtc: rtc_set_alarm error -22
    hwclock: Timed out waiting for time change.
    hwclock: The Hardware Clock registers contain values that are either invalid (e.g. 50th day of month) or beyond the range we can handle (e.g. Year 2095).

    請問有甚麼建義嗎? 感覺是快成功了,謝謝。

  • 我觉得应该是/dev/rtc0

  • Hi TI

    關於這個RTC,我總算是解了,CPU上 RTC driver 沒拿掉,讓rtc-tps65910 註冊為 rtc1,rtc-tps65910.c 內的 bulk_write function 我抄3.4 kernel 的,再修改另一個 driver讓它每次開機都去存取 rtc1,就可以了。

    卡了超久,謝謝指導。