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:
parent
f73618906d
commit
d683ad0300
1 changed files with 14 additions and 23 deletions
|
@ -209,23 +209,23 @@ static int pwm_nrf5_sw_pin_set(const struct device *dev, uint32_t pwm,
|
||||||
|
|
||||||
/* configure RTC / TIMER */
|
/* configure RTC / TIMER */
|
||||||
if (USE_RTC) {
|
if (USE_RTC) {
|
||||||
rtc->EVENTS_COMPARE[channel] = 0;
|
rtc->EVENTS_COMPARE[1 + channel] = 0;
|
||||||
rtc->EVENTS_COMPARE[config->map_size] = 0;
|
rtc->EVENTS_COMPARE[0] = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* '- 1' adjusts pulse and period cycles to the fact that CLEAR
|
* '- 1' adjusts pulse and period cycles to the fact that CLEAR
|
||||||
* task event is generated always one LFCLK cycle after period
|
* task event is generated always one LFCLK cycle after period
|
||||||
* COMPARE value is reached.
|
* COMPARE value is reached.
|
||||||
*/
|
*/
|
||||||
rtc->CC[channel] = pulse_cycles - 1;
|
rtc->CC[1 + channel] = pulse_cycles - 1;
|
||||||
rtc->CC[config->map_size] = period_cycles - 1;
|
rtc->CC[0] = period_cycles - 1;
|
||||||
rtc->TASKS_CLEAR = 1;
|
rtc->TASKS_CLEAR = 1;
|
||||||
} else {
|
} else {
|
||||||
timer->EVENTS_COMPARE[channel] = 0;
|
timer->EVENTS_COMPARE[1 + channel] = 0;
|
||||||
timer->EVENTS_COMPARE[config->map_size] = 0;
|
timer->EVENTS_COMPARE[0] = 0;
|
||||||
|
|
||||||
timer->CC[channel] = pulse_cycles;
|
timer->CC[1 + channel] = pulse_cycles;
|
||||||
timer->CC[config->map_size] = period_cycles;
|
timer->CC[0] = period_cycles;
|
||||||
timer->TASKS_CLEAR = 1;
|
timer->TASKS_CLEAR = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,24 +235,24 @@ static int pwm_nrf5_sw_pin_set(const struct device *dev, uint32_t pwm,
|
||||||
/* setup PPI */
|
/* setup PPI */
|
||||||
if (USE_RTC) {
|
if (USE_RTC) {
|
||||||
NRF_PPI->CH[ppi_chs[0]].EEP =
|
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 =
|
NRF_PPI->CH[ppi_chs[0]].TEP =
|
||||||
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
||||||
NRF_PPI->CH[ppi_chs[1]].EEP =
|
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 =
|
NRF_PPI->CH[ppi_chs[1]].TEP =
|
||||||
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
||||||
NRF_PPI->CH[ppi_chs[2]].EEP =
|
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 =
|
NRF_PPI->CH[ppi_chs[2]].TEP =
|
||||||
(uint32_t) &(rtc->TASKS_CLEAR);
|
(uint32_t) &(rtc->TASKS_CLEAR);
|
||||||
} else {
|
} else {
|
||||||
NRF_PPI->CH[ppi_chs[0]].EEP =
|
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 =
|
NRF_PPI->CH[ppi_chs[0]].TEP =
|
||||||
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
||||||
NRF_PPI->CH[ppi_chs[1]].EEP =
|
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 =
|
NRF_PPI->CH[ppi_chs[1]].TEP =
|
||||||
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
(uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]);
|
||||||
}
|
}
|
||||||
|
@ -360,10 +360,6 @@ static int pwm_nrf5_sw_init(const struct device *dev)
|
||||||
/* setup RTC */
|
/* setup RTC */
|
||||||
rtc->PRESCALER = 0;
|
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 = (RTC_EVTENSET_COMPARE0_Msk |
|
||||||
RTC_EVTENSET_COMPARE1_Msk |
|
RTC_EVTENSET_COMPARE1_Msk |
|
||||||
RTC_EVTENSET_COMPARE2_Msk |
|
RTC_EVTENSET_COMPARE2_Msk |
|
||||||
|
@ -374,12 +370,7 @@ static int pwm_nrf5_sw_init(const struct device *dev)
|
||||||
timer->PRESCALER = config->prescaler;
|
timer->PRESCALER = config->prescaler;
|
||||||
timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
|
timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
|
||||||
|
|
||||||
/*
|
timer->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue