#include "timer.h" #include "interrupt.h" #define BASE ((TIM_TypeDef *)timerBase_Addr_List[timer]) #define HANDLE_INT_FLAG(flagReg, flagMask, intType)\ do {if ((flagReg) & (flagMask)) {\ (flagReg) &= ~(flagMask);\ ((intHandler_t)(intHandlerList[(intType)]))();\ }} while (0) void timerReset(timerNo_t timer) { if(timerBus_No[timer]==1) { RCC->APB1RSTR |= (1<APB1RSTR &=~ (1<APB2RSTR |= (1<APB2RSTR &=~ (1<APB1ENR |= (1<APB2ENR |= (1<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 timerStart(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() { HANDLE_INT_FLAG(TIM1->SR,TIM_SR_BIF,TIM1_BREAK); HANDLE_INT_FLAG(TIM1->SR,TIM_SR_BIF,TIM1_UPDATE); HANDLE_INT_FLAG(TIM1->SR,TIM_SR_BIF,TIM1_TRIGGER); HANDLE_INT_FLAG(TIM1->SR,TIM_SR_BIF,TIM1_COMMUNICATION); } void TIM1_CC_IRQHandler() { HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC1IF,TIM1_COUNTERCOMPARE_1); HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC2IF,TIM1_COUNTERCOMPARE_2); HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC3IF,TIM1_COUNTERCOMPARE_3); HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC4IF,TIM1_COUNTERCOMPARE_4); } void TIM2_IRQHandler() { HANDLE_INT_FLAG(TIM2->SR,TIM_SR_UIF,TIM2_UPDATE); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC1IF,TIM2_COUNTERCOMPARE_1); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC2IF,TIM2_COUNTERCOMPARE_2); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC3IF,TIM2_COUNTERCOMPARE_3); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC4IF,TIM2_COUNTERCOMPARE_4); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_TIF,TIM2_TRIGGER); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC1OF,TIM2_CAPTURECOMPARE_1); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC2OF,TIM2_CAPTURECOMPARE_2); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC3OF,TIM2_CAPTURECOMPARE_3); HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC4OF,TIM2_CAPTURECOMAPRE_4); } void TIM3_IRQHandler() { HANDLE_INT_FLAG(TIM3->SR,TIM_SR_UIF,TIM3_UPDATE); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC1IF,TIM3_COUNTERCOMPARE_1); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC2IF,TIM3_COUNTERCOMPARE_2); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC3IF,TIM3_COUNTERCOMPARE_3); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC4IF,TIM3_COUNTERCOMPARE_4); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_TIF,TIM3_TRIGGER); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC1OF,TIM3_CAPTURECOMPARE_1); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC2OF,TIM3_CAPTURECOMPARE_2); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC3OF,TIM3_CAPTURECOMPARE_3); HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC4OF,TIM3_CAPTURECOMAPRE_4); } void TIM16_IRQHandler() { HANDLE_INT_FLAG(TIM16->SR,TIM_SR_CC1OF,TIM16_CAPTURECOMPARE_1_OVERCAPTURE); HANDLE_INT_FLAG(TIM16->SR,TIM_SR_BIF,TIM16_BREAK); HANDLE_INT_FLAG(TIM16->SR,TIM_SR_COMIF,TIM16_COMMUNICATION); HANDLE_INT_FLAG(TIM16->SR,TIM_SR_CC1IF,TIM16_CAPTURECOMPARE_1); HANDLE_INT_FLAG(TIM16->SR,TIM_SR_UIF,TIM16_UPDATE); } void TIM117_IRQHandler() { HANDLE_INT_FLAG(TIM17->SR,TIM_SR_CC1OF,TIM17_CAPTURECOMPARE_1_OVERCAPTURE); HANDLE_INT_FLAG(TIM17->SR,TIM_SR_BIF,TIM17_BREAK); HANDLE_INT_FLAG(TIM17->SR,TIM_SR_COMIF,TIM17_COMMUNICATION); HANDLE_INT_FLAG(TIM17->SR,TIM_SR_CC1IF,TIM17_CAPTURECOMPARE_1); HANDLE_INT_FLAG(TIM17->SR,TIM_SR_UIF,TIM17_UPDATE); }