@@ -19,13 +19,16 @@ struct spi_nrfx_data {
1919 const struct device * dev ;
2020 size_t chunk_len ;
2121 bool busy ;
22+ bool initialized ;
2223};
2324
2425struct spi_nrfx_config {
2526 nrfx_spi_t spi ;
26- nrfx_spi_config_t config ;
27+ nrfx_spi_config_t def_config ;
2728};
2829
30+ static void event_handler (const nrfx_spi_evt_t * p_event , void * p_context );
31+
2932static inline struct spi_nrfx_data * get_dev_data (const struct device * dev )
3033{
3134 return dev -> data ;
@@ -86,17 +89,19 @@ static inline nrf_spi_bit_order_t get_nrf_spi_bit_order(uint16_t operation)
8689static int configure (const struct device * dev ,
8790 const struct spi_config * spi_cfg )
8891{
89- struct spi_context * ctx = & get_dev_data (dev )-> ctx ;
90- const nrfx_spi_t * spi = & get_dev_config (dev )-> spi ;
92+ struct spi_nrfx_data * dev_data = get_dev_data (dev );
93+ const struct spi_nrfx_config * dev_config = get_dev_config (dev );
94+ struct spi_context * ctx = & dev_data -> ctx ;
95+ nrfx_spi_config_t config ;
96+ nrfx_err_t result ;
9197
92- if (spi_context_configured (ctx , spi_cfg )) {
98+ if (dev_data -> initialized && spi_context_configured (ctx , spi_cfg )) {
9399 /* Already configured. No need to do it again. */
94100 return 0 ;
95101 }
96102
97103 if (SPI_OP_MODE_GET (spi_cfg -> operation ) != SPI_OP_MODE_MASTER ) {
98- LOG_ERR ("Slave mode is not supported on %s" ,
99- dev -> name );
104+ LOG_ERR ("Slave mode is not supported on %s" , dev -> name );
100105 return - EINVAL ;
101106 }
102107
@@ -111,8 +116,7 @@ static int configure(const struct device *dev,
111116 }
112117
113118 if (SPI_WORD_SIZE_GET (spi_cfg -> operation ) != 8 ) {
114- LOG_ERR ("Word sizes other than 8 bits"
115- " are not supported" );
119+ LOG_ERR ("Word sizes other than 8 bits are not supported" );
116120 return - EINVAL ;
117121 }
118122
@@ -121,15 +125,29 @@ static int configure(const struct device *dev,
121125 return - EINVAL ;
122126 }
123127
128+ config = dev_config -> def_config ;
129+
130+ config .frequency = get_nrf_spi_frequency (spi_cfg -> frequency );
131+ config .mode = get_nrf_spi_mode (spi_cfg -> operation );
132+ config .bit_order = get_nrf_spi_bit_order (spi_cfg -> operation );
133+
134+ if (dev_data -> initialized ) {
135+ nrfx_spi_uninit (& dev_config -> spi );
136+ dev_data -> initialized = false;
137+ }
138+
139+ result = nrfx_spi_init (& dev_config -> spi , & config ,
140+ event_handler , dev_data );
141+ if (result != NRFX_SUCCESS ) {
142+ LOG_ERR ("Failed to initialize nrfx driver: %08x" , result );
143+ return - EIO ;
144+ }
145+
146+ dev_data -> initialized = true;
147+
124148 ctx -> config = spi_cfg ;
125149 spi_context_cs_configure (ctx );
126150
127- nrf_spi_configure (spi -> p_reg ,
128- get_nrf_spi_mode (spi_cfg -> operation ),
129- get_nrf_spi_bit_order (spi_cfg -> operation ));
130- nrf_spi_frequency_set (spi -> p_reg ,
131- get_nrf_spi_frequency (spi_cfg -> frequency ));
132-
133151 return 0 ;
134152}
135153
@@ -167,6 +185,18 @@ static void transfer_next_chunk(const struct device *dev)
167185 dev_data -> busy = false;
168186}
169187
188+ static void event_handler (const nrfx_spi_evt_t * p_event , void * p_context )
189+ {
190+ struct spi_nrfx_data * dev_data = p_context ;
191+
192+ if (p_event -> type == NRFX_SPI_EVENT_DONE ) {
193+ spi_context_update_tx (& dev_data -> ctx , 1 , dev_data -> chunk_len );
194+ spi_context_update_rx (& dev_data -> ctx , 1 , dev_data -> chunk_len );
195+
196+ transfer_next_chunk (dev_data -> dev );
197+ }
198+ }
199+
170200static int transceive (const struct device * dev ,
171201 const struct spi_config * spi_cfg ,
172202 const struct spi_buf_set * tx_bufs ,
@@ -242,40 +272,6 @@ static const struct spi_driver_api spi_nrfx_driver_api = {
242272};
243273
244274
245- static void event_handler (const nrfx_spi_evt_t * p_event , void * p_context )
246- {
247- struct spi_nrfx_data * dev_data = p_context ;
248-
249- if (p_event -> type == NRFX_SPI_EVENT_DONE ) {
250- spi_context_update_tx (& dev_data -> ctx , 1 , dev_data -> chunk_len );
251- spi_context_update_rx (& dev_data -> ctx , 1 , dev_data -> chunk_len );
252-
253- transfer_next_chunk (dev_data -> dev );
254- }
255- }
256-
257- static int init_spi (const struct device * dev )
258- {
259- struct spi_nrfx_data * dev_data = get_dev_data (dev );
260- nrfx_err_t result ;
261-
262- dev_data -> dev = dev ;
263-
264- /* This sets only default values of frequency, mode and bit order.
265- * The proper ones are set in configure() when a transfer is started.
266- */
267- result = nrfx_spi_init (& get_dev_config (dev )-> spi ,
268- & get_dev_config (dev )-> config ,
269- event_handler ,
270- dev_data );
271- if (result != NRFX_SUCCESS ) {
272- LOG_ERR ("Failed to initialize device: %s" , dev -> name );
273- return - EBUSY ;
274- }
275-
276- return 0 ;
277- }
278-
279275#ifdef CONFIG_PM_DEVICE
280276static int spi_nrfx_pm_control (const struct device * dev ,
281277 enum pm_device_action action )
@@ -286,13 +282,14 @@ static int spi_nrfx_pm_control(const struct device *dev,
286282
287283 switch (action ) {
288284 case PM_DEVICE_ACTION_RESUME :
289- ret = init_spi ( dev );
290- /* Force reconfiguration before next transfer */
291- data -> ctx . config = NULL ;
285+ /* No action needed at this point, nrfx_spi_init() will be
286+ * called at configuration before the next transfer.
287+ */
292288 break ;
293289
294290 case PM_DEVICE_ACTION_SUSPEND :
295291 nrfx_spi_uninit (& config -> spi );
292+ data -> initialized = false;
296293 break ;
297294
298295 default :
@@ -332,26 +329,23 @@ static int spi_nrfx_pm_control(const struct device *dev,
332329 { \
333330 IRQ_CONNECT(DT_IRQN(SPI(idx)), DT_IRQ(SPI(idx), priority), \
334331 nrfx_isr, nrfx_spi_##idx##_irq_handler, 0); \
335- int err = init_spi(dev); \
336332 spi_context_unlock_unconditionally(&get_dev_data(dev)->ctx); \
337- return err ; \
333+ return 0 ; \
338334 } \
339335 static struct spi_nrfx_data spi_##idx##_data = { \
340336 SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx), \
341337 SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx), \
338+ .dev = DEVICE_DT_GET(SPI(idx)), \
342339 .busy = false, \
343340 }; \
344341 static const struct spi_nrfx_config spi_##idx##z_config = { \
345342 .spi = NRFX_SPI_INSTANCE(idx), \
346- .config = { \
343+ .def_config = { \
347344 .sck_pin = SPI_PROP(idx, sck_pin), \
348345 .mosi_pin = SPI_PROP(idx, mosi_pin), \
349346 .miso_pin = SPI_PROP(idx, miso_pin), \
350347 .ss_pin = NRFX_SPI_PIN_NOT_USED, \
351348 .orc = CONFIG_SPI_##idx##_NRF_ORC, \
352- .frequency = NRF_SPI_FREQ_4M, \
353- .mode = NRF_SPI_MODE_0, \
354- .bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \
355349 .miso_pull = SPI_NRFX_MISO_PULL(idx), \
356350 } \
357351 }; \
0 commit comments