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.
KED/csl/stm32f042k6t6/implementation/imp_timer.c

489 lines
10 KiB

#include "timer.h"
#include "interrupt.h"
#define BASE ((TIM_TypeDef *)timerBase_Addr_List[timer])
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_IRQn()
{
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_IRQn()
{
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_IRQn()
{
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_IRQn()
{
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_IRQn()
{
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]))();
}
}