diff --git a/examples/stm32/mb525/pwmleds/pwmleds.c b/examples/stm32/mb525/pwmleds/pwmleds.c index db7c9ca6..393928f3 100644 --- a/examples/stm32/mb525/pwmleds/pwmleds.c +++ b/examples/stm32/mb525/pwmleds/pwmleds.c @@ -240,12 +240,12 @@ void clock_setup(void) { rcc_clock_setup_in_hse_8mhz_out_72mhz(); - /* Enable TIM3 clock. */ - rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM3EN); + /* Enable TIM1 clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN); /* Enable GPIOC, Alternate Function clocks. */ rcc_peripheral_enable_clock(&RCC_APB2ENR, - RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN); + RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN); } void gpio_setup(void) @@ -254,81 +254,95 @@ void gpio_setup(void) * Set GPIO6 (in GPIO port C) to * 'output alternate function push-pull'. */ - gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, - GPIO_TIM3_FR_CH1 | - GPIO_TIM3_FR_CH2 | - GPIO_TIM3_FR_CH3 | - GPIO_TIM3_FR_CH4); + GPIO_TIM1_CH1 | + GPIO_TIM1_CH2 | + GPIO_TIM1_CH3 | + GPIO_TIM1_CH4); - /* Remap TIM3: + /* Remap TIM1: * CH1 -> PC6 * CH2 -> PC7 * CH3 -> PC8 * CH4 -> PC9 */ - AFIO_MAPR |= AFIO_MAPR_TIM3_REMAP_FULL_REMAP; + //AFIO_MAPR |= AFIO_MAPR_TIM3_REMAP_FULL_REMAP; } void tim_setup(void) { +#if 0 + TIM1_CR1 = TIM_CR1_CMS_CENTER_1 | TIM_CR1_ARPE; + TIM1_CCMR1 = TIM_CCMR1_OC1M_PWM1 | TIM_CCMR1_OC1PE | TIM_CCMR1_OC2M_PWM1 | TIM_CCMR1_OC2PE; + TIM1_CCMR2 = TIM_CCMR2_OC3M_PWM1 | TIM_CCMR2_OC3PE; + + TIM1_CCER &= ~TIM_CCER_CC1P; +#endif +#if 1 + TIM1_SMCR &= ~TIM_SMCR_SMS_MASK; + TIM1_CR1 &= ~TIM_CR1_CEN; + /* Clock division and mode */ - TIM3_CR1 = TIM_CR1_CKD_CK_INT | TIM_CR1_CMS_EDGE; + TIM1_CR1 = TIM_CR1_CKD_CK_INT | TIM_CR1_CMS_EDGE; /* Period */ - TIM3_ARR = 65535; + TIM1_ARR = 65535; /* Prescaler */ - TIM3_PSC = 0; - TIM3_EGR = TIM_EGR_UG; + TIM1_PSC = 2; + TIM1_EGR = TIM_EGR_UG; /* ---- */ /* Output compare 1 mode and preload */ - TIM3_CCMR1 |= TIM_CCMR1_OC1M_PWM1 | TIM_CCMR1_OC1PE; + TIM1_CCMR1 |= TIM_CCMR1_OC1M_PWM1 | TIM_CCMR1_OC1PE; /* Polarity and state */ - // TIM3_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; - TIM3_CCER |= TIM_CCER_CC1E; + // TIM1_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; + TIM1_CCER |= TIM_CCER_CC1E; /* Capture compare value */ - TIM3_CCR1 = 0; + TIM1_CCR1 = 1000; /* ---- */ /* Output compare 2 mode and preload */ - TIM3_CCMR1 |= TIM_CCMR1_OC2M_PWM1 | TIM_CCMR1_OC2PE; + TIM1_CCMR1 |= TIM_CCMR1_OC2M_PWM1 | TIM_CCMR1_OC2PE; /* Polarity and state */ - // TIM3_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; - TIM3_CCER |= TIM_CCER_CC2E; + // TIM1_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; + TIM1_CCER |= TIM_CCER_CC2E; /* Capture compare value */ - TIM3_CCR2 = 0; + TIM1_CCR2 = 1000; /* ---- */ /* Output compare 3 mode and preload */ - TIM3_CCMR2 |= TIM_CCMR2_OC3M_PWM1 | TIM_CCMR2_OC3PE; + TIM1_CCMR2 |= TIM_CCMR2_OC3M_PWM1 | TIM_CCMR2_OC3PE; /* Polarity and state */ - // TIM3_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; - TIM3_CCER |= TIM_CCER_CC3E; + // TIM1_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; + TIM1_CCER |= TIM_CCER_CC3E; /* Capture compare value */ - TIM3_CCR3 = 0; + TIM1_CCR3 = 1000; /* ---- */ /* Output compare 4 mode and preload */ - TIM3_CCMR2 |= TIM_CCMR2_OC4M_PWM1 | TIM_CCMR2_OC4PE; + TIM1_CCMR2 |= TIM_CCMR2_OC4M_PWM1 | TIM_CCMR2_OC4PE; /* Polarity and state */ - // TIM3_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; - TIM3_CCER |= TIM_CCER_CC4E; + // TIM1_CCER = TIM_CCER_CC1P | TIM_CCER_CC1E; + TIM1_CCER |= TIM_CCER_CC4E; /* Capture compare value */ - TIM3_CCR4 = 0; + TIM1_CCR4 = 1000; /* ---- */ /* ARR reload enable */ - TIM3_CR1 |= TIM_CR1_ARPE; + TIM1_CR1 |= TIM_CR1_ARPE; + + TIM1_BDTR |= TIM_BDTR_MOE; /* Counter enable */ - TIM3_CR1 |= TIM_CR1_CEN; + TIM1_CR1 |= TIM_CR1_CEN; +#endif } int main(void) @@ -349,25 +363,25 @@ int main(void) j3 = 0; d3 = 1; while (1) { - TIM3_CCR1 = gamma_table_linear[j0]; + TIM1_CCR1 = gamma_table_linear[j0]; j0 += d0; if (j0 == 255) d0 =- 1; if (j0 == 0) d0 = 1; - TIM3_CCR2 = gamma_table_1_3[j1]; + TIM1_CCR2 = gamma_table_1_3[j1]; j1 += d1; if (j1 == 255) d1 =- 1; if (j1 == 0) d1 = 1; - TIM3_CCR3 = gamma_table_2_5[j2]; + TIM1_CCR3 = gamma_table_2_5[j2]; j2 += d2; if (j2 == 255) d2 =- 1; if (j2 == 0) d2 = 1; - TIM3_CCR4= gamma_table_3_0[j3]; + TIM1_CCR4= gamma_table_3_0[j3]; j3 += d3; if (j3 == 255) d3 =- 1; @@ -387,25 +401,25 @@ int main(void) j3 = 128; d3 = -1; while (1) { - TIM3_CCR1 = GAMMA_TABLE[j0]; + TIM1_CCR1 = GAMMA_TABLE[j0]; j0 += d0; if (j0 == 255) d0 =- 1; if (j0 == 0) d0 = 1; - TIM3_CCR2 = GAMMA_TABLE[j1]; + TIM1_CCR2 = GAMMA_TABLE[j1]; j1 += d1; if (j1 == 255) d1 =- 1; if (j1 == 0) d1 = 1; - TIM3_CCR3 = GAMMA_TABLE[j2]; + TIM1_CCR3 = GAMMA_TABLE[j2]; j2 += d2; if (j2 == 255) d2 =- 1; if (j2 == 0) d2 = 1; - TIM3_CCR4 = GAMMA_TABLE[j3]; + TIM1_CCR4 = GAMMA_TABLE[j3]; j3 += d3; if (j3 == 255) d3 =- 1; @@ -428,25 +442,25 @@ int main(void) k = 0; kd = 1; while (1) { - TIM3_CCR1 = GAMMA_TABLE[j0]; + TIM1_CCR1 = GAMMA_TABLE[j0]; j0 += d0; if (j0 == 255) d0 =- 1; if (j0 == 19) j0 = 20; - TIM3_CCR2 = GAMMA_TABLE[j1]; + TIM1_CCR2 = GAMMA_TABLE[j1]; j1 += d1; if (j1 == 255) d1 =- 1; if (j1 == 19) j1 = 20; - TIM3_CCR3 = GAMMA_TABLE[j2]; + TIM1_CCR3 = GAMMA_TABLE[j2]; j2 += d2; if (j2 == 255) d2 =- 1; if (j2 == 19) j2 = 20; - TIM3_CCR4 = GAMMA_TABLE[j3]; + TIM1_CCR4 = GAMMA_TABLE[j3]; j3 += d3; if (j3 == 255) d3 =- 1; diff --git a/examples/stm32/stm32-h103/pwm_6step/pwm_6step.c b/examples/stm32/stm32-h103/pwm_6step/pwm_6step.c index af26c5a6..b35a4ba1 100644 --- a/examples/stm32/stm32-h103/pwm_6step/pwm_6step.c +++ b/examples/stm32/stm32-h103/pwm_6step/pwm_6step.c @@ -87,222 +87,103 @@ void tim_setup(void) /* Enable preload. */ timer_enable_preload(TIM1); - //timer_disable_preload(TIM1); /* Continous mode. */ timer_continuous_mode(TIM1); /* Period (32kHz) */ - TIM1_ARR = 72000000 / 32000; + timer_set_period(TIM1, 72000000 / 32000); /* -- OC1 and OC1N configuration -- */ - { - u16 tmp_ccmr1 = 0, tmp_ccer = 0, tmp_cr2 = 0; - /** Disable OC1. **/ - TIM1_CCER &= ~TIM_CCER_CC1E; + /* Disable outputs. */ + timer_disable_oc_output(TIM1, TIM_OC1); + timer_disable_oc_output(TIM1, TIM_OC1N); - /** Disable OC1N. **/ - TIM1_CCER &= ~TIM_CCER_CC1NE; + /* Configure global mode of line 1. */ + timer_disable_oc_clear(TIM1, TIM_OC1); + timer_enable_oc_preload(TIM1, TIM_OC1); + timer_set_oc_slow_mode(TIM1, TIM_OC1); + timer_set_oc_mode(TIM1, TIM_OC1, TIM_CCMR1_OC1M_PWM1); - /** Get registers. **/ - tmp_ccmr1 = TIM1_CCMR1; - tmp_ccer = TIM1_CCER; - tmp_cr2 = TIM1_CR2; + /* Configure OC1. */ + timer_set_oc_polarity_high(TIM1, TIM_OC1); + timer_set_oc_idle_state_set(TIM1, TIM_OC1); - /** Configure global mode of line 1 **/ + /* Configure OC1N. */ + timer_set_oc_polarity_high(TIM1, TIM_OC1N); + timer_set_oc_idle_state_set(TIM1, TIM_OC1N); - /* Disable OC1 clear. (esden: What is that?) */ - tmp_ccmr1 &= ~TIM_CCMR1_OC1CE; + /* Set the capture compare value for OC1. */ + timer_set_oc_value(TIM1, TIM_OC1, 100); - /* Set CC1 to output mode. */ - tmp_ccmr1 &= ~TIM_CCMR1_CC1S_MASK; - tmp_ccmr1 |= TIM_CCMR1_CC1S_OUT; - - /* Enable OC1 preload enable. */ - //tmp_ccmr1 |= TIM_CCMR1_OC1PE; - tmp_ccmr1 &= ~TIM_CCMR1_OC1PE; - - /* Disable OC1 fast mode. */ - tmp_ccmr1 &= ~TIM_CCMR1_OC1FE; - - /* Set OC1 mode to PWM1. */ - tmp_ccmr1 &= ~TIM_CCMR1_OC1M_MASK; - tmp_ccmr1 |= TIM_CCMR1_OC1M_PWM1; - - /** Configure OC1. **/ - - /* Set output polarity level, high. */ - tmp_ccer &= ~TIM_CCER_CC1P; - - /* Enable OC1 output */ - tmp_ccer |= TIM_CCER_CC1E; - - /* Set OC1 idle state to "set". (TIM1 and TIM8 only) */ - tmp_cr2 |= TIM_CR2_OIS1; - - /** Configure OC1N. **/ - - /* Set output polarity level, high. (TIM1 and TIM8 only) */ - tmp_ccer &= ~TIM_CCER_CC1NP; - - /* Enable OC1N output. (TIM1 and TIM8 only) */ - tmp_ccer |= TIM_CCER_CC1NE; - - /* Set OC1N idle state to "set". (TIM1 and TIM8 only) */ - tmp_cr2 |= TIM_CR2_OIS1N; - - /** Set the capture compare value for OC1 **/ - TIM1_CCR1 = 100; - - /** Write register values **/ - TIM1_CR2 = tmp_cr2; - TIM1_CCMR1 = tmp_ccmr1; - TIM1_CCER = tmp_ccer; - - } + /* Reenable outputs. */ + timer_enable_oc_output(TIM1, TIM_OC1); + timer_enable_oc_output(TIM1, TIM_OC1N); /* -- OC2 and OC2N configuration -- */ - { - u16 tmp_ccmr1 = 0, tmp_ccer = 0, tmp_cr2 = 0; - /** Disable OC2. **/ - TIM1_CCER &= ~TIM_CCER_CC2E; + /* Disable outputs. */ + timer_disable_oc_output(TIM1, TIM_OC2); + timer_disable_oc_output(TIM1, TIM_OC2N); - /** Disable OC2N. **/ - TIM1_CCER &= ~TIM_CCER_CC2NE; + /* Configure global mode of line 2. */ + timer_disable_oc_clear(TIM1, TIM_OC2); + timer_enable_oc_preload(TIM1, TIM_OC2); + timer_set_oc_slow_mode(TIM1, TIM_OC2); + timer_set_oc_mode(TIM1, TIM_OC2, TIM_CCMR1_OC2M_PWM1); - /** Get registers. **/ - tmp_ccmr1 = TIM1_CCMR1; - tmp_ccer = TIM1_CCER; - tmp_cr2 = TIM1_CR2; + /* Configure OC2. */ + timer_set_oc_polarity_high(TIM1, TIM_OC2); + timer_set_oc_idle_state_set(TIM1, TIM_OC2); - /** Configure global mode of line 1 **/ + /* Configure OC2N. */ + timer_set_oc_polarity_high(TIM1, TIM_OC2N); + timer_set_oc_idle_state_set(TIM1, TIM_OC2N); - /* Disable OC2 clear. (esden: What is that?) */ - tmp_ccmr1 &= ~TIM_CCMR1_OC2CE; + /* Set the capture compare value for OC1. */ + timer_set_oc_value(TIM1, TIM_OC2, 200); - /* Set CC2 to output mode. */ - tmp_ccmr1 &= ~TIM_CCMR1_CC2S_MASK; - tmp_ccmr1 |= TIM_CCMR1_CC2S_OUT; - - /* Enable OC2 preload enable. */ - tmp_ccmr1 |= TIM_CCMR1_OC2PE; - - /* Disable OC2 fast mode. */ - tmp_ccmr1 &= ~TIM_CCMR1_OC2FE; - - /* Set OC2 mode to PWM1. */ - tmp_ccmr1 &= ~TIM_CCMR1_OC2M_MASK; - tmp_ccmr1 |= TIM_CCMR1_OC2M_PWM1; - - /** Configure OC2. **/ - - /* Set output polarity level, high. */ - tmp_ccer &= ~TIM_CCER_CC2P; - - /* Enable OC2 output */ - tmp_ccer |= TIM_CCER_CC2E; - - /* Set OC2 idle state to "set". (TIM1 and TIM8 only) */ - tmp_cr2 |= TIM_CR2_OIS2; - - /** Configure OC2N. **/ - - /* Set output polarity level, high. (TIM1 and TIM8 only) */ - tmp_ccer &= ~TIM_CCER_CC2NP; - - /* Enable OC2N output. (TIM1 and TIM8 only) */ - tmp_ccer |= TIM_CCER_CC2NE; - - /* Set OC2N idle state to "set". (TIM1 and TIM8 only) */ - tmp_cr2 |= TIM_CR2_OIS2N; - - /** Set the capture compare value for OC2 **/ - TIM1_CCR2 = 200; - - /** Write register values **/ - TIM1_CR2 = tmp_cr2; - TIM1_CCMR1 = tmp_ccmr1; - TIM1_CCER = tmp_ccer; - - } + /* Reenable outputs. */ + timer_enable_oc_output(TIM1, TIM_OC2); + timer_enable_oc_output(TIM1, TIM_OC2N); /* -- OC3 and OC3N configuration -- */ - { - u16 tmp_ccmr2 = 0, tmp_ccer = 0, tmp_cr2 = 0; - /** Disable OC3. **/ - TIM1_CCER &= ~TIM_CCER_CC3E; + /* Disable outputs. */ + timer_disable_oc_output(TIM1, TIM_OC3); + timer_disable_oc_output(TIM1, TIM_OC3N); - /** Disable OC3N. **/ - TIM1_CCER &= ~TIM_CCER_CC3NE; + /* Configure global mode of line 3. */ + timer_disable_oc_clear(TIM1, TIM_OC3); + timer_enable_oc_preload(TIM1, TIM_OC3); + timer_set_oc_slow_mode(TIM1, TIM_OC3); + timer_set_oc_mode(TIM1, TIM_OC3, TIM_CCMR2_OC3M_PWM1); - /** Get registers. **/ - tmp_ccmr2 = TIM1_CCMR2; - tmp_ccer = TIM1_CCER; - tmp_cr2 = TIM1_CR2; + /* Configure OC3. */ + timer_set_oc_polarity_high(TIM1, TIM_OC3); + timer_set_oc_idle_state_set(TIM1, TIM_OC3); - /** Configure global mode of line 1 **/ + /* Configure OC3N. */ + timer_set_oc_polarity_high(TIM1, TIM_OC3N); + timer_set_oc_idle_state_set(TIM1, TIM_OC3N); - /* Disable OC3 clear. (esden: What is that?) */ - tmp_ccmr2 &= ~TIM_CCMR2_OC3CE; + /* Set the capture compare value for OC3. */ + timer_set_oc_value(TIM1, TIM_OC3, 300); - /* Set CC3 to output mode. */ - tmp_ccmr2 &= ~TIM_CCMR2_CC3S_MASK; - tmp_ccmr2 |= TIM_CCMR2_CC3S_OUT; - - /* Enable OC3 preload enable. */ - tmp_ccmr2 |= TIM_CCMR2_OC3PE; - - /* Disable OC3 fast mode. */ - tmp_ccmr2 &= ~TIM_CCMR2_OC3FE; - - /* Set OC3 mode to PWM1. */ - tmp_ccmr2 &= ~TIM_CCMR2_OC3M_MASK; - tmp_ccmr2 |= TIM_CCMR2_OC3M_PWM1; - - /** Configure OC3. **/ - - /* Set output polarity level, high. */ - tmp_ccer &= ~TIM_CCER_CC3P; - - /* Enable OC3 output */ - tmp_ccer |= TIM_CCER_CC3E; - - /* Set OC3 idle state to "set". (TIM1 and TIM8 only) */ - tmp_cr2 |= TIM_CR2_OIS3; - - /** Configure OC3N. **/ - - /* Set output polarity level, high. (TIM1 and TIM8 only) */ - tmp_ccer &= ~TIM_CCER_CC3NP; - - /* Enable OC3N output. (TIM1 and TIM8 only) */ - tmp_ccer |= TIM_CCER_CC3NE; - - /* Set OC3N idle state to "set". (TIM1 and TIM8 only) */ - tmp_cr2 |= TIM_CR2_OIS3N; - - /** Set the capture compare value for OC3 **/ - TIM1_CCR3 = 300; - - /** Write register values **/ - TIM1_CR2 = tmp_cr2; - TIM1_CCMR2 = tmp_ccmr2; - TIM1_CCER = tmp_ccer; - - } + /* Reenable outputs. */ + timer_enable_oc_output(TIM1, TIM_OC3); + timer_enable_oc_output(TIM1, TIM_OC3N); /* ---- */ /* ARR reload enable */ - TIM1_CR1 |= TIM_CR1_ARPE; + timer_enable_preload(TIM1); /* Enable outputs in the break subsystem */ TIM1_BDTR |= TIM_BDTR_MOE; /* Counter enable */ - TIM1_CR1 |= TIM_CR1_CEN; + timer_enable_counter(TIM1); } int main(void) diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index 738765b8..603a97c5 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -826,6 +826,19 @@ /* DMAB[15:0]: DMA register for burst accesses */ +/* --- TIMx convenience defines -------------------------------------------- */ + +/* Capture Compare channel designators */ +enum tim_oc_id { + TIM_OC1=0, + TIM_OC1N, + TIM_OC2, + TIM_OC2N, + TIM_OC3, + TIM_OC3N, + TIM_OC4, +}; + /* --- TIM functions ------------------------------------------------------- */ void timer_set_mode(u32 timer_peripheral, u8 clock_div, u8 alignment, u8 direction); @@ -854,5 +867,20 @@ void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral); void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral); void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral); void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral); +void timer_set_period(u32 timer_peripheral, u32 period); +void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, u32 mode); +void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value); #endif diff --git a/lib/stm32/timer.c b/lib/stm32/timer.c index 929469af..152b69f6 100644 --- a/lib/stm32/timer.c +++ b/lib/stm32/timer.c @@ -170,3 +170,450 @@ void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; } + +void timer_set_period(u32 timer_peripheral, u32 period) +{ + TIM_ARR(timer_peripheral) = period; +} + +void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, u32 mode) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK; + TIM_CCMR1(timer_peripheral) |= mode; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK; + TIM_CCMR1(timer_peripheral) |= mode; + break; + case TIM_OC3: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK; + TIM_CCMR2(timer_peripheral) |= mode; + break; + case TIM_OC4: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK; + TIM_CCMR2(timer_peripheral) |= mode; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + if ((timer_peripheral == TIM1) || + (timer_peripheral == TIM8)) { + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } + + } +} + +void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + if ((timer_peripheral == TIM1) || + (timer_peripheral == TIM8)) { + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } + + } +} + +void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + if ((timer_peripheral == TIM1) || + (timer_peripheral == TIM8)) { + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } + + } +} + +void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + if ((timer_peripheral == TIM1) || + (timer_peripheral == TIM8)) { + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } + + } +} + +void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + + /* Acting for TIM1 and TIM8 only. */ + if ((timer_peripheral == TIM1) || + (timer_peripheral == TIM8)) { + switch (oc_id) { + case TIM_OC1: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1; + break; + case TIM_OC1N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N; + break; + case TIM_OC2: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2; + break; + case TIM_OC2N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N; + break; + case TIM_OC3: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3; + break; + case TIM_OC3N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N; + break; + case TIM_OC4: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4; + break; + } + + } +} + +void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + + /* Acting for TIM1 and TIM8 only. */ + if ((timer_peripheral == TIM1) || + (timer_peripheral == TIM8)) { + switch (oc_id) { + case TIM_OC1: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1; + break; + case TIM_OC1N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N; + break; + case TIM_OC2: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2; + break; + case TIM_OC2N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N; + break; + case TIM_OC3: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3; + break; + case TIM_OC3N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N; + break; + case TIM_OC4: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4; + break; + } + + } +} + +void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCR1(timer_peripheral) = value; + break; + case TIM_OC2: + TIM_CCR2(timer_peripheral) = value; + break; + case TIM_OC3: + TIM_CCR3(timer_peripheral) = value; + break; + case TIM_OC4: + TIM_CCR4(timer_peripheral) = value; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +}