From 4a5cc3b90fd7385cc7083752f1eab9f8ee0cc3f9 Mon Sep 17 00:00:00 2001 From: Yilin Sun Date: Wed, 12 Apr 2023 10:06:44 +0800 Subject: [PATCH] WIP: PWM implementation --- src/mrb_machine_impl/mrb_machine_pwm_impl.c | 38 ++++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/mrb_machine_impl/mrb_machine_pwm_impl.c b/src/mrb_machine_impl/mrb_machine_pwm_impl.c index 21f8c53..99641c4 100644 --- a/src/mrb_machine_impl/mrb_machine_pwm_impl.c +++ b/src/mrb_machine_impl/mrb_machine_pwm_impl.c @@ -105,6 +105,10 @@ static CTIMER_Type *const s_pwm_ct_list[] = { CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, }; +static IRQn_Type const s_pwm_irq_list[] = { + CTIMER0_IRQn, CTIMER1_IRQn, CTIMER2_IRQn, CTIMER3_IRQn, +}; + static bool mrb_machine_pwm_ctimer_in_use(uint8_t ctimer_id) { /* Determine whether CTIMERx is in use: * 1: Check module power down status @@ -161,6 +165,9 @@ int mrb_machine_pwm_impl_init(uint32_t channel, machine_pwm_config_t *config) { if (!mrb_machine_pwm_ctimer_in_use(ctimer_id)) { /* CTimer is not in use, initialize timer */ + /* Disable interrupt for CTx */ + DisableIRQ(s_pwm_irq_list[ctimer_id]); + CLOCK_AttachClk(s_pwm_clk_attach_list[ctimer_id]); ctimer_config_t ct_cfg; @@ -170,25 +177,29 @@ int mrb_machine_pwm_impl_init(uint32_t channel, machine_pwm_config_t *config) { CTIMER_Init(ctimer_inst, &ct_cfg); - ctimer_inst->MCR = CTIMER_MCR_MR3R_MASK; - } else { - ctimer_inst->MCR |= CTIMER_MCR_MR3R_MASK; + CTIMER_EnableResetMatchChannel(ctimer_inst, kCTIMER_Match_3, true); } /* From now on, the pin will be controlled by MATx PWM */ ctimer_inst->PWMC |= (1 << ctimer_mat); - /* Calculate new */ - uint32_t rl_match = (PWM_IMPL_REASONABLE_CLK / config->freq); - ctimer_inst->MSR[3] = rl_match; + /* Calculate new reload value */ + uint32_t rl_match_old = ctimer_inst->MR[3]; + uint32_t rl_match_new = (PWM_IMPL_REASONABLE_CLK / config->freq); - /* TODO: Calculate all enabled match channel values due to possible frequency change !! */ - for(uint8_t i = 0; i < 3; i++) { - if(ctimer_inst->PWMC & (1 << i)) { - /* PWM channel i is enabled, write new value to shadow register */ + ctimer_inst->MSR[3] = rl_match_new; + + for (uint8_t i = 0; i < 3; i++) { + if (ctimer_inst->PWMC & (1 << i)) { + /* Corresponding PWM channel is enabled */ + uint32_t new_duty = (((uint64_t)ctimer_inst->MR[i] * rl_match_new) / rl_match_old); + ctimer_inst->MSR[i] = new_duty; } } + /* To disable PWM output: Write MRx to 0xFFFFFFFF, to enable, enable reload from shadow. */ + /* Since PWMC is enabled, no action will be performed on MRx registers */ + /* Function is retrieved from const array. */ uint32_t iocon_mode = IOCON_PIO_SLEW(0) | IOCON_DIGITAL_EN | IOCON_PIO_FUNC(PWM_IMPL_PIN_FUNC(ctimer_pin)); @@ -197,10 +208,3 @@ int mrb_machine_pwm_impl_init(uint32_t channel, machine_pwm_config_t *config) { return 0; } - -int mrb_machine_pwm_impl_config_get(uint32_t channel, machine_pwm_config_t *config) { - config->freq = 1000; - config->duty = 32768; - config->enabled = true; - return 0; -} \ No newline at end of file