From 42275c263bfefb69914fecff274e72bedd96002f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Mon, 11 Apr 2022 11:10:43 +0200 Subject: [PATCH] drivers: pwm_nrf5_sw: Use the PPI FORK feature when available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way, when RTC is used as the generator, one PPI channel per each configured PWM channel can be saved. Signed-off-by: Andrzej Głąbek --- drivers/pwm/pwm_nrf5_sw.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm_nrf5_sw.c b/drivers/pwm/pwm_nrf5_sw.c index a12b1413ea4..a3c394b9956 100644 --- a/drivers/pwm/pwm_nrf5_sw.c +++ b/drivers/pwm/pwm_nrf5_sw.c @@ -37,8 +37,15 @@ BUILD_ASSERT(DT_INST_PROP(0, clock_prescaler) == 0, #endif #define PWM_0_MAP_SIZE DT_INST_PROP(0, channel_count) -/* When RTC is used, one more PPI channel is required. */ -#define PPI_PER_CH (2 + USE_RTC) +/* When RTC is used, one more PPI task endpoint is required for clearing + * the counter, so when FORK feature is not available, one more PPI channel + * needs to be used. + */ +#if USE_RTC && !defined(PPI_FEATURE_FORKS_PRESENT) +#define PPI_PER_CH 3 +#else +#define PPI_PER_CH 2 +#endif struct pwm_config { union { @@ -187,7 +194,8 @@ static int pwm_nrf5_sw_pin_set(const struct device *dev, uint32_t pwm, NRF_GPIOTE->CONFIG[gpiote_ch] = 0; /* clear PPI used */ - ppi_mask = BIT(ppi_chs[0]) | BIT(ppi_chs[1]) | (USE_RTC ? BIT(ppi_chs[2]) : 0); + ppi_mask = BIT(ppi_chs[0]) | BIT(ppi_chs[1]) | + (PPI_PER_CH > 2 ? BIT(ppi_chs[2]) : 0); NRF_PPI->CHENCLR = ppi_mask; /* configure GPIO pin as output */ @@ -242,10 +250,15 @@ static int pwm_nrf5_sw_pin_set(const struct device *dev, uint32_t pwm, (uint32_t) &(rtc->EVENTS_COMPARE[0]); NRF_PPI->CH[ppi_chs[1]].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_OUT[gpiote_ch]); +#if defined(PPI_FEATURE_FORKS_PRESENT) + NRF_PPI->FORK[ppi_chs[1]].TEP = + (uint32_t) &(rtc->TASKS_CLEAR); +#else NRF_PPI->CH[ppi_chs[2]].EEP = (uint32_t) &(rtc->EVENTS_COMPARE[0]); NRF_PPI->CH[ppi_chs[2]].TEP = (uint32_t) &(rtc->TASKS_CLEAR); +#endif } else { NRF_PPI->CH[ppi_chs[0]].EEP = (uint32_t) &(timer->EVENTS_COMPARE[1 + channel]);