mirror of https://github.com/ARMmbed/mbed-os.git
Nuvoton: Make SPI inter-frame (delay match configured suspend interval
In no MISO case, skip SPI read so that no more write/read delay contribute to SPI inter-frame delay when data is written successively. Update targets: - NUMAKER_PFM_NANO130 - NUMAKER_PFM_NUC472 - NUMAKER_PFM_M453 - NUMAKER_PFM_M487/NUMAKER_IOT_M487 - NU_PFM_M2351_* - NUMAKER_IOT_M263A - NUMAKER_M252KGpull/12454/head
parent
3d038e55ee
commit
8df96ec50a
|
@ -285,17 +285,36 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
SPI_WRITE_TX(spi_base, value);
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
int value2 = SPI_READ_RX(spi_base);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
value2 = SPI_READ_RX(spi_base);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
|
@ -243,17 +243,36 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
SPI_WRITE_TX(spi_base, value);
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
int value2 = SPI_READ_RX(spi_base);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
value2 = SPI_READ_RX(spi_base);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
|
@ -264,17 +264,36 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
SPI_WRITE_TX(spi_base, value);
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
int value2 = SPI_READ_RX(spi_base);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
value2 = SPI_READ_RX(spi_base);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
|
@ -257,17 +257,36 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
SPI_WRITE_TX(spi_base, value);
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
int value2 = SPI_READ_RX(spi_base);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
value2 = SPI_READ_RX(spi_base);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
|
@ -270,17 +270,36 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
SPI_WRITE_TX(spi_base, value);
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
int value2 = SPI_READ_RX(spi_base);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
value2 = SPI_READ_RX(spi_base);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
|
@ -303,22 +303,38 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
// NOTE:
|
||||
// NUC472/M453/M487: SPI_CTL.SPIEN is controlled by software (in FIFO mode).
|
||||
// NANO130: SPI_CTL.GO_BUSY is controlled by hardware in FIFO mode.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
uint32_t TX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->TX0) : ((uint32_t) &spi_base->TX1);
|
||||
M32(TX) = value;
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
uint32_t RX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->RX0) : ((uint32_t) &spi_base->RX1);
|
||||
int value2 = M32(RX);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
uint32_t RX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->RX0) : ((uint32_t) &spi_base->RX1);
|
||||
value2 = M32(RX);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
|
@ -263,17 +263,36 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
int spi_master_write(spi_t *obj, int value)
|
||||
{
|
||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||
PinName spi_miso = obj->spi.pin_miso;
|
||||
|
||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||
SPI_ENABLE_SYNC(spi_base);
|
||||
|
||||
// Wait for tx buffer empty
|
||||
/* Wait for TX FIFO not full */
|
||||
while(! spi_writeable(obj));
|
||||
SPI_WRITE_TX(spi_base, value);
|
||||
|
||||
// Wait for rx buffer full
|
||||
while (! spi_readable(obj));
|
||||
int value2 = SPI_READ_RX(spi_base);
|
||||
/* Make inter-frame (SPI data frame) delay match configured suspend interval
|
||||
* in no MISO case
|
||||
*
|
||||
* This API requires data write/read simultaneously. However, it can enlarge
|
||||
* the inter-frame delay. The data flow for one call of this API would be:
|
||||
* 1. Write data to TX FIFO when it is not full
|
||||
* 2. Write delay consisting of TX FIFO to TX Shift Register...
|
||||
* 3. Actual data transfer on SPI bus
|
||||
* 4. Read delay consisting of RX FIFO from RX Shift Register...
|
||||
* 5. Read data from RX FIFO when it is not empty
|
||||
* Among above, S2&S4 contribute to the inter-frame delay.
|
||||
*
|
||||
* To favor no MISO case, we skip S4&S5. Thus, S2 can overlap with S3 and doesn't
|
||||
* contribute to the inter-frame delay when data is written successively. The solution
|
||||
* can cause RX FIFO overrun. Ignore it.
|
||||
*/
|
||||
int value2 = -1;
|
||||
if (spi_miso != NC) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
while (! spi_readable(obj));
|
||||
value2 = SPI_READ_RX(spi_base);
|
||||
}
|
||||
|
||||
/* We don't call SPI_DISABLE_SYNC here for performance. */
|
||||
|
||||
|
|
Loading…
Reference in New Issue