mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #12454 from OpenNuvoton/nuvoton_spi_no_miso
Nuvoton: Optimize spi_master_write(...) in case of no SPI MISO pinpull/12473/head
						commit
						043f68b9a7
					
				| 
						 | 
				
			
			@ -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