Skip to content

Commit 6db4425

Browse files
author
Marcus Chang
committed
Fix NRF52 SPI pin initialization
SPI pins are not initialized correctly according to the current SPI mode. This commit changes how the SPI instance is configured and ensures that: 1. SPI pins are initialized on each object initialization. 2. SPI pins are reinitialized on each mode or object change. 3. SPI instance is only initialized when a change has occured.
1 parent 5fcc961 commit 6db4425

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)