Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrf fromtree] Add functional PWM support for nRF54H20 #1671

Merged
merged 4 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ ram: 256
flash: 512
supported:
- gpio
- pwm
1 change: 1 addition & 0 deletions boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ ram: 62
flash: 62
supported:
- gpio
- pwm
1 change: 1 addition & 0 deletions boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ ram: 192
flash: 256
supported:
- gpio
- pwm
28 changes: 21 additions & 7 deletions drivers/pwm/pwm_nrfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <soc.h>
#include <hal/nrf_gpio.h>
#include <stdbool.h>
#include <zephyr/linker/devicetree_regions.h>

#include <zephyr/logging/log.h>

Expand Down Expand Up @@ -45,7 +46,6 @@ struct pwm_nrfx_config {

struct pwm_nrfx_data {
uint32_t period_cycles;
uint16_t seq_values[NRF_PWM_CHANNEL_COUNT];
/* Bit mask indicating channels that need the PWM generation. */
uint8_t pwm_needed;
uint8_t prescaler;
Expand All @@ -56,6 +56,12 @@ struct pwm_nrfx_data {
#error "Current implementation supports maximum 8 channels."
#endif

static uint16_t *seq_values_ptr_get(const struct device *dev)
{
const struct pwm_nrfx_config *config = dev->config;

return (uint16_t *)config->seq.values.p_raw;
}

static bool pwm_period_check_and_set(const struct device *dev,
uint32_t channel, uint32_t period_cycles)
Expand Down Expand Up @@ -164,7 +170,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
needs_pwm = true;
}

data->seq_values[channel] = PWM_NRFX_CH_VALUE(compare_value, inverted);
seq_values_ptr_get(dev)[channel] = PWM_NRFX_CH_VALUE(compare_value, inverted);

LOG_DBG("channel %u, pulse %u, period %u, prescaler: %u.",
channel, pulse_cycles, period_cycles, data->prescaler);
Expand Down Expand Up @@ -249,7 +255,6 @@ static const struct pwm_driver_api pwm_nrfx_drv_api_funcs = {
static int pwm_nrfx_init(const struct device *dev)
{
const struct pwm_nrfx_config *config = dev->config;
struct pwm_nrfx_data *data = dev->data;
uint8_t initially_inverted = 0;

int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
Expand All @@ -260,7 +265,7 @@ static int pwm_nrfx_init(const struct device *dev)
return ret;
}

for (size_t i = 0; i < ARRAY_SIZE(data->seq_values); i++) {
for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
uint32_t psel;

if (channel_psel_get(i, &psel, config)) {
Expand All @@ -273,10 +278,10 @@ static int pwm_nrfx_init(const struct device *dev)
}
}

for (size_t i = 0; i < ARRAY_SIZE(data->seq_values); i++) {
for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
bool inverted = initially_inverted & BIT(i);

data->seq_values[i] = PWM_NRFX_CH_VALUE(0, inverted);
seq_values_ptr_get(dev)[i] = PWM_NRFX_CH_VALUE(0, inverted);
}

nrfx_err_t result = nrfx_pwm_init(&config->pwm,
Expand Down Expand Up @@ -339,10 +344,19 @@ static int pwm_nrfx_pm_action(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_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)))))), \
())

#define PWM_NRFX_DEVICE(idx) \
NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(PWM(idx)); \
static struct pwm_nrfx_data pwm_nrfx_##idx##_data; \
static uint16_t pwm_##idx##_seq_values[NRF_PWM_CHANNEL_COUNT] \
PWM_MEMORY_SECTION(idx); \
PINCTRL_DT_DEFINE(PWM(idx)); \
static const struct pwm_nrfx_config pwm_nrfx_##idx##_config = { \
.pwm = NRFX_PWM_INSTANCE(idx), \
Expand All @@ -357,7 +371,7 @@ static int pwm_nrfx_pm_action(const struct device *dev,
.load_mode = NRF_PWM_LOAD_INDIVIDUAL, \
.step_mode = NRF_PWM_STEP_TRIGGERED, \
}, \
.seq.values.p_raw = pwm_nrfx_##idx##_data.seq_values, \
.seq.values.p_raw = pwm_##idx##_seq_values, \
.seq.length = NRF_PWM_CHANNEL_COUNT, \
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(PWM(idx)), \
}; \
Expand Down
2 changes: 1 addition & 1 deletion dts/bindings/pwm/nordic,nrf-pwm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ description: nRF PWM

compatible: "nordic,nrf-pwm"

include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml]
include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml, memory-region.yaml]

properties:
reg:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
pinctrl-0 = <&pwm_default>;
pinctrl-1 = <&pwm_sleep>;
pinctrl-names = "default", "sleep";
memory-regions = <&cpuapp_dma_region>;
};
Loading