void timer_set_mode(u32 timer_peripheral, u8 clock_div, u8 alignment, u8 direction) { u32 cr1; cr1 = TIM_CR1(timer_peripheral); cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN); cr1 |= clock_div | alignment | direction; TIM_CR1(timer_peripheral) = cr1; }
static void timer2_setup ( void ) { //timer_reset ( TIM2 ); //timer_set_mode //timer_continuous_mode ( TIM2 ); /* Set timer start value. */ TIM_CNT(TIM2) = 1; /* Set timer prescaler. 72MHz/1440 => 50000 counts per second. */ TIM_PSC(TIM2) = 300; // 280K/s or 0.000 003 571 /* End timer value. If this is reached an interrupt is generated. */ TIM_ARR(TIM2) = 8; // // o-scope reports: // prescale 2000, 1->600 should be 100/sec; in fact, we're exactly 20ms between which is exactly 50 .. so callback is 60MHz, not 120MHz // manual says: // The reference manual (see page 133) states that the GPIO is capable of: // Fast toggle capable of changing every two clock cycles // --> okay so at 120MHz, the best we can do is 60MHz of GPIO. But thats different than here, where the timer seems halved.. /* Update interrupt enable. */ TIM_DIER(TIM2) |= TIM_DIER_UIE; //timer_set_repetition_counter ( TIM2, 100 ); /* Start timer. */ TIM_CR1(TIM2) |= TIM_CR1_CEN; return; }
int main(void) { rcc_clock_setup_in_hse_16mhz_out_72mhz(); gpio_setup(); nvic_setup(); gpio_clear(GPIOB, GPIO7); /* LED1 on */ gpio_set(GPIOB, GPIO6); /* LED2 off */ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN); /* the goal is to let the LED2 glow for a second and then be off for a second */ /* Set timer start value */ TIM_CNT(TIM2) = 1; /* Set timer prescaler. 72MHz/1440 => 50000 counts per second */ TIM_PSC(TIM2) = 1440; /* End timer value. If this value is reached an interrupt is generated */ TIM_ARR(TIM2) = 50000; /* Update interrupt enable */ TIM_DIER(TIM2) |= TIM_DIER_UIE; /* Start timer */ TIM_CR1(TIM2) |= TIM_CR1_CEN; while(1); /* Halt. */ return 0; }
/** * @brief Trigger function to start a 2 wire SSI read of arbitrary length * @param u7 nbits The number of bits to read */ void ssi_start_read(u8 nbits) { if(ext_buffer_flag == true) { ext_buffer->ready_flag = 0; } ssi_counter = nbits; ssi_state = SSI_START; TIM_CNT(SSI_TIMER) = 0; TIM_CR1(SSI_TIMER) |= TIM_CR1_CEN;// Start counter }
// init common timer // use SOFTI2C_TIMER_1 timer void delay_timer_init() { rcc_periph_clock_enable(get_rcc_by_port(SOFTI2C_TIMER_1)); timer_set_prescaler(SOFTI2C_TIMER_1, 72); timer_direction_up(SOFTI2C_TIMER_1); timer_continuous_mode(SOFTI2C_TIMER_1); timer_set_counter(SOFTI2C_TIMER_1, 0); /* Start timer. */ TIM_CR1(SOFTI2C_TIMER_1) |= TIM_CR1_CEN; timer_enable_counter(SOFTI2C_TIMER_1); }
void delay_nus(sGrpDev* pGrpDev, uint32_t nCount) { volatile uint16_t TIMCounter = nCount; if (pGrpDev->pTimer) { /* Counter enable. */ /* Reset prescaler value. */ timer_set_prescaler(pGrpDev->pTimer, 72); timer_direction_down(pGrpDev->pTimer); timer_enable_counter(pGrpDev->pTimer); timer_set_counter(pGrpDev->pTimer, TIMCounter); /* Start timer. */ TIM_CR1(pGrpDev->pTimer) |= TIM_CR1_CEN; while (TIMCounter > 1) { TIMCounter = timer_get_counter(pGrpDev->pTimer); } timer_disable_counter(pGrpDev->pTimer); } }
void ssi_bit_handler(u8 bit) { ssi_counter--; // Decrement bit Counter ssi_buffer = ssi_buffer << 1; // Shift buffer if(bit == 1) { ssi_buffer |= 1; // Add 1 to LSB } if((ssi_counter == 0) && (ext_buffer_flag == true)) { ext_buffer->value = ssi_buffer; ext_buffer->ready_flag = true; } // Set Timer TIM_CNT(SSI_TIMER) = 0; TIM_CR1(SSI_TIMER) |= TIM_CR1_CEN; }
void blinkRed(uint32_t count) { g_isRedBlinking = true; TIM_CR1(RGB_TIMER) = 0; // stop timer gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_R_PIN); gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_G_PIN); gpio_clear(LED_PORT, LED_R_PIN); gpio_clear(LED_PORT, LED_G_PIN); gpio_set(LED_PORT, LED_B_PIN); system_mutex_lock(); g_blinkCount = count; swTimer_registerOnTimer(onBlinkTimer, RGB_BLINK_DELAY_MS, false); system_mutex_unlock(); }
void setupPWM() { gpio_mode_setup(LED_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, LED_R_PIN | LED_G_PIN); gpio_set_output_options(LED_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, LED_R_PIN | LED_G_PIN); gpio_set_af(LED_PORT, GPIO_AF1, LED_R_PIN | LED_G_PIN); TIM_CCMR1(RGB_TIMER) = TIM_CCMR1_OC1M_PWM1 | TIM_CCMR1_OC2M_PWM1; TIM_CCER(RGB_TIMER) = TIM_CCER_CC1E | TIM_CCER_CC2E; TIM_PSC(RGB_TIMER) = 1000; TIM_ARR(RGB_TIMER) = 0xff; TIM_CR1(RGB_TIMER) = TIM_CR1_CEN; g_isRedBlinking = false; setLEDColor(127, 127, 0); }
void delay_ms(sGrpDev* pGrpDev, uint32_t nCount) { volatile uint16_t TIMCounter;// = nCount; uint16_t cnt2; /* Counter enable. */ /* Reset prescaler value. */ timer_set_prescaler(pGrpDev->pTimer, 7200); timer_direction_down(pGrpDev->pTimer); timer_enable_counter(pGrpDev->pTimer); for (cnt2 = 0; cnt2 < 750; cnt2++) { TIMCounter = nCount; timer_set_counter(pGrpDev->pTimer, TIMCounter); /* Start timer. */ TIM_CR1(pGrpDev->pTimer) |= TIM_CR1_CEN; while (TIMCounter > 1) { TIMCounter = timer_get_counter(pGrpDev->pTimer); } } timer_disable_counter(pGrpDev->pTimer); }
void timer1_setup() { // Timer 1 a 2MHz /* Set timer start value */ TIM_CNT(TIM1) = 1; /* Set timer prescaler. 72MHz/36 => 2MHz counts per second */ TIM_PSC(TIM1) = 36; // 2MHz /* End timer value. If this value is reached an interrupt is generated */ TIM_ARR(TIM1) = 60000; // 1kHz /* Update interrupt enable */ // TIM_DIER(TIM1) |= TIM_DIER_UIE; /* Start timer */ TIM_CR1(TIM1) |= TIM_CR1_CEN; }
void Encoder::UpdateRotorAngle(int dir) { if (encMode == SINGLE) { int16_t numPulses = GetPulseTimeFiltered(); angle += (int16_t)(dir * numPulses * anglePerPulse); } else if (encMode == RESOLVER) { GetAngleResolver(); } else { static uint16_t lastAngle = 0; uint16_t angleDiff; if (encMode == SPI) { angle = GetAngleSPI(); //Gets 12-bit angle <<= 4; uint16_t diffPos = angle - lastAngle; uint16_t diffNeg = lastAngle - angle; angleDiff = MIN(diffNeg, diffPos); } else { uint32_t cntVal = timer_get_counter(REV_CNT_TIMER); cntVal *= TWO_PI; cntVal /= pulsesPerTurn * 4; angle = (uint16_t)cntVal; angleDiff = (angle - lastAngle) & 0xFFFF; if ((TIM_CR1(REV_CNT_TIMER) & TIM_CR1_DIR_DOWN)) angleDiff = (lastAngle - angle) & 0xFFFF; } lastAngle = angle; turnsSinceLastSample += angleDiff; //Param::SetDig(Param::tm_meas, angle); } }
/** * Timer 2 interrupt service routine */ void tim2_isr(void) { TIM_SR(SSI_TIMER) &= ~TIM_SR_UIF;// Clear Interrupt Flag // Check state and run correct handler action switch(ssi_state) { case(SSI_START): // SSI Start of Frame { gpio_clear(SSI_GPIO, SSI_CLK_PIN);// Set the clock low ssi_state = SSI_CLK_LOW; // Change SSI state break; } case(SSI_CLK_HIGH): // SSI Clock High-to-Low { gpio_clear(SSI_GPIO, SSI_CLK_PIN);// Set clock low u8 input_bit = GPIO_IDR(SSI_GPIO) & SSI_DATA_PIN;// Read bit on pin 10 ssi_bit_handler(input_bit); // Call bit handler ssi_state = SSI_CLK_LOW; break; } case(SSI_CLK_LOW): // SSI Clock Low-to-High { // Set clock high gpio_set(SSI_GPIO, SSI_CLK_PIN); if(ssi_counter == 0) { ssi_state = SSI_IDLE; ssi_data_ready_flag = true; TIM_CR1(SSI_TIMER) &= ~TIM_CR1_CEN; // Turn off timer } else ssi_state = SSI_CLK_HIGH; break; } case(SSI_IDLE): // SSI Idle (Not Used) break; default: break; } }
void timer_update_on_overflow(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_URS; }
void timer_update_on_any(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; }
void timer_continuous_mode(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; }
void timer_one_shot_mode(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; }
void timer_direction_down(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; }
void timer_direction_up(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; }
void timer_set_alignment(u32 timer_peripheral, u32 alignment) { alignment &= TIM_CR1_CMS_MASK; TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK; TIM_CR1(timer_peripheral) |= alignment; }
void timer_disable_preload(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; }
void timer_enable_preload(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; }
void timer_enable_counter(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; }
void timer_enable_update_event(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; }
void timer_disable_update_event(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; }
void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) { clock_div &= TIM_CR1_CKD_CK_INT_MASK; TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK; TIM_CR1(timer_peripheral) |= clock_div; }
void timer_disable_counter(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; }
bool Pwm_stm32::init(void) { bool success = true; /* Enable peripheral port & TIM clock. */ //rcc_periph_clock_enable(RCC_GPIOx); rcc_periph_clock_enable(pwm_config_.rcc_timer_config); gpio_mode_setup(pwm_config_.gpio_config.port, GPIO_MODE_AF, GPIO_PUPD_NONE, pwm_config_.gpio_config.pin); gpio_set_af(pwm_config_.gpio_config.port, pwm_config_.gpio_config.alt_fct, pwm_config_.gpio_config.pin); gpio_set_output_options(pwm_config_.gpio_config.port, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, pwm_config_.gpio_config.port); //WARNING Common to all channels of that TIMER //select prescaler TIM_PSC(pwm_config_.timer_config) = prescaler_; //select the output period TIM_ARR(pwm_config_.timer_config) = period_; //enable the autoreload TIM_CR1(pwm_config_.timer_config) |= TIM_CR1_ARPE; //select counting mode (edge-aligned) TIM_CR1(pwm_config_.timer_config) |= TIM_CR1_CMS_EDGE; //counting up TIM_CR1(pwm_config_.timer_config) |= TIM_CR1_DIR_UP; //enable counter TIM_CR1(pwm_config_.timer_config) |= TIM_CR1_CEN; //CHANNEL SPECIFIC if (pwm_config_.channel_config == PWM_STM32_CHANNEL_1) { //Disable channel1 TIM_CCER(pwm_config_.timer_config) &= (uint16_t)~TIM_CCER_CC1E; //Reset output compare TIM_CCMR1(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR1_OC1M_MASK; TIM_CCMR1(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR1_CC1S_MASK; //Select output mode TIM_CCMR1(pwm_config_.timer_config) |= TIM_CCMR1_CC1S_OUT; //select polarity low TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC1NP; //select PWM mode 1 TIM_CCMR1(pwm_config_.timer_config) |= TIM_CCMR1_OC1M_PWM1; //select duty cycle TIM_CCR1(pwm_config_.timer_config) = duty_cyle_; //set the preload bit TIM_CCMR1(pwm_config_.timer_config) |= TIM_CCMR1_OC1PE; //enable capture/compare TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC1E; } else if (pwm_config_.channel_config == PWM_STM32_CHANNEL_2) { //Disable channel2 TIM_CCER(pwm_config_.timer_config) &= (uint16_t)~TIM_CCER_CC2E; //Reset output compare TIM_CCMR1(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR1_OC2M_MASK; TIM_CCMR1(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR1_CC2S_MASK; //Select output mode TIM_CCMR1(pwm_config_.timer_config) |= TIM_CCMR1_CC2S_OUT; //select polarity low TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC2NP; //select PWM mode 1 TIM_CCMR1(pwm_config_.timer_config) |= TIM_CCMR1_OC2M_PWM1; //select duty cycle TIM_CCR2(pwm_config_.timer_config) = duty_cyle_; //set the preload bit TIM_CCMR1(pwm_config_.timer_config) |= TIM_CCMR1_OC2PE; //enable capture/compare TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC2E; } else if (pwm_config_.channel_config == PWM_STM32_CHANNEL_3) { //Disable channel3 TIM_CCER(pwm_config_.timer_config) &= (uint16_t)~TIM_CCER_CC3E; //Reset output compare TIM_CCMR2(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR2_OC3M_MASK; TIM_CCMR2(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR2_CC3S_MASK; //Select output mode TIM_CCMR2(pwm_config_.timer_config) |= TIM_CCMR2_CC3S_OUT; //select polarity low TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC3NP; //select PWM mode 1 TIM_CCMR2(pwm_config_.timer_config) |= TIM_CCMR2_OC3M_PWM1; //select duty cycle TIM_CCR3(pwm_config_.timer_config) = duty_cyle_; //set the preload bit TIM_CCMR2(pwm_config_.timer_config) |= TIM_CCMR2_OC3PE; //enable capture/compare TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC3E; } else if (pwm_config_.channel_config == PWM_STM32_CHANNEL_4) { //Disable channel4 TIM_CCER(pwm_config_.timer_config) &= (uint16_t)~TIM_CCER_CC4E; //Reset output compare TIM_CCMR2(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR2_OC4M_MASK; TIM_CCMR2(pwm_config_.timer_config) &= (uint16_t)~TIM_CCMR2_CC4S_MASK; //Select output mode TIM_CCMR2(pwm_config_.timer_config) |= TIM_CCMR2_CC4S_OUT; //select polarity low TIM_CCER(pwm_config_.timer_config) |= (1 << 15); //TODO TIM_CCER_CC4NP does not exist in libopencm3 library //select PWM mode 1 TIM_CCMR2(pwm_config_.timer_config) |= TIM_CCMR2_OC4M_PWM1; //select duty cycle TIM_CCR4(pwm_config_.timer_config) = duty_cyle_; //set the preload bit TIM_CCMR2(pwm_config_.timer_config) |= TIM_CCMR2_OC4PE; //enable capture/compare TIM_CCER(pwm_config_.timer_config) |= TIM_CCER_CC4E; } return success; }