@@ -303,22 +303,38 @@ void spi_frequency(spi_t *obj, int hz)
303
303
int spi_master_write (spi_t * obj , int value )
304
304
{
305
305
SPI_T * spi_base = (SPI_T * ) NU_MODBASE (obj -> spi .spi );
306
+ PinName spi_miso = obj -> spi .pin_miso ;
306
307
307
- // NOTE: Data in receive FIFO can be read out via ICE.
308
- // NOTE:
309
- // NUC472/M453/M487: SPI_CTL.SPIEN is controlled by software (in FIFO mode).
310
- // NANO130: SPI_CTL.GO_BUSY is controlled by hardware in FIFO mode.
311
308
SPI_ENABLE_SYNC (spi_base );
312
309
313
- // Wait for tx buffer empty
310
+ /* Wait for TX FIFO not full */
314
311
while (! spi_writeable (obj ));
315
312
uint32_t TX = (NU_MODSUBINDEX (obj -> spi .spi ) == 0 ) ? ((uint32_t ) & spi_base -> TX0 ) : ((uint32_t ) & spi_base -> TX1 );
316
313
M32 (TX ) = value ;
317
314
318
- // Wait for rx buffer full
319
- while (! spi_readable (obj ));
320
- uint32_t RX = (NU_MODSUBINDEX (obj -> spi .spi ) == 0 ) ? ((uint32_t ) & spi_base -> RX0 ) : ((uint32_t ) & spi_base -> RX1 );
321
- int value2 = M32 (RX );
315
+ /* Make inter-frame (SPI data frame) delay match configured suspend interval
316
+ * in no MISO case
317
+ *
318
+ * This API requires data write/read simultaneously. However, it can enlarge
319
+ * the inter-frame delay. The data flow for one call of this API would be:
320
+ * 1. Write data to TX FIFO when it is not full
321
+ * 2. Write delay consisting of TX FIFO to TX Shift Register...
322
+ * 3. Actual data transfer on SPI bus
323
+ * 4. Read delay consisting of RX FIFO from RX Shift Register...
324
+ * 5. Read data from RX FIFO when it is not empty
325
+ * Among above, S2&S4 contribute to the inter-frame delay.
326
+ *
327
+ * To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
328
+ * contribute to the inter-frame delay when data is written successively. The solution
329
+ * can cause RX FIFO overrun. Ignore it.
330
+ */
331
+ int value2 = -1 ;
332
+ if (spi_miso != NC ) {
333
+ /* Wait for RX FIFO not empty */
334
+ while (! spi_readable (obj ));
335
+ uint32_t RX = (NU_MODSUBINDEX (obj -> spi .spi ) == 0 ) ? ((uint32_t ) & spi_base -> RX0 ) : ((uint32_t ) & spi_base -> RX1 );
336
+ value2 = M32 (RX );
337
+ }
322
338
323
339
/* We don't call SPI_DISABLE_SYNC here for performance. */
324
340
0 commit comments