1010#include <soc.h>
1111#include <hal/nrf_gpio.h>
1212#include <stdbool.h>
13+ #include <zephyr/linker/devicetree_regions.h>
1314
1415#include <zephyr/logging/log.h>
1516
@@ -45,7 +46,6 @@ struct pwm_nrfx_config {
4546
4647struct pwm_nrfx_data {
4748 uint32_t period_cycles ;
48- uint16_t seq_values [NRF_PWM_CHANNEL_COUNT ];
4949 /* Bit mask indicating channels that need the PWM generation. */
5050 uint8_t pwm_needed ;
5151 uint8_t prescaler ;
@@ -56,6 +56,12 @@ struct pwm_nrfx_data {
5656#error "Current implementation supports maximum 8 channels."
5757#endif
5858
59+ static uint16_t * seq_values_ptr_get (const struct device * dev )
60+ {
61+ const struct pwm_nrfx_config * config = dev -> config ;
62+
63+ return (uint16_t * )config -> seq .values .p_raw ;
64+ }
5965
6066static bool pwm_period_check_and_set (const struct device * dev ,
6167 uint32_t channel , uint32_t period_cycles )
@@ -164,7 +170,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
164170 needs_pwm = true;
165171 }
166172
167- data -> seq_values [channel ] = PWM_NRFX_CH_VALUE (compare_value , inverted );
173+ seq_values_ptr_get ( dev ) [channel ] = PWM_NRFX_CH_VALUE (compare_value , inverted );
168174
169175 LOG_DBG ("channel %u, pulse %u, period %u, prescaler: %u." ,
170176 channel , pulse_cycles , period_cycles , data -> prescaler );
@@ -249,7 +255,6 @@ static const struct pwm_driver_api pwm_nrfx_drv_api_funcs = {
249255static int pwm_nrfx_init (const struct device * dev )
250256{
251257 const struct pwm_nrfx_config * config = dev -> config ;
252- struct pwm_nrfx_data * data = dev -> data ;
253258 uint8_t initially_inverted = 0 ;
254259
255260 int ret = pinctrl_apply_state (config -> pcfg , PINCTRL_STATE_DEFAULT );
@@ -260,7 +265,7 @@ static int pwm_nrfx_init(const struct device *dev)
260265 return ret ;
261266 }
262267
263- for (size_t i = 0 ; i < ARRAY_SIZE ( data -> seq_values ) ; i ++ ) {
268+ for (size_t i = 0 ; i < NRF_PWM_CHANNEL_COUNT ; i ++ ) {
264269 uint32_t psel ;
265270
266271 if (channel_psel_get (i , & psel , config )) {
@@ -273,10 +278,10 @@ static int pwm_nrfx_init(const struct device *dev)
273278 }
274279 }
275280
276- for (size_t i = 0 ; i < ARRAY_SIZE ( data -> seq_values ) ; i ++ ) {
281+ for (size_t i = 0 ; i < NRF_PWM_CHANNEL_COUNT ; i ++ ) {
277282 bool inverted = initially_inverted & BIT (i );
278283
279- data -> seq_values [i ] = PWM_NRFX_CH_VALUE (0 , inverted );
284+ seq_values_ptr_get ( dev ) [i ] = PWM_NRFX_CH_VALUE (0 , inverted );
280285 }
281286
282287 nrfx_err_t result = nrfx_pwm_init (& config -> pwm ,
@@ -339,10 +344,19 @@ static int pwm_nrfx_pm_action(const struct device *dev,
339344
340345#define PWM (dev_idx ) DT_NODELABEL(pwm##dev_idx)
341346#define PWM_PROP (dev_idx , prop ) DT_PROP(PWM(dev_idx), prop)
347+ #define PWM_HAS_PROP (idx , prop ) DT_NODE_HAS_PROP(PWM(idx), prop)
348+
349+ #define PWM_MEMORY_SECTION (idx ) \
350+ COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
351+ (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
352+ DT_PHANDLE(PWM(idx), memory_regions)))))), \
353+ ())
342354
343355#define PWM_NRFX_DEVICE (idx ) \
344356 NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(PWM(idx)); \
345357 static struct pwm_nrfx_data pwm_nrfx_##idx##_data; \
358+ static uint16_t pwm_##idx##_seq_values[NRF_PWM_CHANNEL_COUNT] \
359+ PWM_MEMORY_SECTION(idx); \
346360 PINCTRL_DT_DEFINE(PWM(idx)); \
347361 static const struct pwm_nrfx_config pwm_nrfx_##idx##_config = { \
348362 .pwm = NRFX_PWM_INSTANCE(idx), \
@@ -357,7 +371,7 @@ static int pwm_nrfx_pm_action(const struct device *dev,
357371 .load_mode = NRF_PWM_LOAD_INDIVIDUAL, \
358372 .step_mode = NRF_PWM_STEP_TRIGGERED, \
359373 }, \
360- .seq.values.p_raw = pwm_nrfx_ ##idx##_data.seq_values, \
374+ .seq.values.p_raw = pwm_ ##idx##_seq_values, \
361375 .seq.length = NRF_PWM_CHANNEL_COUNT, \
362376 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PWM(idx)), \
363377 }; \
0 commit comments