@@ -303,22 +303,38 @@ void spi_frequency(spi_t *obj, int hz)
303303int spi_master_write (spi_t * obj , int value )
304304{
305305 SPI_T * spi_base = (SPI_T * ) NU_MODBASE (obj -> spi .spi );
306+ PinName spi_miso = obj -> spi .pin_miso ;
306307
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.
311308 SPI_ENABLE_SYNC (spi_base );
312309
313- // Wait for tx buffer empty
310+ /* Wait for TX FIFO not full */
314311 while (! spi_writeable (obj ));
315312 uint32_t TX = (NU_MODSUBINDEX (obj -> spi .spi ) == 0 ) ? ((uint32_t ) & spi_base -> TX0 ) : ((uint32_t ) & spi_base -> TX1 );
316313 M32 (TX ) = value ;
317314
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+ }
322338
323339 /* We don't call SPI_DISABLE_SYNC here for performance. */
324340
0 commit comments