Skip to content

Commit

Permalink
[nrf fromlist] drivers: pwm: nrfx: adjust PWM driver to fast PWM120
Browse files Browse the repository at this point in the history
Fast PWM120 instance works with 320MHz clock, thus
pwm_nrfx_get_cycles_per_sec needs to be adjusted,
applying correct clock frequency.
Also, it uses cachable RAM, thus sys_cache function
needs to be added to flush the cached sequence.

Upstream PR #: 80672

Signed-off-by: Michał Stasiak <[email protected]>
  • Loading branch information
mstasiaknordic committed Nov 4, 2024
1 parent 83a3b95 commit 0e8f376
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions drivers/pwm/pwm_nrfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <hal/nrf_gpio.h>
#include <stdbool.h>
#include <zephyr/linker/devicetree_regions.h>
#include <zephyr/cache.h>
#include <zephyr/mem_mgmt/mem_attr.h>

#include <zephyr/logging/log.h>

Expand Down Expand Up @@ -40,6 +42,10 @@ struct pwm_nrfx_config {
nrfx_pwm_config_t initial_config;
nrf_pwm_sequence_t seq;
const struct pinctrl_dev_config *pcfg;
uint32_t clock_freq;
#ifdef CONFIG_DCACHE
uint32_t mem_attr;
#endif
};

struct pwm_nrfx_data {
Expand Down Expand Up @@ -176,6 +182,12 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,

seq_values_ptr_get(dev)[channel] = PWM_NRFX_CH_VALUE(compare_value, inverted);

#ifdef CONFIG_DCACHE
if (config->mem_attr & DT_MEM_CACHEABLE) {
sys_cache_data_flush_range((void *)config->seq.values.p_raw, config->seq.length);
}
#endif

LOG_DBG("channel %u, pulse %u, period %u, prescaler: %u.",
channel, pulse_cycles, period_cycles, data->prescaler);

Expand Down Expand Up @@ -243,11 +255,8 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
static int pwm_nrfx_get_cycles_per_sec(const struct device *dev, uint32_t channel,
uint64_t *cycles)
{
/* TODO: Since this function might be removed, we will always return
* 16MHz from this function and handle the conversion with prescaler,
* etc, in the pin set function. See issue #6958.
*/
*cycles = 16ul * 1000ul * 1000ul;
const struct pwm_nrfx_config *config = dev->config;
*cycles = config->clock_freq;

return 0;
}
Expand Down Expand Up @@ -333,13 +342,19 @@ static int pwm_nrfx_init(const struct device *dev)
#define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx)
#define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop)
#define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop)
#define PWM_MEM_REGION(idx) DT_PHANDLE(PWM(idx), memory_regions)

#define PWM_MEMORY_SECTION(idx) \
COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
DT_PHANDLE(PWM(idx), memory_regions)))))), \
PWM_MEM_REGION(idx)))))), \
())

#define PWM_GET_MEM_ATTR(idx) \
COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
(COND_CODE_1(DT_NODE_HAS_PROP(PWM_MEM_REGION(idx), zephyr_memory_attr), \
(DT_PROP(PWM_MEM_REGION(idx), zephyr_memory_attr)), (0))), (0))

#define PWM_NRFX_DEVICE(idx) \
NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(PWM(idx)); \
static struct pwm_nrfx_data pwm_nrfx_##idx##_data; \
Expand All @@ -362,6 +377,11 @@ static int pwm_nrfx_init(const struct device *dev)
.seq.values.p_raw = pwm_##idx##_seq_values, \
.seq.length = NRF_PWM_CHANNEL_COUNT, \
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(PWM(idx)), \
.clock_freq = COND_CODE_1(DT_CLOCKS_HAS_IDX(PWM(idx), 0), \
(DT_PROP(DT_CLOCKS_CTLR(PWM(idx)), clock_frequency)), \
(16ul * 1000ul * 1000ul)), \
IF_ENABLED(CONFIG_DCACHE, \
(.mem_attr = PWM_GET_MEM_ATTR(idx),)) \
}; \
static int pwm_nrfx_init##idx(const struct device *dev) \
{ \
Expand Down

0 comments on commit 0e8f376

Please sign in to comment.