WIP PWM support.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
e024eb97d4
commit
f9056a5dd0
|
@ -24,7 +24,7 @@
|
|||
#define PWM_IMPL_INST_CH 4
|
||||
|
||||
/* FIXME: A reasonable clock for PWM resolution, could be determined dynamically. */
|
||||
#define PWM_IMPL_REASONABLE_CLK (10000000UL)
|
||||
#define PWM_IMPL_REASONABLE_CLK (10000000UL) /* 10MHz */
|
||||
|
||||
/* Timer channel ID fields */
|
||||
|
||||
|
@ -64,7 +64,7 @@
|
|||
(((port << PWM_IMPL_PIN_PORT_Pos) & PWM_IMPL_PIN_PORT_Msk) | ((id << PWM_IMPL_PIN_ID_Pos) & PWM_IMPL_PIN_ID_Msk) | \
|
||||
((func << PWM_IMPL_PIN_FUNC_Pos) & PWM_IMPL_PIN_FUNC_Msk) | PWM_IMPL_PIN_VALID_Msk)
|
||||
|
||||
static const uint32_t s_pwm_channel_map[PWM_IMPL_INST_COUNT][PWM_IMPL_INST_COUNT * 2] = {
|
||||
static uint32_t const s_pwm_channel_map[PWM_IMPL_INST_COUNT][PWM_IMPL_INST_COUNT * 2] = {
|
||||
{
|
||||
PWM_IMPL_PIN(0, 0, 3), PWM_IMPL_PIN(0, 30, 3), // CT0MAT0, Channel ID: 0, 1
|
||||
PWM_IMPL_PIN(0, 3, 2), PWM_IMPL_PIN(0, 31, 3), // CT0MAT1, Channel ID: 2, 3
|
||||
|
@ -101,7 +101,7 @@ static clock_attach_id_t const 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 CTIMER_Type * const s_pwm_ct_list[] = {
|
||||
static CTIMER_Type *const s_pwm_ct_list[] = {
|
||||
CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4,
|
||||
};
|
||||
|
||||
|
@ -150,14 +150,15 @@ int mrb_machine_pwm_impl_init(uint32_t channel, machine_pwm_config_t *config) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ctimer_pin = s_pwm_channel_map[ctimer_id][ctimer_off];
|
||||
uint32_t ctimer_pin = s_pwm_channel_map[ctimer_id][ctimer_off];
|
||||
CTIMER_Type *ctimer_inst = s_pwm_ct_list[ctimer_id];
|
||||
|
||||
/* Check valid bit to see if there really is a pin for this channel */
|
||||
if (PWM_IMPL_PIN_VALID(ctimer_pin) == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(!mrb_machine_pwm_ctimer_in_use(ctimer_id)) {
|
||||
if (!mrb_machine_pwm_ctimer_in_use(ctimer_id)) {
|
||||
/* CTimer is not in use, initialize timer */
|
||||
|
||||
CLOCK_AttachClk(s_pwm_clk_attach_list[ctimer_id]);
|
||||
|
@ -167,10 +168,26 @@ int mrb_machine_pwm_impl_init(uint32_t channel, machine_pwm_config_t *config) {
|
|||
|
||||
ct_cfg.prescale = CLOCK_GetCTimerClkFreq(ctimer_id) / PWM_IMPL_REASONABLE_CLK;
|
||||
|
||||
CTIMER_Init(s_pwm_ct_list[ctimer_id], &ct_cfg);
|
||||
CTIMER_Init(ctimer_inst, &ct_cfg);
|
||||
|
||||
ctimer_inst->MCR = CTIMER_MCR_MR3R_MASK;
|
||||
} else {
|
||||
ctimer_inst->MCR |= CTIMER_MCR_MR3R_MASK;
|
||||
}
|
||||
|
||||
/* FIXME: How to determine whether CTIMER is set up previously? Tips: CTIMER might be used by other gems... */
|
||||
/* 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;
|
||||
|
||||
/* 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 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 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));
|
||||
|
|
Loading…
Reference in New Issue