void vInitialiseTimerForIntQueueTest( void ) { BaseType_t xStatus; TmrCntrSetup *pxTimerSettings; extern XScuGic xInterruptController; BaseType_t xTimer; XTtcPs *pxTimerInstance; XTtcPs_Config *pxTimerConfiguration; const uint8_t ucRisingEdge = 3; for( xTimer = 0; xTimer < tmrTIMERS_USED; xTimer++ ) { /* Look up the timer's configuration. */ pxTimerInstance = &( xTimerInstances[ xTimer ] ); pxTimerConfiguration = XTtcPs_LookupConfig( xDeviceIDs[ xTimer ] ); configASSERT( pxTimerConfiguration ); pxTimerSettings = &( xTimerSettings[ xTimer ] ); /* Initialise the device. */ xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); if( xStatus != XST_SUCCESS ) { /* Not sure how to do this before XTtcPs_CfgInitialize is called as pxTimerInstance is set within XTtcPs_CfgInitialize(). */ XTtcPs_Stop( pxTimerInstance ); xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); configASSERT( xStatus == XST_SUCCESS ); } /* Set the options. */ XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options ); /* The timer frequency is preset in the pxTimerSettings structure. Derive the values for the other structure members. */ XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) ); /* Set the interval and prescale. */ XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval ); XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler ); /* The priority must be the lowest possible. */ XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge ); /* Connect to the interrupt controller. */ xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance ); configASSERT( xStatus == XST_SUCCESS); /* Enable the interrupt in the GIC. */ XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] ); /* Enable the interrupts in the timer. */ XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); /* Start the timer. */ XTtcPs_Start( pxTimerInstance ); } }
/** * * This function uses the interrupt inter-locking between the ticker timer * counter and the waveform output timer counter. When certain amount of * interrupts have happened to the ticker timer counter, a flag, PWM_UpdateFlag, * is set to true. * * When PWM_UpdateFlag for the waveform timer counter is true, the duty * cycle for PWM timer counter is increased by PWM_DELTA_DUTY. * The function exits successfully when the duty cycle for PWM timer * counter reaches beyond 100. * * @param None * * @return XST_SUCCESS if duty cycle successfully reaches beyond 100, * otherwise, XST_FAILURE. * * @note None. * *****************************************************************************/ int WaitForDutyCycleFull(void) { TmrCntrSetup *TimerSetup; u8 DutyCycle; /* The current output duty cycle */ XTtcPs *TtcPs_PWM; /* Pointer to the instance structure */ TimerSetup = &(SettingsTable[TTC_PWM_DEVICE_ID]); TtcPs_PWM = &(TtcPsInst[TTC_PWM_DEVICE_ID]); /* * Initialize some variables used by the interrupts and in loops. */ DutyCycle = PWM_DELTA_DUTY; PWM_UpdateFlag = TRUE; ErrorCount = 0; /* * Loop until 100% duty cycle in the PWM output. */ while (DutyCycle <= 100) { /* * If error occurs, disable interrupts, and exit. */ if (0 != ErrorCount) { return XST_FAILURE; } /* * The Ticker interrupt sets a flag for PWM to update its duty * cycle. */ if (PWM_UpdateFlag) { /* Calculate the new register setting here, not at the * time critical interrupt level. */ MatchValue = (TimerSetup->Interval * DutyCycle) / 100; /* * Change the PWM duty cycle */ DutyCycle += PWM_DELTA_DUTY; /* * Enable the PWM Interval interrupt */ XTtcPs_EnableInterrupts(TtcPs_PWM, XTTCPS_IXR_INTERVAL_MASK); PWM_UpdateFlag = FALSE; } } return XST_SUCCESS; }
int HAL_TIMER_TTC_TimerSetup(unsigned int nHz) { int Status; TmrCntrSetup *TimerSetup; XTtcPs *TtcPsTick; SettingsTable.OutputHz = nHz; TimerSetup = &SettingsTable; /* * Set up appropriate options for Ticker: interval mode without * waveform output. */ TimerSetup->Options |= (XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE); /* * Calling the timer setup routine * . initialize device * . set options */ Status = SetupTimer(TTC_TICK_DEVICE_ID); if(Status != XST_SUCCESS) { return Status; } TtcPsTick = &TtcPsInst; /* * Connect to the interrupt controller */ Status = HAL_GIC_ConnectIntRoutine(TTC_TICK_INTR_ID, (Xil_ExceptionHandler)TickHandler, (void *)TtcPsTick); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the Timer counter */ HAL_GIC_EnableIntForDevice(TTC_TICK_INTR_ID); /* * Enable the interrupts for the tick timer/counter * We only care about the interval timeout. */ XTtcPs_EnableInterrupts(TtcPsTick, XTTCPS_IXR_INTERVAL_MASK); /* * Start the tick timer/counter */ XTtcPs_Start(TtcPsTick); return Status; }
/** * * This function sets up the waveform output timer counter (PWM). * * @param None * * @return XST_SUCCESS if everything sets up well, XST_FAILURE otherwise. * * @note None * *****************************************************************************/ int SetupPWM(void) { int Status; TmrCntrSetup *TimerSetup; XTtcPs *TtcPsPWM; TimerSetup = &(SettingsTable[TTC_PWM_DEVICE_ID]); /* * Set up appropriate options for PWM: interval mode and * match mode for waveform output. */ TimerSetup->Options |= (XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_MATCH_MODE); /* * Calling the timer setup routine * initialize device * set options */ Status = SetupTimer(TTC_PWM_DEVICE_ID); if(Status != XST_SUCCESS) { return Status; } TtcPsPWM = &(TtcPsInst[TTC_PWM_DEVICE_ID]); /* * Connect to the interrupt controller */ Status = XScuGic_Connect(&InterruptController, TTC_PWM_INTR_ID, (Xil_ExceptionHandler)PWMHandler, (void *)&MatchValue); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the Timer counter */ XScuGic_Enable(&InterruptController, TTC_PWM_INTR_ID); /* * Enable the interrupts for the tick timer/counter * We only care about the interval timeout. */ XTtcPs_EnableInterrupts(TtcPsPWM, XTTCPS_IXR_INTERVAL_MASK); /* * Start the tick timer/counter */ XTtcPs_Start(TtcPsPWM); return Status; }
void platform_enable_interrupts() { /* * Enable non-critical exceptions. */ Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ); XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR); XTtcPs_EnableInterrupts(&TimerInstance, XTTCPS_IXR_INTERVAL_MASK); XTtcPs_Start(&TimerInstance); return; }
/* * The application must provide a function that configures a peripheral to * create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT() * in FreeRTOSConfig.h to call the function. This file contains a function * that is suitable for use on the Zynq SoC. */ void vConfigureTickInterrupt( void ) { XTtcPs_Config *pxTimerConfig; BaseType_t xStatus; XScuGic_Config *pxGICConfig; static XScuGic xInterruptController; /* Interrupt controller instance */ uint16_t usInterval; uint8_t ucPrescale = 0; const uint8_t ucRisingEdge = 3; /* This function is called with the IRQ interrupt disabled, and the IRQ interrupt should be left disabled. It is enabled automatically when the scheduler is started. */ /* Ensure XScuGic_CfgInitialize() has been called. In this demo it has already been called from prvSetupHardware() in main(). */ pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID ); xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress ); configASSERT( xStatus == XST_SUCCESS ); ( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */ /* The interrupt priority must be the lowest possible. */ XScuGic_SetPriorityTriggerType( &xInterruptController, tickINTERRUPT_ID, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, ucRisingEdge ); /* Install the FreeRTOS tick handler. */ xStatus = XScuGic_Connect( &xInterruptController, tickINTERRUPT_ID, (Xil_ExceptionHandler) FreeRTOS_Tick_Handler, NULL ); configASSERT( xStatus == XST_SUCCESS ); ( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */ /* Initialise the Triple Timer Counter (TTC) that is going to be used to generate the tick interrupt. */ pxTimerConfig = XTtcPs_LookupConfig( tickTTC_ID ); xStatus = XTtcPs_CfgInitialize( &xTimerInstance, pxTimerConfig, pxTimerConfig->BaseAddress ); configASSERT( xStatus == XST_SUCCESS ); ( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */ /* Configure the interval to be the require tick rate. */ XTtcPs_CalcIntervalFromFreq( &xTimerInstance, configTICK_RATE_HZ, &usInterval, &ucPrescale ); XTtcPs_SetInterval( &xTimerInstance, usInterval ); XTtcPs_SetPrescaler( &xTimerInstance, ucPrescale ); /* Interval mode used. */ XTtcPs_SetOptions( &xTimerInstance, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE ); /* Start the timer. */ XTtcPs_Start( &xTimerInstance ); /* Enable the interrupt in the interrupt controller. */ XScuGic_Enable( &xInterruptController, tickINTERRUPT_ID ); /* Enable the interrupt in the timer itself. */ XTtcPs_EnableInterrupts( &xTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); }
void vConfigureTickInterrupt( void ) { BaseType_t xStatus; XTtcPs_Config *pxTimerConfiguration; uint16_t usInterval; uint8_t ucPrescale; const uint8_t ucLevelSensitive = 1; extern XScuGic xInterruptController; pxTimerConfiguration = XTtcPs_LookupConfig( XPAR_XTTCPS_3_DEVICE_ID ); /* Initialise the device. */ xStatus = XTtcPs_CfgInitialize( &xRTOSTickTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); if( xStatus != XST_SUCCESS ) { /* Not sure how to do this before XTtcPs_CfgInitialize is called as *xRTOSTickTimerInstance is set within XTtcPs_CfgInitialize(). */ XTtcPs_Stop( &xRTOSTickTimerInstance ); xStatus = XTtcPs_CfgInitialize( &xRTOSTickTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); configASSERT( xStatus == XST_SUCCESS ); } /* Set the options. */ XTtcPs_SetOptions( &xRTOSTickTimerInstance, ( XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE ) ); /* Derive values from the tick rate. */ XTtcPs_CalcIntervalFromFreq( &xRTOSTickTimerInstance, configTICK_RATE_HZ, &( usInterval ), &( ucPrescale ) ); /* Set the interval and prescale. */ XTtcPs_SetInterval( &xRTOSTickTimerInstance, usInterval ); XTtcPs_SetPrescaler( &xRTOSTickTimerInstance, ucPrescale ); /* The priority must be the lowest possible. */ XScuGic_SetPriorityTriggerType( &xInterruptController, XPAR_XTTCPS_3_INTR, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, ucLevelSensitive ); /* Connect to the interrupt controller. */ xStatus = XScuGic_Connect( &xInterruptController, XPAR_XTTCPS_3_INTR, (Xil_ExceptionHandler) FreeRTOS_Tick_Handler, ( void * ) &xRTOSTickTimerInstance ); configASSERT( xStatus == XST_SUCCESS); /* Enable the interrupt in the GIC. */ XScuGic_Enable( &xInterruptController, XPAR_XTTCPS_3_INTR ); /* Enable the interrupts in the timer. */ XTtcPs_EnableInterrupts( &xRTOSTickTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); /* Start the timer. */ XTtcPs_Start( &xRTOSTickTimerInstance ); }
void FreeRTOS_SetupTickInterrupt( void ) { BaseType_t xStatus; XTtcPs_Config *pxTimerConfiguration; XInterval usInterval; uint8_t ucPrescale; const uint8_t ucLevelSensitive = 1; XScuGic_Config *pxInterruptControllerConfig; /* Initialize the interrupt controller driver. */ pxInterruptControllerConfig = XScuGic_LookupConfig( configINTERRUPT_CONTROLLER_DEVICE_ID ); XScuGic_CfgInitialize( &xInterruptController, pxInterruptControllerConfig, pxInterruptControllerConfig->CpuBaseAddress ); /* Connect the interrupt controller interrupt handler to the hardware interrupt handling logic in the ARM processor. */ Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_IRQ_INT, ( Xil_ExceptionHandler ) XScuGic_InterruptHandler, &xInterruptController); /* Enable interrupts in the ARM. */ Xil_ExceptionEnable(); pxTimerConfiguration = XTtcPs_LookupConfig( configTIMER_ID ); /* Initialise the device. */ xStatus = XTtcPs_CfgInitialize( &xTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); if( xStatus != XST_SUCCESS ) { /* Not sure how to do this before XTtcPs_CfgInitialize is called as *xRTOSTickTimerInstance is set within XTtcPs_CfgInitialize(). */ XTtcPs_Stop( &xTimerInstance ); xStatus = XTtcPs_CfgInitialize( &xTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); configASSERT( xStatus == XST_SUCCESS ); } /* Set the options. */ XTtcPs_SetOptions( &xTimerInstance, ( XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE ) ); /* Derive values from the tick rate. */ XTtcPs_CalcIntervalFromFreq( &xTimerInstance, configTICK_RATE_HZ, &( usInterval ), &( ucPrescale ) ); /* Set the interval and prescale. */ XTtcPs_SetInterval( &xTimerInstance, usInterval ); XTtcPs_SetPrescaler( &xTimerInstance, ucPrescale ); /* The priority must be the lowest possible. */ XScuGic_SetPriorityTriggerType( &xInterruptController, configTIMER_INTERRUPT_ID, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, ucLevelSensitive ); /* Connect to the interrupt controller. */ XScuGic_Connect( &xInterruptController, configTIMER_INTERRUPT_ID, ( Xil_InterruptHandler ) FreeRTOS_Tick_Handler, ( void * ) &xTimerInstance ); /* Enable the interrupt in the GIC. */ XScuGic_Enable( &xInterruptController, configTIMER_INTERRUPT_ID ); /* Enable the interrupts in the timer. */ XTtcPs_EnableInterrupts( &xTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); /* Start the timer. */ XTtcPs_Start( &xTimerInstance ); }