1 #include "pxa260/pxa260.h"
2 #include "pxa260/pxa260_RTC.h"
3
4 #include <sys/time.h>
5
6
7
rtcCurTime(void)8 static UInt32 rtcCurTime(void){
9
10 struct timeval tv;
11
12 gettimeofday(&tv, NULL);
13
14 return tv.tv_sec;
15 }
16
pxa260rtcPrvUpdate(Pxa260rtc * rtc)17 void pxa260rtcPrvUpdate(Pxa260rtc* rtc){
18
19 UInt32 time = rtcCurTime();
20
21 if(rtc->lastSeenTime != time){ //do not triger alarm more than once per second please
22
23 if((rtc->RTSR & 0x4) && (time + rtc->RCNR_offset == rtc->RTAR)){ //check alarm
24 rtc->RTSR |= 1;
25 }
26 if(rtc->RTSR & 0x8){ //send HZ interrupt
27 rtc->RTSR |= 2;
28 }
29 }
30 pxa260icInt(rtc->ic, PXA260_I_RTC_ALM, (rtc->RTSR & 1) != 0);
31 pxa260icInt(rtc->ic, PXA260_I_RTC_HZ, (rtc->RTSR & 2) != 0);
32 }
33
pxa260rtcPrvMemAccessF(void * userData,UInt32 pa,UInt8 size,Boolean write,void * buf)34 static Boolean pxa260rtcPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){
35
36 Pxa260rtc* rtc = userData;
37 UInt32 val = 0;
38
39 if(size != 4) {
40 err_str(__FILE__ ": Unexpected ");
41 // err_str(write ? "write" : "read");
42 // err_str(" of ");
43 // err_dec(size);
44 // err_str(" bytes to 0x");
45 // err_hex(pa);
46 // err_str("\r\n");
47 return true; //we do not support non-word accesses
48 }
49
50 pa = (pa - PXA260_RTC_BASE) >> 2;
51
52 debugLog("PXA260 RTC access:0x%04X, write:%d, PC:0x%08X\n", pa, write, pxa260GetPc());
53
54 if(write){
55 val = *(UInt32*)buf;
56
57 switch(pa){
58 case 0:
59 rtc->RCNR_offset = rtcCurTime() - val;
60 break;
61
62 case 1:
63 rtc->RTAR = val;
64 pxa260rtcPrvUpdate(rtc);
65 break;
66
67 case 2:
68 rtc->RTSR = (val &~ 3UL) | ((rtc->RTSR &~ val) & 3UL);
69 pxa260rtcPrvUpdate(rtc);
70 break;
71
72 case 3:
73 if(!(rtc->RTTR & 0x80000000UL)) rtc->RTTR = val;
74 break;
75 }
76 }
77 else{
78 switch(pa){
79 case 0:
80 val = rtcCurTime() - rtc->RCNR_offset;
81 break;
82
83 case 1:
84 val = rtc->RTAR;
85 break;
86
87 case 2:
88 val = rtc->RTSR;
89 break;
90
91 case 3:
92 val = rtc->RTTR;
93 break;
94 }
95 *(UInt32*)buf = val;
96 }
97
98 return true;
99 }
100
101
pxa260rtcInit(Pxa260rtc * rtc,Pxa260ic * ic)102 void pxa260rtcInit(Pxa260rtc* rtc, Pxa260ic* ic){
103
104 __mem_zero(rtc, sizeof(Pxa260rtc));
105 rtc->ic = ic;
106 rtc->RCNR_offset = 0;
107 rtc->RTTR = 0x7FFF; //nice default value
108 rtc->lastSeenTime = rtcCurTime();
109 //return memRegionAdd(physMem, PXA260_RTC_BASE, PXA260_RTC_SIZE, pxa260rtcPrvMemAccessF, rtc);
110 }
111
pxa260rtcUpdate(Pxa260rtc * rtc)112 void pxa260rtcUpdate(Pxa260rtc* rtc){
113 pxa260rtcPrvUpdate(rtc);
114 }
115