Skip to content

Commit 2a199af

Browse files
ananglnashif
authored andcommitted
drivers: spi_nrfx_spim: Change the way the nrfx driver is configured
According to the nRF5340 PS, for 32 Mbps high-speed SPI using SPIM4, drive configuration H0H1 must be used. The underlying nrfx_spim driver does it properly in its initialization function, so change the shim to (re)initialize the driver when the SPI configuration is to be changed (only then the speed to use is known), to avoid the need of duplicating the corresponding code in the shim itself. Signed-off-by: Andrzej Głąbek <[email protected]>
1 parent 5f1581b commit 2a199af

File tree

1 file changed

+57
-66
lines changed

1 file changed

+57
-66
lines changed

drivers/spi/spi_nrfx_spim.c

Lines changed: 57 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,23 @@ LOG_MODULE_REGISTER(spi_nrfx_spim);
1919
struct spi_nrfx_data {
2020
struct spi_context ctx;
2121
const struct device *dev;
22-
size_t chunk_len;
23-
bool busy;
22+
size_t chunk_len;
23+
bool busy;
24+
bool initialized;
2425
#if (CONFIG_SPI_NRFX_RAM_BUFFER_SIZE > 0)
25-
uint8_t buffer[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE];
26+
uint8_t buffer[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE];
2627
#endif
2728
};
2829

2930
struct spi_nrfx_config {
3031
nrfx_spim_t spim;
3132
size_t max_chunk_len;
3233
uint32_t max_freq;
33-
nrfx_spim_config_t config;
34+
nrfx_spim_config_t def_config;
3435
};
3536

37+
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
38+
3639
static inline struct spi_nrfx_data *get_dev_data(const struct device *dev)
3740
{
3841
return dev->data;
@@ -105,20 +108,20 @@ static inline nrf_spim_bit_order_t get_nrf_spim_bit_order(uint16_t operation)
105108
static int configure(const struct device *dev,
106109
const struct spi_config *spi_cfg)
107110
{
111+
struct spi_nrfx_data *dev_data = get_dev_data(dev);
108112
const struct spi_nrfx_config *dev_config = get_dev_config(dev);
109-
struct spi_context *ctx = &get_dev_data(dev)->ctx;
110-
const nrfx_spim_t *spim = &dev_config->spim;
113+
struct spi_context *ctx = &dev_data->ctx;
111114
uint32_t max_freq = dev_config->max_freq;
112-
nrf_spim_frequency_t spim_frequency;
115+
nrfx_spim_config_t config;
116+
nrfx_err_t result;
113117

114-
if (spi_context_configured(ctx, spi_cfg)) {
118+
if (dev_data->initialized && spi_context_configured(ctx, spi_cfg)) {
115119
/* Already configured. No need to do it again. */
116120
return 0;
117121
}
118122

119123
if (SPI_OP_MODE_GET(spi_cfg->operation) != SPI_OP_MODE_MASTER) {
120-
LOG_ERR("Slave mode is not supported on %s",
121-
dev->name);
124+
LOG_ERR("Slave mode is not supported on %s", dev->name);
122125
return -EINVAL;
123126
}
124127

@@ -133,8 +136,7 @@ static int configure(const struct device *dev,
133136
}
134137

135138
if (SPI_WORD_SIZE_GET(spi_cfg->operation) != 8) {
136-
LOG_ERR("Word sizes other than 8 bits"
137-
" are not supported");
139+
LOG_ERR("Word sizes other than 8 bits are not supported");
138140
return -EINVAL;
139141
}
140142

@@ -143,9 +145,6 @@ static int configure(const struct device *dev,
143145
return -EINVAL;
144146
}
145147

146-
ctx->config = spi_cfg;
147-
spi_context_cs_configure(ctx);
148-
149148
#if defined(CONFIG_SOC_NRF5340_CPUAPP)
150149
/* On nRF5340, the 32 Mbps speed is supported by the application core
151150
* when it is running at 128 MHz (see the Timing specifications section
@@ -156,14 +155,31 @@ static int configure(const struct device *dev,
156155
max_freq = 16000000;
157156
}
158157
#endif
159-
/* Limit the frequency to that supported by the SPIM instance */
160-
spim_frequency = get_nrf_spim_frequency(MIN(spi_cfg->frequency,
161-
max_freq));
162158

163-
nrf_spim_configure(spim->p_reg,
164-
get_nrf_spim_mode(spi_cfg->operation),
165-
get_nrf_spim_bit_order(spi_cfg->operation));
166-
nrf_spim_frequency_set(spim->p_reg, spim_frequency);
159+
config = dev_config->def_config;
160+
161+
/* Limit the frequency to that supported by the SPIM instance. */
162+
config.frequency = get_nrf_spim_frequency(MIN(spi_cfg->frequency,
163+
max_freq));
164+
config.mode = get_nrf_spim_mode(spi_cfg->operation);
165+
config.bit_order = get_nrf_spim_bit_order(spi_cfg->operation);
166+
167+
if (dev_data->initialized) {
168+
nrfx_spim_uninit(&dev_config->spim);
169+
dev_data->initialized = false;
170+
}
171+
172+
result = nrfx_spim_init(&dev_config->spim, &config,
173+
event_handler, dev_data);
174+
if (result != NRFX_SUCCESS) {
175+
LOG_ERR("Failed to initialize nrfx driver: %08x", result);
176+
return -EIO;
177+
}
178+
179+
dev_data->initialized = true;
180+
181+
ctx->config = spi_cfg;
182+
spi_context_cs_configure(ctx);
167183

168184
return 0;
169185
}
@@ -227,6 +243,18 @@ static void transfer_next_chunk(const struct device *dev)
227243
dev_data->busy = false;
228244
}
229245

246+
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
247+
{
248+
struct spi_nrfx_data *dev_data = p_context;
249+
250+
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
251+
spi_context_update_tx(&dev_data->ctx, 1, dev_data->chunk_len);
252+
spi_context_update_rx(&dev_data->ctx, 1, dev_data->chunk_len);
253+
254+
transfer_next_chunk(dev_data->dev);
255+
}
256+
}
257+
230258
static int transceive(const struct device *dev,
231259
const struct spi_config *spi_cfg,
232260
const struct spi_buf_set *tx_bufs,
@@ -301,41 +329,6 @@ static const struct spi_driver_api spi_nrfx_driver_api = {
301329
.release = spi_nrfx_release,
302330
};
303331

304-
305-
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
306-
{
307-
struct spi_nrfx_data *dev_data = p_context;
308-
309-
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
310-
spi_context_update_tx(&dev_data->ctx, 1, dev_data->chunk_len);
311-
spi_context_update_rx(&dev_data->ctx, 1, dev_data->chunk_len);
312-
313-
transfer_next_chunk(dev_data->dev);
314-
}
315-
}
316-
317-
static int init_spim(const struct device *dev)
318-
{
319-
struct spi_nrfx_data *data = get_dev_data(dev);
320-
nrfx_err_t result;
321-
322-
data->dev = dev;
323-
324-
/* This sets only default values of frequency, mode and bit order.
325-
* The proper ones are set in configure() when a transfer is started.
326-
*/
327-
result = nrfx_spim_init(&get_dev_config(dev)->spim,
328-
&get_dev_config(dev)->config,
329-
event_handler,
330-
data);
331-
if (result != NRFX_SUCCESS) {
332-
LOG_ERR("Failed to initialize device: %s", dev->name);
333-
return -EBUSY;
334-
}
335-
336-
return 0;
337-
}
338-
339332
#ifdef CONFIG_PM_DEVICE
340333
static int spim_nrfx_pm_control(const struct device *dev,
341334
enum pm_device_action action)
@@ -346,13 +339,14 @@ static int spim_nrfx_pm_control(const struct device *dev,
346339

347340
switch (action) {
348341
case PM_DEVICE_ACTION_RESUME:
349-
ret = init_spim(dev);
350-
/* Force reconfiguration before next transfer */
351-
data->ctx.config = NULL;
342+
/* No action needed at this point, nrfx_spim_init() will be
343+
* called at configuration before the next transfer.
344+
*/
352345
break;
353346

354347
case PM_DEVICE_ACTION_SUSPEND:
355348
nrfx_spim_uninit(&config->spim);
349+
data->initialized = false;
356350
break;
357351

358352
default:
@@ -401,28 +395,25 @@ static int spim_nrfx_pm_control(const struct device *dev,
401395
IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIM##idx), \
402396
DT_IRQ(SPIM(idx), priority), \
403397
nrfx_isr, nrfx_spim_##idx##_irq_handler, 0); \
404-
int err = init_spim(dev); \
405398
spi_context_unlock_unconditionally(&get_dev_data(dev)->ctx); \
406-
return err; \
399+
return 0; \
407400
} \
408401
static struct spi_nrfx_data spi_##idx##_data = { \
409402
SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx), \
410403
SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx), \
404+
.dev = DEVICE_DT_GET(SPIM(idx)), \
411405
.busy = false, \
412406
}; \
413407
static const struct spi_nrfx_config spi_##idx##z_config = { \
414408
.spim = NRFX_SPIM_INSTANCE(idx), \
415409
.max_chunk_len = (1 << SPIM##idx##_EASYDMA_MAXCNT_SIZE) - 1, \
416410
.max_freq = SPIM##idx##_MAX_DATARATE * 1000000, \
417-
.config = { \
411+
.def_config = { \
418412
.sck_pin = SPIM_PROP(idx, sck_pin), \
419413
.mosi_pin = SPIM_PROP(idx, mosi_pin), \
420414
.miso_pin = SPIM_PROP(idx, miso_pin), \
421415
.ss_pin = NRFX_SPIM_PIN_NOT_USED, \
422416
.orc = CONFIG_SPI_##idx##_NRF_ORC, \
423-
.frequency = NRF_SPIM_FREQ_4M, \
424-
.mode = NRF_SPIM_MODE_0, \
425-
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, \
426417
.miso_pull = SPIM_NRFX_MISO_PULL(idx), \
427418
SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \
428419
} \

0 commit comments

Comments
 (0)