#include #include "system.h" static uint32_t master_clock = 0; /** Use TIM4_CH4, which is linked to PD15 AF1 **/ int pwm_init(uint32_t clock, uint32_t threshold) { uint32_t val = (clock / 100000); /* Frequency is 100 KHz */ uint32_t lvl; master_clock = clock; if (threshold > 100) return -1; lvl = (val * threshold) / 100; if (lvl != 0) lvl--; APB1_CLOCK_RST |= TIM4_APB1_CLOCK_ER_VAL; __asm__ volatile ("dmb"); APB1_CLOCK_RST &= ~TIM4_APB1_CLOCK_ER_VAL; APB1_CLOCK_ER |= TIM4_APB1_CLOCK_ER_VAL; /* disable CC */ TIM4_CCER &= ~TIM_CCER_CC4_ENABLE; TIM4_CR1 = 0; TIM4_PSC = 0; TIM4_ARR = val - 1; TIM4_CCR4 = lvl; TIM4_CCMR1 &= ~(0x03 << 0); TIM4_CCMR1 &= ~(0x07 << 4); TIM4_CCMR1 |= TIM_CCMR1_OC1M_PWM1; TIM4_CCMR2 &= ~(0x03 << 8); TIM4_CCMR2 &= ~(0x07 << 12); TIM4_CCMR2 |= TIM_CCMR2_OC4M_PWM1; TIM4_CCER |= TIM_CCER_CC4_ENABLE; TIM4_CR1 |= TIM_CR1_CLOCK_ENABLE | TIM_CR1_ARPE; __asm__ volatile ("dmb"); return 0; } /* Timer 2: Use val 60000 with PSC 1400 for 1s tick (84 Mhz) */ /* Timer 2: Use val 52500 with PSC 200 for 1/8 s tick (84 Mhz) */ #define TMR2_INIT_VAL 52500 #define TMR2_INIT_PSC 200 void timer_init(void) { uint32_t val = 0; uint32_t psc = 1; uint32_t err = 0; nvic_irq_enable(NVIC_TIM2_IRQN); nvic_irq_setprio(NVIC_TIM2_IRQN, 0); APB1_CLOCK_RST |= TIM2_APB1_CLOCK_ER_VAL; __asm__ volatile ("dmb"); APB1_CLOCK_RST &= ~TIM2_APB1_CLOCK_ER_VAL; APB1_CLOCK_ER |= TIM2_APB1_CLOCK_ER_VAL; TIM2_CR1 = 0; __asm__ volatile ("dmb"); TIM2_PSC = TMR2_INIT_PSC; TIM2_ARR = TMR2_INIT_VAL; TIM2_CR1 |= TIM_CR1_CLOCK_ENABLE; TIM2_DIER |= TIM_DIER_UIE; __asm__ volatile ("dmb"); } static volatile uint32_t tim2_ticks = 0; void isr_tim2(void) { TIM2_SR &= ~TIM_SR_UIF; tim2_ticks++; } void gettime(uint32_t *seconds, uint32_t *microseconds) { *microseconds = ((TIM2_CNT * TMR2_INIT_PSC) / 84) + (tim2_ticks & 0x07) * 125000; *seconds = (tim2_ticks >> 3); }