I am working with the RTC and the only problem left is why the RTC is not running.
See code further down. I have managed to set the date/time/dayofweek, but when I try to read them, they are the same as when it was set. I'm aware of that the alarm is not set, but shouldn't the RTC be running anyway?
Code: Select all
// Union to access rtcc registers
typedef union tagRTCC {
struct {
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char dayofweek;
unsigned char day;
unsigned char month;
unsigned char year;
} components;
struct {
unsigned int prt00;
unsigned int prt01;
unsigned int prt10;
unsigned int prt11;
} ports;
} RTCC;
/* Enable Write's to RTC Configuration Register
* This cannot be directly done by setting RTCWREN bit in RTCCFG
* The special unlock sequence would set RTCWREN bit for the first time
* Once this unlock sequence has been executed, RTCWREN bit can be set or reset directly
*/
void RTCCUnlock()
{
asm {
disi #5
mov #0x55, w7 // write 0x55 and 0xAA to
mov w7, NVMKEY // NVMKEY to disable
mov #0xAA, w8 // write protection
mov w8, NVMKEY
BSET RCFGCAL, #13 // set the RTCWREN bit
nop
nop
}
}
void OSCCONWriteEnable() {
OSCCON = OSCCON; // Let the linker use the value
asm {
disi #7
mov #@OSCCON, W1
mov #0x02, W0
mov #0x46, W2
mov #0x57, W3
mov.b W2, [W1]
mov.b W3, [W1]
mov.b W0, [W1]
}
}
// Input is binary
// encoding in RTC registers are BCD
void RTC_Set(unsigned char year,
unsigned char month,
unsigned char day,
unsigned char hour,
unsigned char min,
unsigned char sec,
unsigned char dayofweek) {
RTCC time;
time.components.year = Dec2Bcd(year);
time.components.month = Dec2Bcd(month);
time.components.day = Dec2Bcd(day);
time.components.hour = Dec2Bcd(hour);
time.components.min = Dec2Bcd(min);
time.components.sec = Dec2Bcd(sec);
time.components.dayofweek = Dec2Bcd(dayofweek);
OSCCONWriteEnable();
RTCCUnlock(); // includes RTCWREN = 1
// Start setting time and date
RCFGCALbits.RTCEN = 0; // bit15 - disable RTC
RCFGCALbits.RTCPTR0 = 1;
RCFGCALbits.RTCPTR1 = 1;
RTCVAL = time.ports.prt11;
RTCVAL = time.ports.prt10;
RTCVAL = time.ports.prt01;
RTCVAL = time.ports.prt00;
RCFGCALbits.RTCEN = 1; // bit15 enable RTC
RCFGCALbits.RTCWREN = 0; // Lock the RTCC
}
void RTC_Get() {
RTCC time;
RCFGCALbits.RTCPTR0 = 1;
RCFGCALbits.RTCPTR1 = 1;
time.ports.prt11 = RTCVAL;
time.ports.prt10 = RTCVAL;
time.ports.prt01 = RTCVAL;
time.ports.prt00 = RTCVAL; // <-- Never changes WHY????
// Here we should get time one more time to ensure, that there's no roll over
}
void Timer1Int() org 0x1A{// Timer1 address in the interrupt vector table
IFS0 = IFS0 & 0xFFF7; // Interrupt flag reset
RTC_Get();
}
void InitTimer() {
const unsigned long Sec = 19530;
// Init the timerlist and flag
// Init Timer 1
PR1 = Sec; // Interrupt period is 10000 clocks
T1CON = 0x8030; // Timer1 enabled (internal clock divided by 256)
IPC0 = IPC0 | 0x1000; // Priority level is 1
IEC0 = IEC0 | 0x0008; // Timer1 interrupt enabled
}
void main(){
RTC_SET(9,10,13, 11,15,0, 1);
InitTimer();
while(1) asm nop; // Endless loop
}