WIP: PWM implementation

This commit is contained in:
Yilin Sun 2023-04-12 10:06:44 +08:00
parent f9056a5dd0
commit 4a5cc3b90f
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
1 changed files with 21 additions and 17 deletions

View File

@ -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;
}