/* | |
* FreeRTOS Kernel V10.3.0 | |
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy of | |
* this software and associated documentation files (the "Software"), to deal in | |
* the Software without restriction, including without limitation the rights to | |
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | |
* the Software, and to permit persons to whom the Software is furnished to do so, | |
* subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in all | |
* copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
* | |
* http://www.FreeRTOS.org | |
* http://aws.amazon.com/freertos | |
* | |
* 1 tab == 4 spaces! | |
*/ | |
/* | |
* This file initialises three timers as follows: | |
* | |
* TIM2 and TIM3 provide the interrupts that are used with the IntQ | |
* standard demo tasks, which test interrupt nesting and using queues from | |
* interrupts. The timers generate interrupts at slightly different | |
* frequencies and use different priorities, resulting in a nesting depth of | |
* three (including the tick and PendSV interrupts, which run at lower | |
* priorities). | |
* | |
* TIM4 provides a much higher frequency timer that tests the nesting | |
* of interrupts that don't use the FreeRTOS API. For convenience, the high | |
* frequency timer also keeps a count of the number of times it executes, and | |
* the count can be used as the time base for the run time stats. | |
* | |
* All the timers can nest with the tick interrupt - creating a maximum | |
* interrupt nesting depth of 4. | |
* | |
*/ | |
/* Scheduler includes. */ | |
#include "FreeRTOS.h" | |
/* Demo includes. */ | |
#include "IntQueueTimer.h" | |
#include "IntQueue.h" | |
/* The frequencies at which the first two timers expire are slightly offset to | |
ensure they don't remain synchronised. The frequency of the highest priority | |
interrupt is 20 times faster so really hammers the interrupt entry and exit | |
code. */ | |
#define tmrTIMER_2_FREQUENCY ( 2000UL ) | |
#define tmrTIMER_3_FREQUENCY ( 2003UL ) | |
#define tmrTIMER_4_FREQUENCY ( 20000UL ) | |
/* The high frequency interrupt given a priority above the maximum at which | |
interrupt safe FreeRTOS calls can be made. The priority of the lower frequency | |
timers must still be above the tick interrupt priority. */ | |
#define tmrLOWER_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1 | |
#define tmrMEDIUM_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY | |
#define tmrHIGHER_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 1 | |
/*-----------------------------------------------------------*/ | |
/* For convenience the high frequency timer increments a variable that is then | |
used as the time base for the run time stats. */ | |
volatile uint32_t ulHighFrequencyTimerCounts = 0; | |
/*-----------------------------------------------------------*/ | |
void vInitialiseTimerForIntQueueTest( void ) | |
{ | |
TIM_HandleTypeDef xTimHandle; | |
const uint32_t ulPrescale = 0; /* No prescale. */ | |
/* Clock the utilised timers. */ | |
__TIM2_CLK_ENABLE(); | |
__TIM3_CLK_ENABLE(); | |
__TIM4_CLK_ENABLE(); | |
/* Configure TIM2 to generate an interrupt at the required frequency. */ | |
xTimHandle.Instance = TIM2; | |
xTimHandle.Init.Period = ( SystemCoreClock / 2UL ) / ( tmrTIMER_2_FREQUENCY - 1 ); | |
xTimHandle.Init.Prescaler = ulPrescale; | |
xTimHandle.Init.ClockDivision = 0; | |
xTimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; | |
HAL_TIM_Base_Init( &xTimHandle ); | |
HAL_TIM_Base_Start_IT( &xTimHandle ); | |
/* Configure and enable TIM2 interrupt. */ | |
NVIC_SetPriority( TIM2_IRQn, tmrLOWER_PRIORITY ); | |
NVIC_ClearPendingIRQ( TIM2_IRQn ); | |
NVIC_EnableIRQ( TIM2_IRQn ); | |
/* Repeat for TIM3 and TIM4. */ | |
xTimHandle.Instance = TIM3; | |
xTimHandle.Init.Period = ( SystemCoreClock / 2UL ) / ( tmrTIMER_3_FREQUENCY - 1 ); | |
HAL_TIM_Base_Init( &xTimHandle ); | |
HAL_TIM_Base_Start_IT( &xTimHandle ); | |
NVIC_SetPriority( TIM3_IRQn, tmrMEDIUM_PRIORITY ); | |
NVIC_ClearPendingIRQ( TIM3_IRQn ); | |
NVIC_EnableIRQ( TIM3_IRQn ); | |
xTimHandle.Instance = TIM4; | |
xTimHandle.Init.Period = ( SystemCoreClock / 2UL ) / ( tmrTIMER_4_FREQUENCY - 1 ); | |
HAL_TIM_Base_Init( &xTimHandle ); | |
HAL_TIM_Base_Start_IT( &xTimHandle ); | |
NVIC_SetPriority( TIM4_IRQn, tmrHIGHER_PRIORITY ); | |
NVIC_ClearPendingIRQ( TIM4_IRQn ); | |
NVIC_EnableIRQ( TIM4_IRQn ); | |
} | |
/*-----------------------------------------------------------*/ | |
void TIM2_IRQHandler( void ) | |
{ | |
/* Clear the interrupt and call the IntQTimer test function. */ | |
TIM2->SR = 0; | |
portYIELD_FROM_ISR( xFirstTimerHandler() ); | |
} | |
/*-----------------------------------------------------------*/ | |
void TIM3_IRQHandler( void ) | |
{ | |
/* Clear the interrupt and call the IntQTimer test function. */ | |
TIM3->SR = 0; | |
portYIELD_FROM_ISR( xSecondTimerHandler() ); | |
} | |
/*-----------------------------------------------------------*/ | |
void TIM4_IRQHandler( void ) | |
{ | |
TIM4->SR = 0; | |
/* Keep a count of the number of interrupts to use as a time base for the | |
run-time stats. */ | |
ulHighFrequencyTimerCounts++; | |
} | |