Пример #1
0
/**
*
* This function sets the alarm value of RTC device.
*
* @param	InstancePtr is a pointer to the XRtcPsu instance
* @param	Alarm is the desired alarm time for RTC.
* @param	Periodic says whether the alarm need to set at periodic
* 			Intervals or a one-time alarm.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XRtcPsu_SetAlarm(XRtcPsu *InstancePtr, u32 Alarm, u32 Periodic)
{
    Xil_AssertVoid(InstancePtr != NULL);
    Xil_AssertVoid(Alarm != 0U);
    Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
    Xil_AssertVoid((Alarm - XRtcPsu_GetCurrentTime(InstancePtr)) > (u32)0);

    XRtcPsu_WriteReg(InstancePtr->RtcConfig.BaseAddr+XRTC_ALRM_OFFSET, Alarm);
    if(Periodic != 0U) {
        InstancePtr->IsPeriodicAlarm = 1U;
        InstancePtr->PeriodicAlarmTime =
            Alarm - XRtcPsu_GetCurrentTime(InstancePtr);
    }
}
/**
*
* This function does a minimal Alarm test on the XRtcPsu device in polled mode.
*
* This function sets one time alarm from the current time to a specified time.
*
* @param	DeviceId is the unique device id from hardware build.
*
* @return	XST_SUCCESS if successful, XST_FAILURE if unsuccessful
*
* @note
* This function polls the RTC, it may hang if the hardware is not
* working correctly.
*
****************************************************************************/
int RtcPsuAlarmPolledExample(u16 DeviceId)
{
	int Status;
	XRtcPsu_Config *Config;
	u32 CurrentTime, AlarmTime;
	XRtcPsu_DT dt0;

	/*
	 * Initialize the RTC driver so that it's ready to use.
	 * Look up the configuration in the config table, then initialize it.
	 */
	Config = XRtcPsu_LookupConfig(DeviceId);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XRtcPsu_CfgInitialize(&Rtc_Psu, Config, Config->BaseAddr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Check hardware build. */
	Status = XRtcPsu_SelfTest(&Rtc_Psu);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	xil_printf("\n\rDay Convention : 0-Fri, 1-Sat, 2-Sun, 3-Mon, 4-Tue, 5-Wed, 6-Thur\n\r");
	xil_printf("Current RTC time is..\n\r");
	CurrentTime = XRtcPsu_GetCurrentTime(&Rtc_Psu);
	XRtcPsu_SecToDateTime(CurrentTime,&dt0);
	xil_printf("YEAR:MM:DD HR:MM:SS \t %04d:%02d:%02d %02d:%02d:%02d\t Day = %d\n\r",
			dt0.Year,dt0.Month,dt0.Day,dt0.Hour,dt0.Min,dt0.Sec,dt0.WeekDay);

	CurrentTime = XRtcPsu_GetCurrentTime(&Rtc_Psu);
	AlarmTime = CurrentTime + ALARM_PERIOD;
	XRtcPsu_SetAlarm(&Rtc_Psu,AlarmTime,0U);

	/*
	 * If Alarm was not generated, then the processor goes into an infinite
	 * loop. This represents a failure case of alarm example.
	 */
	while (!XRtcPsu_IsAlarmEventGenerated(&Rtc_Psu));
	xil_printf("Alarm generated.\n\r");

	return XST_SUCCESS;
}
Пример #3
0
/**
*
* This function calculates the calibration value depending on the actual
* realworld time and also helps in deriving new calibration value if
* the user wishes to change his oscillator frequency.TimeReal is generally the
* internet time with EPOCH time as reference i.e.,1/1/1970 1st second.
* But this RTC driver assumes start time from 1/1/2000 1st second. Hence,if
* the user maps the internet time InternetTimeInSecs, then he has to use
* 	XRtcPsu_SecToDateTime(InternetTimeInSecs,&InternetTime),
* 	TimeReal = XRtcPsu_DateTimeToSec(InternetTime)
* 	consecutively to arrive at TimeReal value.
*
* @param	InstancePtr is a pointer to the XRtcPsu instance.
* @param	TimeReal is the actual realworld time generally an
* 		network time / Internet time in seconds.
*
* @param	CrystalOscFreq is the Oscillator new frequency. Say, If the user
* 		is going with the typical 32768Hz, then he inputs the same
* 		frequency value.
*
* @return	None.
*
* @note		After Calculating the calibration register, user / application has to
* 			call again CfgInitialize API to bring the new calibration into effect.
*
*****************************************************************************/
void XRtcPsu_CalculateCalibration(XRtcPsu *InstancePtr,u32 TimeReal,
                                  u32 CrystalOscFreq)
{
    u32 ReadTime, SetTime;
    u32 Cprev,Fprev,Cnew,Fnew,Xf,Calibration;
    Xil_AssertVoid(TimeReal != 0U);
    Xil_AssertVoid(CrystalOscFreq != 0U);

    ReadTime = XRtcPsu_GetCurrentTime(InstancePtr);
    SetTime = XRtcPsu_GetLastSetTime(InstancePtr);
    Calibration = XRtcPsu_GetCalibration(InstancePtr);
    /*
     * When board gets reseted, Calibration value is zero
     * and Last setTime will be marked as 1st  second. This implies
     * CurrentTime to be in few seconds say something in tens. TimeReal will
     * be huge, say something in thousands. So to prevent such reset case, Cnew
     * and Fnew will not be calculated.
     */
    if((Calibration == 0U) || (CrystalOscFreq != InstancePtr->OscillatorFreq)) {
        Cnew = CrystalOscFreq - (u32)1;
        Fnew = 0U;
    } else {
        Cprev = Calibration & XRTC_CALIB_RD_FRACTN_DATA_MASK;
        Fprev = Calibration & XRTC_CALIB_RD_MAX_TCK_MASK;

        Xf = ((ReadTime - SetTime) * ((Cprev+1U) + ((Fprev+1U)/16U))) / (TimeReal - SetTime);
        Cnew = (u32)(Xf) - (u32)1;
        Fnew = XRtcPsu_RoundOff((Xf - Cnew) * 16U) - (u32)1;
    }

    Calibration = (Fnew << XRTC_CALIB_RD_FRACTN_DATA_SHIFT) + Cnew;
    Calibration |= XRTC_CALIB_RD_FRACTN_EN_MASK;

    InstancePtr->CalibrationValue = Calibration;
    InstancePtr->OscillatorFreq = CrystalOscFreq;
}
Пример #4
0
/**
*
* This function is the interrupt handler for the driver.
* It must be connected to an interrupt system by the application such that it
* can be called when an interrupt occurs.
*
* @param	InstancePtr contains a pointer to the driver instance
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XRtcPsu_InterruptHandler(XRtcPsu *InstancePtr)
{
	u32 IsrStatus;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the interrupt ID register to determine which
	 * interrupt is active.
	 */
	IsrStatus = ~(XRtcPsu_ReadReg(InstancePtr->RtcConfig.BaseAddr +
			XRTC_INT_MSK_OFFSET));

	IsrStatus &= XRtcPsu_ReadReg(InstancePtr->RtcConfig.BaseAddr +
			XRTC_INT_STS_OFFSET);

	/*
	 * Clear the interrupt status to allow future
	 * interrupts before this generated interrupt is serviced.
	 */
	XRtcPsu_WriteReg(InstancePtr->RtcConfig.BaseAddr +
			XRTC_INT_STS_OFFSET, IsrStatus);

	/* Handle the generated interrupts appropriately. */

	/* Alarm interrupt */
	if((IsrStatus & XRTC_INT_STS_ALRM_MASK) != (u32)0) {

		if(InstancePtr->IsPeriodicAlarm != 0U) {
			XRtcPsu_SetAlarm(InstancePtr,
					(XRtcPsu_GetCurrentTime(InstancePtr)+InstancePtr->PeriodicAlarmTime),1U);
		}

		/*
		 * Call the application handler to indicate that there is an
		 * alarm interrupt. If the application cares about this alarm,
		 * it will act accordingly through its own handler.
		 */
		InstancePtr->Handler(InstancePtr->CallBackRef,
					XRTCPSU_EVENT_ALARM_GEN);
	}

	/* Seconds interrupt */
	if((IsrStatus & XRTC_INT_STS_SECS_MASK) != (u32)0) {
		/* Set the CurrTimeUpdated flag to 1 */
		InstancePtr->CurrTimeUpdated = 1;

		if(InstancePtr->TimeUpdated == (u32)1) {
			/* Clear the TimeUpdated */
			InstancePtr->TimeUpdated = (u32)0;
		}

		/*
		 * Call the application handler to indicate that there is an
		 * seconds interrupt. If the application cares about this seconds
		 * interrupt, it will act accordingly through its own handler.
		 */
		InstancePtr->Handler(InstancePtr->CallBackRef,
					XRTCPSU_EVENT_SECS_GEN);
	}

}
/**
*
* This function does a minimal test on the Rtc device and driver as a
* design example. The purpose of this function is to illustrate
* how to use alarm feature in the XRtcPsu driver.
*
* This function sets alarm for a specified time from the current time.
*
* @param	IntcInstPtr is a pointer to the instance of the ScuGic driver.
* @param	RtcInstPtr is a pointer to the instance of the RTC driver
*		which is going to be connected to the interrupt controller.
* @param	DeviceId is the device Id of the RTC device and is typically
*		XPAR_<RTCPSU_instance>_DEVICE_ID value from xparameters.h.
* @param	RtcIntrId is the interrupt Id and is typically
*		XPAR_<RTCPSU_instance>_INTR value from xparameters.h.
*
* @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note
*
* This function contains an infinite loop such that if interrupts are not
* working it may never return.
*
**************************************************************************/
int RtcPsuAlarmIntrExample(XScuGic *IntcInstPtr, XRtcPsu *RtcInstPtr,
			u16 DeviceId, u16 RtcIntrId)
{
	int Status;
	XRtcPsu_Config *Config;
	u32 CurrentTime, Alarm;
	XRtcPsu_DT dt0;

	/*
	 * Initialize the RTC driver so that it's ready to use
	 * Look up the configuration in the config table, then initialize it.
	 */
	Config = XRtcPsu_LookupConfig(DeviceId);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XRtcPsu_CfgInitialize(RtcInstPtr, Config, Config->BaseAddr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Check hardware build */
	Status = XRtcPsu_SelfTest(RtcInstPtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	xil_printf("\n\rDay Convention : 0-Fri, 1-Sat, 2-Sun, 3-Mon, 4-Tue, 5-Wed, 6-Thur\n\r");
	xil_printf("Current RTC time is..\n\r");
	CurrentTime = XRtcPsu_GetCurrentTime(RtcInstPtr);
	XRtcPsu_SecToDateTime(CurrentTime,&dt0);
	xil_printf("YEAR:MM:DD HR:MM:SS \t %04d:%02d:%02d %02d:%02d:%02d\t Day = %d\n\r",
			dt0.Year,dt0.Month,dt0.Day,dt0.Hour,dt0.Min,dt0.Sec,dt0.WeekDay);

	/*
	 * Connect the RTC to the interrupt subsystem such that interrupts
	 * can occur. This function is application specific.
	 */
	Status = SetupInterruptSystem(IntcInstPtr, RtcInstPtr, RtcIntrId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Setup the handlers for the RTC that will be called from the
	 * interrupt context when alarm and seconds interrupts are raised,
	 * specify a pointer to the RTC driver instance as the callback reference
	 * so the handlers are able to access the instance data
	 */
	XRtcPsu_SetHandler(RtcInstPtr, (XRtcPsu_Handler)Handler, RtcInstPtr);

	/*
	 * Enable the interrupt of the RTC device so interrupts will occur.
	 */
	XRtcPsu_SetInterruptMask(RtcInstPtr, XRTC_INT_EN_ALRM_MASK );

	CurrentTime = XRtcPsu_GetCurrentTime(RtcInstPtr);
	Alarm = CurrentTime + ALARM_PERIOD;
	XRtcPsu_SetAlarm(RtcInstPtr,Alarm,0);

	while( IsAlarmGen != 1);

	/*
	 * Disable the interrupt of the RTC device so interrupts will not occur.
	 */
	XRtcPsu_ClearInterruptMask(RtcInstPtr,XRTC_INT_DIS_ALRM_MASK);

	return XST_SUCCESS;
}