Skip to content

Timer pull request #447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
136 changes: 126 additions & 10 deletions cores/arduino/stm32/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ uint32_t getTimerClkFreq(TIM_TypeDef *tim)
return uwTimclock;
}


/**
* @brief This function will set the timer to generate pulse in interrupt mode with a particular duty cycle
* @param timer_id : timer_id_e
Expand All @@ -799,7 +800,9 @@ void TimerPulseInit(stimer_t *obj, uint16_t period, uint16_t pulseWidth, void (*
TIM_OC_InitTypeDef sConfig = {};
TIM_HandleTypeDef *handle = &(obj->handle);

obj->timer = TIMER_SERVO;
if (obj->timer == 0x00) {
obj->timer = TIMER_SERVO;
}

//min pulse = 1us - max pulse = 65535us
handle->Instance = obj->timer;
Expand Down Expand Up @@ -836,6 +839,80 @@ void TimerPulseInit(stimer_t *obj, uint16_t period, uint16_t pulseWidth, void (*
}
}

/**
* @brief This function will attach timer interrupt to with a particular duty cycle on channel x
* @param timer_id : timer_id_e
* @param irqHandle : interrupt routine to call
* @param timChannel : timmer channel
* @param pulseWidth : phase of the timer where the callback will happen
* @retval None
*/
void attachIntHandleOC(stimer_t *obj, void (*irqHandle)(void), uint16_t timChannel, uint16_t pulseWidth)
{
TIM_OC_InitTypeDef sConfig = {};
TIM_HandleTypeDef *handle = &(obj->handle);

sConfig.OCMode = TIM_OCMODE_TIMING;
sConfig.Pulse = pulseWidth;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE;
#if !defined(STM32L0xx) && !defined(STM32L1xx)
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
#endif
//HAL_NVIC_SetPriority(getTimerIrq(obj->timer), 14, 0);
//HAL_NVIC_EnableIRQ(getTimerIrq(obj->timer));

if (HAL_TIM_OC_Init(handle) != HAL_OK) {
return;
}
switch (timChannel) {
case 1:
obj->irqHandleOC_CH1 = irqHandle;
if (HAL_TIM_OC_Start_IT(handle, TIM_CHANNEL_1) != HAL_OK) {
return;
}
if (HAL_TIM_OC_ConfigChannel(handle, &sConfig, TIM_CHANNEL_1) != HAL_OK) {
return;
}
break;
case 2:
obj->irqHandleOC_CH2 = irqHandle;
if (HAL_TIM_OC_Start_IT(handle, TIM_CHANNEL_2) != HAL_OK) {
return;
}
if (HAL_TIM_OC_ConfigChannel(handle, &sConfig, TIM_CHANNEL_2) != HAL_OK) {
return;
}
break;
case 3:
obj->irqHandleOC_CH3 = irqHandle;
if (HAL_TIM_OC_Start_IT(handle, TIM_CHANNEL_3) != HAL_OK) {
return;
}
if (HAL_TIM_OC_ConfigChannel(handle, &sConfig, TIM_CHANNEL_3) != HAL_OK) {
return;
}
break;
case 4:
obj->irqHandleOC_CH4 = irqHandle;
if (HAL_TIM_OC_Start_IT(handle, TIM_CHANNEL_4) != HAL_OK) {
return;
}
if (HAL_TIM_OC_ConfigChannel(handle, &sConfig, TIM_CHANNEL_4) != HAL_OK) {
return;
}
break;
default:
return;
break;
}
return;
}



/**
* @brief This function will reset the pulse generation
* @param timer_id : timer_id_e
Expand All @@ -844,8 +921,11 @@ void TimerPulseInit(stimer_t *obj, uint16_t period, uint16_t pulseWidth, void (*
void TimerPulseDeinit(stimer_t *obj)
{
TIM_HandleTypeDef *handle = &(obj->handle);

obj->irqHandleOC = NULL;
obj->irqHandleOC_CH1 = NULL;
obj->irqHandleOC_CH2 = NULL;
obj->irqHandleOC_CH3 = NULL;
obj->irqHandleOC_CH4 = NULL;

HAL_NVIC_DisableIRQ(getTimerIrq(obj->timer));

Expand Down Expand Up @@ -900,18 +980,41 @@ void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
uint32_t channel = 0;
stimer_t *obj = get_timer_obj(htim);
switch (htim->Channel) {
case HAL_TIM_ACTIVE_CHANNEL_1:
channel = TIM_CHANNEL_1 / 4;
if (obj->irqHandleOC_CH1 != NULL) {
obj->irqHandleOC_CH1();
}
break;
case HAL_TIM_ACTIVE_CHANNEL_2:
channel = TIM_CHANNEL_2 / 4;
if (obj->irqHandleOC_CH2 != NULL) {
obj->irqHandleOC_CH2();
}
break;
case HAL_TIM_ACTIVE_CHANNEL_3:
if (obj->irqHandleOC_CH3 != NULL) {
obj->irqHandleOC_CH3();
}
channel = TIM_CHANNEL_3 / 4;
break;
case HAL_TIM_ACTIVE_CHANNEL_4:
if (obj->irqHandleOC_CH4 != NULL) {
obj->irqHandleOC_CH4();
}
channel = TIM_CHANNEL_4 / 4;
break;
default:
return;
break;
}

//make it compatible with older versions
if (obj->irqHandleOC != NULL) {
switch (htim->Channel) {
case HAL_TIM_ACTIVE_CHANNEL_1:
channel = TIM_CHANNEL_1 / 4;
break;
default:
return;
break;
}
obj->irqHandleOC(obj, channel);
}

}

/**
Expand Down Expand Up @@ -1058,6 +1161,19 @@ void setCCRRegister(stimer_t *obj, uint32_t channel, uint32_t value)
__HAL_TIM_SET_COMPARE(&(obj->handle), channel * 4, value);
}


/**
* @brief Set the TIM Capture Compare Register value.
* @param timer_id : id of the timer
* @param prescaler : prescaler value to set for this timer.
* @retval None
*/
void setTimerPrescalerRegister(stimer_t *obj, uint32_t prescaler)
{
__HAL_TIM_SET_PRESCALER(&(obj->handle), prescaler);
}


/**
* @brief Set the TIM Capture Compare Register value.
* @param timer_id : id of the timer
Expand Down
6 changes: 6 additions & 0 deletions cores/arduino/stm32/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ struct timer_s {
uint8_t idx;
void (*irqHandle)(stimer_t *);
void (*irqHandleOC)(stimer_t *, uint32_t);
void (*irqHandleOC_CH1)(void);
void (*irqHandleOC_CH2)(void);
void (*irqHandleOC_CH3)(void);
void (*irqHandleOC_CH4)(void);
PinName pin;
volatile timerPinInfo_t pinInfo;
};
Expand Down Expand Up @@ -200,13 +204,15 @@ void TimerPulseDeinit(stimer_t *obj);
uint32_t getTimerCounter(stimer_t *obj);
void setTimerCounter(stimer_t *obj, uint32_t value);
void setCCRRegister(stimer_t *obj, uint32_t channel, uint32_t value);
void setTimerPrescalerRegister(stimer_t *obj, uint32_t prescaler);
uint32_t getCCRRegister(stimer_t *obj, uint32_t channel);

uint32_t getTimerIrq(TIM_TypeDef *tim);
uint8_t getTimerClkSrc(TIM_TypeDef *tim);
uint32_t getTimerClkFreq(TIM_TypeDef *tim);

void attachIntHandle(stimer_t *obj, void (*irqHandle)(stimer_t *));
void attachIntHandleOC(stimer_t *obj, void (*irqHandle)(void), uint16_t timChannel, uint16_t pulseWidth);

#ifdef __cplusplus
}
Expand Down