uint32_t attachTimerCallback(uint8_t timer, ISRType ISR, uint32_t usDelay) { // Get the correct PCLK RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCC_Clocks); uint32_t PCLK = RCC_Clocks.PCLK1_Frequency;// Frequency in Hz TIM_TypeDef *TIMx = TIMER_MAP[timer].TIMx; // For timers on APB2 use PCLK2 #if defined(STM32F446xx) if (TIMx == TIM1 || TIMx == TIM8 || TIMx == TIM9 || TIMx == TIM10 || TIMx == TIM11) PCLK = RCC_Clocks.PCLK2_Frequency; #elif defined(SERIES_STM32F30x) if (TIMx == TIM1 || TIMx == TIM8 || TIMx == TIM15 || TIMx == TIM16 || TIMx == TIM17) PCLK = RCC_Clocks.PCLK2_Frequency; #endif // Set the update ISR TimerInfo *cfg = &TIMER_MAP[timer]; cfg->isr = ISR; // Start interrupts with low priority uint8_t priority = 0xd; nvicEnable(TIMER_MAP[timer].IRQn, priority); // Start 1MHz timebase TIM_Cmd(TIMx, DISABLE); TIM_DeInit(TIMx); // FIXME always getting half of what expected... timerInitHelper(timer, PCLK/(1000000)-1, usDelay-1); TIMx->CNT = 0; TIM_ClearITPendingBit(TIMx, TIM_IT_Update); TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE); TIM_Cmd(TIMx, ENABLE); return PCLK; }
void timerInit(uint8_t timer, int freqHz) { // Enable interrupts for the timer (but not any of the timer updates yet) nvicEnable(TIMER_MAP[timer].IRQn, 2); timerInitHelper(timer, 1, TIMER_PERIOD(freqHz)); TIM_Cmd(TIMER_MAP[timer].TIMx, ENABLE); }
// Helper function void setupTimerUpdateInterrupt(uint8_t i, ISRType ISR, uint16_t prescaler, uint32_t period) { uint8_t timer = TIMEBASE_MAP[i].timer; timerInitHelper(timer, prescaler, period); TIM_ITConfig(TIMER_MAP[timer].TIMx, TIM_IT_Update, ENABLE); TIM_Cmd(TIMER_MAP[timer].TIMx, ENABLE); // Start interrupts with low priority uint8_t priority = (i==0) ? 0xe : 0xf; nvicEnable(TIMER_MAP[timer].IRQn, priority); TIMEBASE_MAP[i].isr = ISR; }
void attachInterruptWithPriority(uint8_t pinName, ISRType ISR, InterruptTrigger mode, uint8_t priority) { // Connect EXTIi to this pin const PinInfo *pinfo = &PIN_MAP[pinName]; #if defined(SERIES_STM32F10x) if (pinfo->port == GPIOA) GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, pinfo->pin); else if (pinfo->port == GPIOB) GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, pinfo->pin); else if (pinfo->port == GPIOC) GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, pinfo->pin); else if (pinfo->port == GPIOD) GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, pinfo->pin); else if (pinfo->port == GPIOE) GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, pinfo->pin); else if (pinfo->port == GPIOF) GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, pinfo->pin); #else if (pinfo->port == GPIOA) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, pinfo->pin); else if (pinfo->port == GPIOB) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, pinfo->pin); else if (pinfo->port == GPIOC) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, pinfo->pin); else if (pinfo->port == GPIOD) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, pinfo->pin); else if (pinfo->port == GPIOE) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, pinfo->pin); else if (pinfo->port == GPIOF) SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, pinfo->pin); #endif // Configure EXTIi line EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = extiLines[pinfo->pin]; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; if (mode == RISING) EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; else if (mode == FALLING) EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; else EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // Local code EXTI_MAP[pinfo->pin].handler = ISR; // Enable the interrupt with low priority. // TODO: check https://github.com/spark/core-firmware/blob/master/src/spark_wiring_interrupts.cpp does something peculiar with special cases?? nvicEnable(extiIRQn[pinfo->pin], priority); }
void pinTimerInit(uint8_t pin) { uint8_t timer = PIN_MAP[pin].timer; nvicEnable(TIMER_MAP[timer].IRQn, 2); // Use the frequency set using analogWriteFrequency timerInitHelper(timer, 1, TIMER_PERIOD(TIMER_MAP[timer].freqHz)); TIM_Cmd(TIMER_MAP[timer].TIMx, ENABLE); // FIXME: Advanced timers need to be specified in variant.cpp // isAdvancedTimer() ir something // http://www.disca.upv.es/aperles/arm_cortex_m3/curset/STM32F4xx_DSP_StdPeriph_Lib_V1.0.1/html/group___t_i_m___group4.html #if defined(SERIES_STM32F4xx) if (TIMER_MAP[timer].TIMx == TIM1) { TIM_CtrlPWMOutputs(TIM1, ENABLE); } #endif #if defined(SERIES_STM32F30x) if (IS_TIM_LIST6_PERIPH(TIMER_MAP[timer].TIMx)) { TIM_CtrlPWMOutputs(TIMER_MAP[timer].TIMx, ENABLE); } #endif }