drivers: pwm_nrf5_sw: Correctly use all channels provided by generator

Use compare channel 0 in the generator for handling the PWM period.
This way all other channels offered by the generator can be easily
used for handling pulses on particular PWM channels.
So far the driver allowed to configure more than 3 channels for certain
TIMER instances, but since channel 3 was always used for the period,
the generation could not work in such setups.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
Andrzej Głąbek 2022-04-08 17:02:38 +02:00 committed by Carles Cufí
commit d683ad0300

View file

@ -209,23 +209,23 @@ static int pwm_nrf5_sw_pin_set(const struct device *dev, uint32_t pwm,
/* configure RTC / TIMER */
if (USE_RTC) {
rtc->EVENTS_COMPARE[channel] = 0;
rtc->EVENTS_COMPARE[config->map_size] = 0;
rtc->EVENTS_COMPARE[1 + channel] = 0;
rtc->EVENTS_COMPARE[0] = 0;
/*
* '- 1' adjusts pulse and period cycles to the fact that CLEAR
* task event is generated always one LFCLK cycle after period
* COMPARE value is reached.
*/
rtc->CC[channel] = pulse_cycles - 1;
rtc->CC[config->map_size] = period_cycles - 1;
rtc->CC[1 + channel] = pulse_cycles - 1;
rtc->CC[0] = period_cycles - 1;
rtc->TASKS_CLEAR = 1;
} else {
timer->EVENTS_COMPARE[channel] = 0;
timer->EVENTS_COMPARE[config->map_size] = 0;
timer->EVENTS_COMPARE[1 + channel] = 0;
timer->EVENTS_COMPARE[0] = 0;
timer->CC[channel] = pulse_cycles;
timer->CC[config->map_size] = period_cycles;
timer->CC[1 + channel] = pulse_cycles;
timer->CC[0] = period_cycles;
timer->TASKS_CLEAR = 1;
}
@ -235,24 +235,24 @@ static int pwm_nrf5_sw_pin_set(const struct device *dev, uint32_t pwm,
/* setup PPI */
if (USE_RTC) {
NRF_PPI->CH[ppi_chs[0]].EEP =
(uint32_t) &(rtc->EVENTS_COMPARE[channel]);
(uint32_t) &(rtc->EVENTS_COMPARE[1 + channel]);
NRF_PPI->CH[ppi_chs[0]].TEP =
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
NRF_PPI->CH[ppi_chs[1]].EEP =
(uint32_t) &(rtc->EVENTS_COMPARE[config->map_size]);
(uint32_t) &(rtc->EVENTS_COMPARE[0]);
NRF_PPI->CH[ppi_chs[1]].TEP =
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
NRF_PPI->CH[ppi_chs[2]].EEP =
(uint32_t) &(rtc->EVENTS_COMPARE[config->map_size]);
(uint32_t) &(rtc->EVENTS_COMPARE[0]);
NRF_PPI->CH[ppi_chs[2]].TEP =
(uint32_t) &(rtc->TASKS_CLEAR);
} else {
NRF_PPI->CH[ppi_chs[0]].EEP =
(uint32_t) &(timer->EVENTS_COMPARE[channel]);
(uint32_t) &(timer->EVENTS_COMPARE[1 + channel]);
NRF_PPI->CH[ppi_chs[0]].TEP =
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
NRF_PPI->CH[ppi_chs[1]].EEP =
(uint32_t) &(timer->EVENTS_COMPARE[config->map_size]);
(uint32_t) &(timer->EVENTS_COMPARE[0]);
NRF_PPI->CH[ppi_chs[1]].TEP =
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
}
@ -360,10 +360,6 @@ static int pwm_nrf5_sw_init(const struct device *dev)
/* setup RTC */
rtc->PRESCALER = 0;
/*
* TODO: set EVTEN to map_size if not 3, i.e. if RTC supports
* less than 4 compares, then less channels can be supported.
*/
rtc->EVTENSET = (RTC_EVTENSET_COMPARE0_Msk |
RTC_EVTENSET_COMPARE1_Msk |
RTC_EVTENSET_COMPARE2_Msk |
@ -374,12 +370,7 @@ static int pwm_nrf5_sw_init(const struct device *dev)
timer->PRESCALER = config->prescaler;
timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
/*
* TODO: set shorts according to map_size if not 3, i.e. if
* NRF_TIMER supports more than 4 compares, then more channels
* can be supported.
*/
timer->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk;
timer->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
}
return 0;