Updated PWM impl (WIP).

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-03-27 09:58:15 +08:00
parent d42b7664ac
commit 5c3e2a0640
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
2 changed files with 43 additions and 2 deletions

@ -1 +1 @@
Subproject commit ef83164ddba5403ec1e8eff4c102af907353bc95
Subproject commit 7b84e47e26ce6d180057b5c303ba21ac9e92ee9a

View File

@ -16,6 +16,10 @@
* LPC55S69 has 5 CTimers, each with 4 Match channels, each channel can route up to 2 pins
* Total: 40 PWM capable pins (at most)
* Actual: 30 pins (shared).
* Match channel 3 is special, normally it will be used as period channel, until
* initialized explicitly.
* The match channel will be switched to channel 2 if 3 is initialized, or to 1 if channel 2 is initialized
* eventually to 0. If all channels are occupied, then channel 3 can not be initialized.
*/
#define PWM_IMPL_INST_COUNT 5
@ -92,7 +96,44 @@ static const uint32_t s_pwm_channel_map[PWM_IMPL_INST_COUNT][PWM_IMPL_INST_COUNT
},
};
int mrb_machine_pwm_impl_config_set(uint32_t channel, machine_pwm_config_t *config) {
static const clock_attach_id_t s_pwm_clk_attach_list[] = {
kMAIN_CLK_to_CTIMER0, kMAIN_CLK_to_CTIMER1, kMAIN_CLK_to_CTIMER2, kMAIN_CLK_to_CTIMER3, kMAIN_CLK_to_CTIMER4,
};
static const CTIMER_Type *s_pwm_ct_list[] = {
CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4,
};
static bool mrb_machine_pwm_ctimer_in_use(uint8_t ctimer_id) {
/* Determine whether CTIMERx is in use:
* 1: Check module power down status
* 2: Check module enable and counter running status
* 3: Check MATCH output settings and enable status (by MATCH action)
*/
clock_attach_id_t ct_att_id = s_pwm_clk_attach_list[ctimer_id];
const CTIMER_Type *ct_inst = s_pwm_ct_list[ctimer_id];
/* Check if the clock is configured by us */
if (ct_att_id != CLOCK_GetClockAttachId(ct_att_id)) {
return false;
}
/* Check if this CTIMER is enabled */
if((ct_inst->TCR & CTIMER_TCR_CEN_MASK) == 0) {
return false;
}
/* Check if any MATCH channels are configured as reset.
* For a typical PWM setup, a channel needs at least 1 MATCH channel set as reset */
if((ct_inst->MCR & (CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR1R_MASK | CTIMER_MCR_MR2R_MASK | CTIMER_MCR_MR3R_MASK)) == 0) {
return false;
}
}
int mrb_machine_pwm_impl_init(uint32_t channel, machine_pwm_config_t *config) {
uint8_t ctimer_id = PWM_IMPL_CT_INST(channel);
uint8_t ctimer_mat = PWM_IMPL_CT_CH(channel);
uint8_t ctimer_off = PWM_IMPL_CT_OFFSET(channel);