Skip to content

Commit a858454

Browse files
authored
Merge pull request #6717 from marcuschangarm/fix-spi-pins
Fix NRF52 SPI pin initialization
2 parents beb8da9 + 6db4425 commit a858454

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/spi_api.c

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,10 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
156156
spi_inst->event = 0;
157157
#endif
158158

159-
/* Configuration has changed, set flag to force update. */
160-
spi_inst->update = true;
159+
/* Configure peripheral. This is called on each init to ensure all pins are set correctly
160+
* according to the SPI mode before calling CS for the first time.
161+
*/
162+
spi_configure_driver_instance(obj);
161163

162164
/* Configure GPIO pin if chip select has been set. */
163165
if (ssel != NC) {
@@ -223,19 +225,31 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
223225
struct spi_s *spi_inst = obj;
224226
#endif
225227

228+
nrf_drv_spi_mode_t new_mode = NRF_DRV_SPI_MODE_0;
229+
226230
/* Convert Mbed HAL mode to Nordic mode. */
227231
if(mode == 0) {
228-
spi_inst->config.mode = NRF_DRV_SPI_MODE_0;
232+
new_mode = NRF_DRV_SPI_MODE_0;
229233
} else if(mode == 1) {
230-
spi_inst->config.mode = NRF_DRV_SPI_MODE_1;
234+
new_mode = NRF_DRV_SPI_MODE_1;
231235
} else if(mode == 2) {
232-
spi_inst->config.mode = NRF_DRV_SPI_MODE_2;
236+
new_mode = NRF_DRV_SPI_MODE_2;
233237
} else if(mode == 3) {
234-
spi_inst->config.mode = NRF_DRV_SPI_MODE_3;
238+
new_mode = NRF_DRV_SPI_MODE_3;
235239
}
236240

237-
/* Configuration has changed, set flag to force application. */
238-
spi_inst->update = true;
241+
/* Check if configuration has changed. */
242+
if (spi_inst->config.mode != new_mode) {
243+
spi_inst->config.mode = new_mode;
244+
245+
/* Set flag to force update. */
246+
spi_inst->update = true;
247+
}
248+
249+
/* Configure peripheral if necessary. Must be called on each format to ensure the pins are set
250+
* correctly according to the SPI mode.
251+
*/
252+
spi_configure_driver_instance(obj);
239253
}
240254

241255
/** Set the SPI baud rate
@@ -253,25 +267,32 @@ void spi_frequency(spi_t *obj, int hz)
253267
struct spi_s *spi_inst = obj;
254268
#endif
255269

270+
nrf_drv_spi_frequency_t new_frequency = NRF_DRV_SPI_FREQ_1M;
271+
256272
/* Convert frequency to Nordic enum type. */
257273
if (hz < 250000) {
258-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_125K;
274+
new_frequency = NRF_DRV_SPI_FREQ_125K;
259275
} else if (hz < 500000) {
260-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_250K;
276+
new_frequency = NRF_DRV_SPI_FREQ_250K;
261277
} else if (hz < 1000000) {
262-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_500K;
278+
new_frequency = NRF_DRV_SPI_FREQ_500K;
263279
} else if (hz < 2000000) {
264-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_1M;
280+
new_frequency = NRF_DRV_SPI_FREQ_1M;
265281
} else if (hz < 4000000) {
266-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_2M;
282+
new_frequency = NRF_DRV_SPI_FREQ_2M;
267283
} else if (hz < 8000000) {
268-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_4M;
284+
new_frequency = NRF_DRV_SPI_FREQ_4M;
269285
} else {
270-
spi_inst->config.frequency = NRF_DRV_SPI_FREQ_8M;
286+
new_frequency = NRF_DRV_SPI_FREQ_8M;
271287
}
272288

273-
/* Configuration has changed, set flag to force application. */
274-
spi_inst->update = true;
289+
/* Check if configuration has changed. */
290+
if (spi_inst->config.frequency != new_frequency) {
291+
spi_inst->config.frequency = new_frequency;
292+
293+
/* Set flag to force update. */
294+
spi_inst->update = true;
295+
}
275296
}
276297

277298
/** Write a byte out in master mode and receive a value
@@ -290,18 +311,18 @@ int spi_master_write(spi_t *obj, int value)
290311

291312
int instance = spi_inst->instance;
292313

293-
/* Manually clear chip select pin if defined. */
294-
if (spi_inst->cs != NC) {
295-
nrf_gpio_pin_clear(spi_inst->cs);
296-
}
297-
298314
/* Local variables used in transfer. */
299315
const uint8_t tx_buff = (uint8_t) value;
300316
uint8_t rx_buff;
301317

302318
/* Configure peripheral if necessary. */
303319
spi_configure_driver_instance(obj);
304320

321+
/* Manually clear chip select pin if defined. */
322+
if (spi_inst->cs != NC) {
323+
nrf_gpio_pin_clear(spi_inst->cs);
324+
}
325+
305326
/* Transfer 1 byte. */
306327
nrf_drv_spi_transfer(&nordic_nrf5_spi_instance[instance], &tx_buff, 1, &rx_buff, 1);
307328

0 commit comments

Comments
 (0)