/********************************************************************* Function: void RtccInitClock(void) PreCondition: None Input: None Output: None Side Effects: Enables the secondary oscillator from Timer1 Overview: The function initializes the RTCC device. It starts the RTCC clock, sets the RTCC Off and disables RTCC write. Disables the OE. Note: None ********************************************************************/ void RtccInitClock(void) { // enable the Secondary Oscillator #if defined (RTCC_SFR_V1) T1CONbits.SOSCEN = 1; #else T1CONbits.T1OSCEN = 1; #endif #if defined (RTCC_V1) RTCCFG = 0x0; #else RTCCON1=0x0; #endif RTCCAL = 0x00; if(mRtccIsOn()) { if(!mRtccIsWrEn()) { RtccWrOn(); } mRtccOff(); } mRtccWrOff(); }
/********************************************************************************************** Function: void RtccSetCalibration(int drift) PreCondition: drift has to fit into signed 8 bits representation Input: drift - value to be added/subtracted to perform calibration Output: None Side Effects: None Overview: The function updates the value that the RTCC uses in the auto-adjust feature, once every minute. The drift value acts as a signed value, [-128*4, +127*4], 0 not having any effect. Note: Writes to the RTCCAL[7:0] register should only occur when the timer is turned off or immediately or after the edge of the seconds pulse (except when SECONDS=00 - due to the possibility of the auto-adjust event). In order to speed-up the process, the API function performs the reading of the HALFSEC field. The function may block for half a second, worst case, when called at the start of the minute. Interrupts can not be disabled for such a long period. However, long interrupt routines can interfere with the proper functioning of the device.Care must be taken. ***********************************************************************************************/ void RtccSetCalibration(int drift) { if(mRtccIsOn()) { unsigned int currSec; mRtccClearRtcPtr(); // make sure you read seconds if((currSec=RTCVALL)&0xff==00) { // we're at second 00, wait auto-adjust to be performed while(!mRtccIs2ndHalfSecond()); // wait until second half... } } // update the CAL value RTCCAL=drift; }
/********************************************************************* * Function: BOOL RtccWriteTime(const rtccTime* pTm, BOOL di) * * PreCondition: pTm pointing to a valid rtccTime structure having proper values: * - sec: BCD codification, 00-59 * - min: BCD codification, 00-59 * - hour: BCD codification, 00-24 * Input: pTm - pointer to a constant rtccTime union * di - if interrupts need to be disabled * Output: TRUE '1' : If all the values are within range * FALSE '0' : If any value is out of above mentioned range. * Side Effects: None * Overview: The function sets the current time of the RTCC device. * Note: - The write is successful only if Wr Enable is set. * The function will enable the write itself, if needed. * Also, the Alarm will be temporarily disabled and the * device will be stopped (On set to 0) in order * to safely perform the update of the RTC time register. * However, the device status will be restored. * - Usually the disabling of the interrupts is desired, if the user has to have more * precise control over the actual moment of the time setting. ********************************************************************/ BOOL RtccWriteTime(const rtccTime* pTm , BOOL di) { WORD_VAL tempHourWDay ; WORD_VAL tempMinSec ; UINT8 CPU_IPL; BOOL wasWrEn; BOOL wasOn; BOOL wasAlrm=FALSE; if((MAX_MIN < pTm->f.min )|| (MAX_SEC < pTm->f.sec) || (MAX_HOUR < pTm->f.hour)) { return(FALSE); } tempMinSec.byte.HB = pTm->f.min; tempMinSec.byte.LB =pTm->f.sec; // update the desired fields if(di) { /* Disable Global Interrupt */ mSET_AND_SAVE_CPU_IP(CPU_IPL,7); } if(!(wasWrEn= mRtccIsWrEn())) { RtccWrOn(); // have to allow the WRTEN in order to write the new value } if((wasOn=mRtccIsOn())) { wasAlrm= mRtccIsAlrmEnabled(); mRtccOff(); // turn module off before updating the time } mRtccClearRtcPtr(); mRtccSetRtcPtr(RTCCPTR_MASK_HRSWEEK); tempHourWDay.Val = RTCVAL; tempHourWDay.byte.LB = pTm->f.hour; mRtccClearRtcPtr(); mRtccSetRtcPtr(RTCCPTR_MASK_HRSWEEK); RTCVAL = tempHourWDay.Val; // update device value RTCVAL = tempMinSec.Val; if(wasOn) { mRtccOn(); if(wasAlrm) { mRtccAlrmEnable(); } if(wasWrEn) { RtccWrOn(); } } else { if(!wasWrEn) { mRtccWrOff(); } } if(di) { /* Enable Global Interrupt */ mRESTORE_CPU_IP(CPU_IPL); } return(TRUE); }