You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
501 lines
11 KiB
501 lines
11 KiB
#include "timer.h"
|
|
#include "interrupt.h"
|
|
|
|
#define BASE ((TIM_TypeDef *)timerBase_Addr_List[timer])
|
|
|
|
#define HANDLE_INT_FLAG(flagReg, flagMask, intType)(\
|
|
// do{ ... }while(1) is used to insure that this makro acts as a function call
|
|
do {\
|
|
// check if flag is set
|
|
if ((flagReg) & (flagMask)) {\
|
|
// clear flag
|
|
(flagReg) &= ~(flagMask);\
|
|
// indext to corresponding handler and execute
|
|
((intHandler_t)(intHandlerList[(intType)]))();)\
|
|
}\
|
|
} while (0)
|
|
|
|
void timerReset(timerNo_t timer)
|
|
{
|
|
if(timerBus_No[timer]==1)
|
|
{
|
|
RCC->APB1RSTR |= (1<<timerBus_Rst_bitPos[timer]);
|
|
RCC->APB1RSTR &=~ (1<<timerBus_Rst_bitPos[timer]);
|
|
return;
|
|
}
|
|
RCC->APB2RSTR |= (1<<timerBus_Rst_bitPos[timer]);
|
|
RCC->APB2RSTR &=~ (1<<timerBus_Rst_bitPos[timer]);
|
|
}
|
|
|
|
void timerActivateBus(timerNo_t timer)
|
|
{
|
|
if(timerBus_No[timer]==1)
|
|
{
|
|
RCC->APB1ENR |= (1<<timerBus_En_bitPos[timer]);
|
|
return;
|
|
}
|
|
RCC->APB2ENR |= (1<<timerBus_En_bitPos[timer]);
|
|
}
|
|
|
|
void timerEnable(timerNo_t timer)
|
|
{
|
|
BASE->CR1 |= TIM_CR1_CEN; //all the timers have the same CEN bit in CR1 register pos 0
|
|
}
|
|
|
|
void timerDisable(timerNo_t timer)
|
|
{
|
|
BASE->CR1 &=~ TIM_CR1_CEN; //all the timers have the same CEN bit in CR1 register pos 0
|
|
}
|
|
|
|
void timerSetMode(timerNo_t timer, timerMode_t mode)
|
|
{
|
|
// Propably not needed
|
|
}
|
|
|
|
void timerSetCountDirection(timerNo_t timer, timerCountDirection_t direction)
|
|
{
|
|
if(direction == upCounting)
|
|
{
|
|
|
|
BASE->CR1 &=~ TIM_CR1_DIR;
|
|
return;
|
|
}
|
|
|
|
BASE->CR1 |= TIM_CR1_DIR;
|
|
}
|
|
|
|
void timerSetPrescaler(timerNo_t timer, uint32_t prescaler)
|
|
{
|
|
if(prescaler > timerRes_Prescaler[timer])
|
|
{
|
|
timerThrowError(prescalerOutOfRange);
|
|
return; // To prevent writing wrong value in to the Register
|
|
}
|
|
BASE->PSC = prescaler;
|
|
}
|
|
|
|
void timerSetPostscaler(timerNo_t timer, uint32_t postscaler)
|
|
{
|
|
timerThrowError(functionNotSupported);
|
|
}
|
|
|
|
void timerSetAutoReload(timerNo_t timer, uint32_t reload)
|
|
{
|
|
// TODO: implement error wen reload value exceeds the hardware register size (e.g. value > 16bit)
|
|
BASE->ARR = reload;
|
|
}
|
|
|
|
void timerClearCounter(timerNo_t timer)
|
|
{
|
|
BASE->CNT = 0;
|
|
}
|
|
|
|
uint8_t timerGetUpdateInterrupt(timerNo_t timer)
|
|
{
|
|
return (BASE->SR & 1);
|
|
}
|
|
|
|
void timerClearUpdateInterrupt(timerNo_t timer)
|
|
{
|
|
BASE->SR &= ~1;
|
|
}
|
|
|
|
/* Second stage configuration */
|
|
void timerInitCounter ( timerNo_t timer,
|
|
uint32_t prescaler,
|
|
uint32_t autoReload,
|
|
timerCountDirection_t direction)
|
|
{
|
|
timerActivateBus(timer);
|
|
timerSetMode(timer, counter);
|
|
timerSetCountDirection(timer,direction);
|
|
timerSetPrescaler(timer, prescaler);
|
|
timerSetAutoReload(timer, autoReload);
|
|
}
|
|
|
|
void timerInitOutputCompare( timerNo_t timer,
|
|
timerOutputCompareMode_t mode,
|
|
uint8_t timerIoChannel,
|
|
pinNo_t pinNo,
|
|
uint16_t altFunction,
|
|
uint8_t polarity,
|
|
uint32_t ccValue)
|
|
{
|
|
timerStop(timer);
|
|
pinSetMode(pinNo,alternate);
|
|
pinSetAlternate(pinNo,altFunction);
|
|
|
|
// TODO: check for value existing register size
|
|
//if(ccValue)
|
|
// timerThrowError(timerError_t error)
|
|
switch(timerIoChannel)
|
|
{
|
|
case 1:
|
|
BASE->CCMR1 &= ~TIM_CCMR1_OC1M;
|
|
BASE->CCMR1 |= mode << TIM_CCMR1_OC1M_Pos;
|
|
BASE->CCER |= TIM_CCER_CC1E;
|
|
BASE->CCER |= (1&&polarity) << TIM_CCER_CC1P_Pos;
|
|
BASE->CCER &= ~TIM_CCER_CC1NP;
|
|
BASE->CCR1 = (uint16_t)ccValue;
|
|
break;
|
|
case 2:
|
|
BASE->CCMR1 &= ~TIM_CCMR1_OC2M;
|
|
BASE->CCMR1 |= mode << TIM_CCMR1_OC2M_Pos;
|
|
BASE->CCER |= TIM_CCER_CC2E;
|
|
BASE->CCER |= (1&&polarity) << TIM_CCER_CC2P_Pos;
|
|
BASE->CCER &= ~TIM_CCER_CC2NP;
|
|
BASE->CCR2 = (uint16_t)ccValue;
|
|
break;
|
|
case 3:
|
|
BASE->CCMR2 &= ~TIM_CCMR2_OC3M;
|
|
BASE->CCMR2 |= mode << TIM_CCMR2_OC3M_Pos;
|
|
BASE->CCER |= TIM_CCER_CC3E;
|
|
BASE->CCER |= (1&&polarity) << TIM_CCER_CC3P_Pos;
|
|
BASE->CCER &= ~TIM_CCER_CC3NP;
|
|
BASE->CCR3 = (uint16_t)ccValue;
|
|
break;
|
|
case 4:
|
|
BASE->CCMR2 &= ~TIM_CCMR2_OC4M;
|
|
BASE->CCMR2 |= mode << TIM_CCMR2_OC4M_Pos;
|
|
BASE->CCER |= TIM_CCER_CC4E;
|
|
BASE->CCER |= (1&&polarity) << TIM_CCER_CC4P_Pos;
|
|
BASE->CCER &= ~TIM_CCER_CC4NP;
|
|
BASE->CCR4 = (uint16_t)ccValue;
|
|
break;
|
|
default:
|
|
timerThrowError(ccChannelNoOutOfRange);
|
|
break;
|
|
};
|
|
}
|
|
|
|
void timerSetCounterCompareValue(timerNo_t timer,
|
|
uint8_t timerIoChannel,
|
|
uint32_t ccValue)
|
|
{
|
|
switch(timerIoChannel) {
|
|
case 1:
|
|
BASE->CCR1 = (uint16_t)ccValue;
|
|
break;
|
|
case 2:
|
|
BASE->CCR2 = (uint16_t)ccValue;
|
|
break;
|
|
case 3:
|
|
BASE->CCR3 = (uint16_t)ccValue;
|
|
break;
|
|
case 4:
|
|
BASE->CCR4 = (uint16_t)ccValue;
|
|
break;
|
|
default:
|
|
timerThrowError(ccChannelNoOutOfRange);
|
|
break;
|
|
};
|
|
}
|
|
|
|
|
|
/* Bus Clock
|
|
* ------------------------------ = Duty (Hz)
|
|
* (Prescaler-1) * (Period-1)
|
|
*/
|
|
void timerSetHz(timerNo_t timer, uint16_t hz)
|
|
{
|
|
uint32_t prescaler = 8000000;
|
|
uint32_t period = 0;
|
|
uint32_t temp = 0;
|
|
|
|
do{
|
|
prescaler = prescaler / 10;
|
|
}while(prescaler > 0xffff);
|
|
|
|
|
|
do{
|
|
period = period + 1;
|
|
temp = 8000000/(prescaler*(period));
|
|
}while(temp >= hz);
|
|
|
|
timerSetPrescaler(timer, prescaler-1);
|
|
timerSetAutoReload(timer, period-1);
|
|
timerClearCounter(timer);
|
|
}
|
|
|
|
void timerSetMs(timerNo_t timer, uint16_t ms)
|
|
{
|
|
|
|
}
|
|
|
|
void timerSetNs(timerNo_t timer, uint16_t ns)
|
|
{
|
|
|
|
}
|
|
|
|
void timerSetPs(timerNo_t timer, uint16_t ps)
|
|
{
|
|
|
|
}
|
|
|
|
void timerSart(timerNo_t timer)
|
|
{
|
|
timerEnable(timer);
|
|
}
|
|
|
|
void timerHalt(timerNo_t timer)
|
|
{
|
|
timerDisable(timer);
|
|
}
|
|
|
|
void timerStop(timerNo_t timer)
|
|
{
|
|
timerDisable(timer);
|
|
timerClearCounter(timer);
|
|
}
|
|
|
|
|
|
uint32_t timerGetCount(timerNo_t timer)
|
|
{
|
|
return BASE->CNT;
|
|
}
|
|
|
|
|
|
void timerThrowError(timerError_t error)
|
|
{
|
|
while(1);
|
|
}
|
|
|
|
// Interrupt service routines
|
|
|
|
void TIM1_BRK_UP_TRG_COM_IRQHandler()
|
|
{
|
|
if(TIM1->SR & TIM_SR_BIF) {
|
|
TIM1->SR &= ~TIM_SR_BIF;
|
|
((intHandler_t)(intHandlerList[TIM1_BREAK]))();
|
|
}
|
|
|
|
if(TIM1->SR & TIM_SR_UIF) {
|
|
TIM1->SR &= ~TIM_SR_UIF;
|
|
((intHandler_t)(intHandlerList[TIM1_UPDATE]))();
|
|
}
|
|
|
|
if(TIM1->SR & TIM_SR_TIF) {
|
|
TIM1->SR &= ~TIM_SR_TIF;
|
|
((intHandler_t)(intHandlerList[TIM1_TRIGGER]))();
|
|
}
|
|
|
|
if(TIM1->SR & TIM_SR_COMIF) {
|
|
TIM1->SR &= ~TIM_SR_COMIF;
|
|
((intHandler_t)(intHandlerList[TIM1_COMMUNICATION]))();
|
|
}
|
|
}
|
|
|
|
void TIM1_CC_IRQHandler()
|
|
{
|
|
if(TIM1->SR & TIM_SR_CC1IF) {
|
|
TIM1-> SR &= ~TIM_SR_CC1IF;
|
|
((intHandler_t)(intHandlerList[TIM1_COUNTERCOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM1->SR & TIM_SR_CC2IF) {
|
|
TIM1-> SR &= ~TIM_SR_CC2IF;
|
|
((intHandler_t)(intHandlerList[TIM1_COUNTERCOMPARE_2]))();
|
|
}
|
|
|
|
if(TIM1->SR & TIM_SR_CC3IF) {
|
|
TIM1-> SR &= ~TIM_SR_CC3IF;
|
|
((intHandler_t)(intHandlerList[TIM1_COUNTERCOMPARE_3]))();
|
|
}
|
|
|
|
if(TIM1->SR & TIM_SR_CC4IF) {
|
|
TIM1-> SR &= ~TIM_SR_CC4IF;
|
|
((intHandler_t)(intHandlerList[TIM1_COUNTERCOMPARE_4]))();
|
|
}
|
|
}
|
|
|
|
void TIM2_IRQHandler()
|
|
{
|
|
if(TIM2->SR & TIM_SR_UIF) {
|
|
TIM2-> SR &= ~TIM_SR_UIF;
|
|
((intHandler_t)(intHandlerList[TIM2_UPDATE]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC1IF) {
|
|
TIM2-> SR &= ~TIM_SR_CC1IF;
|
|
((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC2IF) {
|
|
TIM2-> SR &= ~TIM_SR_CC2IF;
|
|
((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_2]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC3IF) {
|
|
TIM2-> SR &= ~TIM_SR_CC3IF;
|
|
((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_3]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC4IF) {
|
|
TIM2-> SR &= ~TIM_SR_CC4IF;
|
|
((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_4]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_TIF) {
|
|
TIM2-> SR &= ~TIM_SR_TIF;
|
|
((intHandler_t)(intHandlerList[TIM2_TRIGGER]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC1OF) {
|
|
TIM2-> SR &= ~TIM_SR_CC1OF;
|
|
((intHandler_t)(intHandlerList[TIM2_CAPTURECOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC2OF) {
|
|
TIM2-> SR &= ~TIM_SR_CC2OF;
|
|
((intHandler_t)(intHandlerList[TIM2_CAPTURECOMPARE_2]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC3OF) {
|
|
TIM2-> SR &= ~TIM_SR_CC3OF;
|
|
((intHandler_t)(intHandlerList[TIM2_CAPTURECOMPARE_3]))();
|
|
}
|
|
|
|
if(TIM2->SR & TIM_SR_CC4OF) {
|
|
TIM2-> SR &= ~TIM_SR_CC4OF;
|
|
((intHandler_t)(intHandlerList[TIM2_CAPTURECOMAPRE_4]))();
|
|
}
|
|
}
|
|
|
|
void TIM3_IRQHandler()
|
|
{
|
|
if(TIM3->SR & TIM_SR_UIF) {
|
|
// clear flag
|
|
TIM3-> SR &= ~TIM_SR_UIF;
|
|
|
|
//TODO: call handler here
|
|
((intHandler_t)(intHandlerList[TIM3_UPDATE]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC1IF) {
|
|
TIM3-> SR &= ~TIM_SR_CC1IF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_COUNTERCOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC2IF) {
|
|
TIM3-> SR &= ~TIM_SR_CC2IF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_COUNTERCOMPARE_2]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC3IF) {
|
|
TIM3-> SR &= ~TIM_SR_CC3IF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_COUNTERCOMPARE_3]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC4IF) {
|
|
TIM3-> SR &= ~TIM_SR_CC4IF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_COUNTERCOMPARE_4]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_TIF) {
|
|
TIM3-> SR &= ~TIM_SR_TIF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_TRIGGER]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC1OF) {
|
|
TIM3-> SR &= ~TIM_SR_CC1OF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_CAPTURECOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC2OF) {
|
|
TIM3-> SR &= ~TIM_SR_CC2OF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_CAPTURECOMPARE_2]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC3OF) {
|
|
TIM3-> SR &= ~TIM_SR_CC3OF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_CAPTURECOMPARE_3]))();
|
|
}
|
|
|
|
if(TIM3->SR & TIM_SR_CC4OF) {
|
|
TIM3-> SR &= ~TIM_SR_CC4OF;
|
|
|
|
((intHandler_t)(intHandlerList[TIM3_CAPTURECOMAPRE_4]))();
|
|
}
|
|
}
|
|
|
|
void TIM14_IRQHandler()
|
|
{
|
|
if(TIM14->SR & TIM_SR_CC1OF) {
|
|
TIM14-> SR &= ~TIM_SR_CC1OF;
|
|
((intHandler_t)(intHandlerList[TIM14_CAPTURECOMPARE_1_OVERCAPTURE]))();
|
|
}
|
|
|
|
if(TIM14->SR & TIM_SR_CC1IF) {
|
|
TIM14-> SR &= ~TIM_SR_CC1IF;
|
|
((intHandler_t)(intHandlerList[TIM14_CAPTURECOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM14->SR & TIM_SR_UIF) {
|
|
TIM14-> SR &= ~TIM_SR_UIF;
|
|
((intHandler_t)(intHandlerList[TIM14_UPDATE]))();
|
|
}
|
|
}
|
|
|
|
void TIM16_IRQHandler()
|
|
{
|
|
if(TIM16->SR & TIM_SR_CC1OF) {
|
|
TIM16-> SR &= ~TIM_SR_CC1OF;
|
|
((intHandler_t)(intHandlerList[TIM16_CAPTURECOMPARE_1_OVERCAPTURE]))();
|
|
}
|
|
|
|
if(TIM16->SR & TIM_SR_BIF) {
|
|
TIM16-> SR &= ~TIM_SR_BIF;
|
|
((intHandler_t)(intHandlerList[TIM16_BREAK]))();
|
|
}
|
|
|
|
if(TIM16->SR & TIM_SR_COMIF) {
|
|
TIM16-> SR &= ~TIM_SR_COMIF;
|
|
((intHandler_t)(intHandlerList[TIM16_COMMUNICATION]))();
|
|
}
|
|
|
|
if(TIM16->SR & TIM_SR_CC1IF) {
|
|
TIM16-> SR &= ~TIM_SR_CC1IF;
|
|
((intHandler_t)(intHandlerList[TIM16_CAPTURECOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM16->SR & TIM_SR_UIF) {
|
|
TIM16-> SR &= ~TIM_SR_UIF;
|
|
((intHandler_t)(intHandlerList[TIM16_UPDATE]))();
|
|
}
|
|
}
|
|
|
|
void TIM117_IRQHandler()
|
|
{
|
|
if(TIM17->SR & TIM_SR_CC1OF) {
|
|
TIM17-> SR &= ~TIM_SR_CC1OF;
|
|
((intHandler_t)(intHandlerList[TIM17_CAPTURECOMPARE_1_OVERCAPTURE]))();
|
|
}
|
|
|
|
if(TIM17->SR & TIM_SR_BIF) {
|
|
TIM17-> SR &= ~TIM_SR_BIF;
|
|
((intHandler_t)(intHandlerList[TIM17_BREAK]))();
|
|
}
|
|
|
|
if(TIM17->SR & TIM_SR_COMIF) {
|
|
TIM17-> SR &= ~TIM_SR_COMIF;
|
|
((intHandler_t)(intHandlerList[TIM17_COMMUNICATION]))();
|
|
}
|
|
|
|
if(TIM17->SR & TIM_SR_CC1IF) {
|
|
TIM17-> SR &= ~TIM_SR_CC1IF;
|
|
((intHandler_t)(intHandlerList[TIM17_CAPTURECOMPARE_1]))();
|
|
}
|
|
|
|
if(TIM17->SR & TIM_SR_UIF) {
|
|
TIM17-> SR &= ~TIM_SR_UIF;
|
|
((intHandler_t)(intHandlerList[TIM17_UPDATE]))();
|
|
}
|
|
} |