[Nuvoton] Introduce SPI_ENABLE_SYNC/SPI_DISABLE_SYNC to simplify enable/disable control

pull/6466/head
ccli8 2018-03-26 10:34:22 +08:00
parent f6bcbfe1f0
commit 643d772cf9
4 changed files with 176 additions and 93 deletions

View File

@ -60,6 +60,34 @@ static struct nu_spi_var spi2_var = {
#endif
};
/* Synchronous version of SPI_ENABLE()/SPI_DISABLE() macros
*
* The SPI peripheral clock is asynchronous with the system clock. In order to make sure the SPI
* control logic is enabled/disabled, this bit indicates the real status of SPI controller.
*
* NOTE: All configurations shall be ready before calling SPI_ENABLE_SYNC().
* NOTE: Before changing the configurations of SPIx_CTL, SPIx_CLKDIV, SPIx_SSCTL and SPIx_FIFOCTL registers,
* user shall clear the SPIEN (SPIx_CTL[0]) and confirm the SPIENSTS (SPIx_STATUS[15]) is 0
* (by SPI_DISABLE_SYNC here).
*/
__STATIC_INLINE void SPI_ENABLE_SYNC(SPI_T *spi_base)
{
if (! (spi_base->CTL & SPI_CTL_SPIEN_Msk)) {
SPI_ENABLE(spi_base);
}
while (! (spi_base->STATUS & SPI_STATUS_SPIENSTS_Msk));
}
__STATIC_INLINE void SPI_DISABLE_SYNC(SPI_T *spi_base)
{
if (spi_base->CTL & SPI_CTL_SPIEN_Msk) {
// NOTE: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
}
while (spi_base->STATUS & SPI_STATUS_SPIENSTS_Msk);
}
#if DEVICE_SPI_ASYNCH
static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t enable);
static void spi_master_enable_interrupt(spi_t *obj, uint8_t enable);
@ -177,10 +205,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE 1: All configurations should be ready before enabling SPI peripheral.
// NOTE 2: Re-configuration is allowed only as SPI peripheral is idle.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
SPI_Open(spi_base,
slave ? SPI_SLAVE : SPI_MASTER,
@ -207,15 +232,14 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
}
// NOTE: M451's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk). This will violate judgement of spi_active(). Disable it.
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
}
void spi_frequency(spi_t *obj, int hz)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
}
@ -226,7 +250,7 @@ int spi_master_write(spi_t *obj, int value)
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE: Data in receive FIFO can be read out via ICE.
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for tx buffer empty
while(! spi_writeable(obj));
@ -236,7 +260,7 @@ int spi_master_write(spi_t *obj, int value)
while (! spi_readable(obj));
int value2 = SPI_READ_RX(spi_base);
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
return value2;
}
@ -261,7 +285,7 @@ int spi_slave_receive(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
return spi_readable(obj);
};
@ -270,7 +294,7 @@ int spi_slave_read(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for rx buffer full
while (! spi_readable(obj));
@ -282,7 +306,7 @@ void spi_slave_write(spi_t *obj, int value)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for tx buffer empty
while(! spi_writeable(obj));
@ -316,7 +340,7 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
spi_enable_event(obj, event, 1);
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
@ -426,9 +450,8 @@ void spi_abort_asynch(spi_t *obj)
spi_enable_vector_interrupt(obj, 0, 0);
spi_master_enable_interrupt(obj, 0);
// FIXME: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
/* Necessary for accessing FIFOCTL below */
SPI_DISABLE_SYNC(spi_base);
SPI_ClearRxFIFO(spi_base);
SPI_ClearTxFIFO(spi_base);

View File

@ -71,6 +71,34 @@ static struct nu_spi_var spi4_var = {
#endif
};
/* Synchronous version of SPI_ENABLE()/SPI_DISABLE() macros
*
* The SPI peripheral clock is asynchronous with the system clock. In order to make sure the SPI
* control logic is enabled/disabled, this bit indicates the real status of SPI controller.
*
* NOTE: All configurations shall be ready before calling SPI_ENABLE_SYNC().
* NOTE: Before changing the configurations of SPIx_CTL, SPIx_CLKDIV, SPIx_SSCTL and SPIx_FIFOCTL registers,
* user shall clear the SPIEN (SPIx_CTL[0]) and confirm the SPIENSTS (SPIx_STATUS[15]) is 0
* (by SPI_DISABLE_SYNC here).
*/
__STATIC_INLINE void SPI_ENABLE_SYNC(SPI_T *spi_base)
{
if (! (spi_base->CTL & SPI_CTL_SPIEN_Msk)) {
SPI_ENABLE(spi_base);
}
while (! (spi_base->STATUS & SPI_STATUS_SPIENSTS_Msk));
}
__STATIC_INLINE void SPI_DISABLE_SYNC(SPI_T *spi_base)
{
if (spi_base->CTL & SPI_CTL_SPIEN_Msk) {
// NOTE: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
}
while (spi_base->STATUS & SPI_STATUS_SPIENSTS_Msk);
}
#if DEVICE_SPI_ASYNCH
static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t enable);
static void spi_master_enable_interrupt(spi_t *obj, uint8_t enable);
@ -184,10 +212,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE 1: All configurations should be ready before enabling SPI peripheral.
// NOTE 2: Re-configuration is allowed only as SPI peripheral is idle.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
SPI_Open(spi_base,
slave ? SPI_SLAVE : SPI_MASTER,
@ -212,15 +237,14 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
}
// NOTE: M451's/M480's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk). This will violate judgement of spi_active(). Disable it.
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
}
void spi_frequency(spi_t *obj, int hz)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
}
@ -231,7 +255,7 @@ int spi_master_write(spi_t *obj, int value)
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE: Data in receive FIFO can be read out via ICE.
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for tx buffer empty
while(! spi_writeable(obj));
@ -241,7 +265,7 @@ int spi_master_write(spi_t *obj, int value)
while (! spi_readable(obj));
int value2 = SPI_READ_RX(spi_base);
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
return value2;
}
@ -266,7 +290,7 @@ int spi_slave_receive(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
return spi_readable(obj);
};
@ -275,7 +299,7 @@ int spi_slave_read(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for rx buffer full
while (! spi_readable(obj));
@ -287,7 +311,7 @@ void spi_slave_write(spi_t *obj, int value)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for tx buffer empty
while(! spi_writeable(obj));
@ -320,7 +344,7 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
spi_enable_event(obj, event, 1);
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
@ -428,9 +452,8 @@ void spi_abort_asynch(spi_t *obj)
spi_enable_vector_interrupt(obj, 0, 0);
spi_master_enable_interrupt(obj, 0);
// NOTE: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
/* Necessary for accessing FIFOCTL below */
SPI_DISABLE_SYNC(spi_base);
SPI_ClearRxFIFO(spi_base);
SPI_ClearTxFIFO(spi_base);

View File

@ -75,6 +75,38 @@ static struct nu_spi_var spi2_var = {
#endif
};
/* Synchronous version of SPI_ENABLE()/SPI_DISABLE() macros
*
* The SPI peripheral clock is asynchronous with the system clock. In order to make sure the SPI
* control logic is enabled/disabled, this bit indicates the real status of SPI controller.
*
* NOTE: All configurations shall be ready before calling SPI_ENABLE_SYNC().
* NOTE: Before changing the configurations of SPIx_CTL, SPIx_CLKDIV, SPIx_SSCTL and SPIx_FIFOCTL registers,
* user shall clear the SPIEN (SPIx_CTL[0]) and confirm the SPIENSTS (SPIx_STATUS[15]) is 0
* (by SPI_DISABLE_SYNC here).
*
* NOTE:
* 1. NUC472/M453/M487: SPI_CTL.SPIEN is controlled by software (in FIFO mode).
* 2. NANO130: SPI_CTL.GO_BUSY is controlled by hardware in FIFO mode.
*/
__STATIC_INLINE void SPI_ENABLE_SYNC(SPI_T *spi_base)
{
/* NOTE: On NANO130, FIFO mode defaults to disabled. */
if (! (spi_base->CTL & SPI_CTL_FIFOM_Msk)) {
SPI_EnableFIFO(spi_base, NU_SPI_FIFO_DEPTH / 2, NU_SPI_FIFO_DEPTH / 2);
}
}
__STATIC_INLINE void SPI_DISABLE_SYNC(SPI_T *spi_base)
{
/* NOTE: On NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave/FIFO mode. So disable FIFO first. */
if (spi_base->CTL & SPI_CTL_FIFOM_Msk) {
SPI_DisableFIFO(spi_base);
}
/* NOTE: SPI H/W may get out of state without the busy check */
while (SPI_IS_BUSY(spi_base));
}
#if DEVICE_SPI_ASYNCH
static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t enable);
static void spi_master_enable_interrupt(spi_t *obj, uint8_t enable, uint32_t mask);
@ -191,13 +223,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE: All configurations should be ready before enabling SPI peripheral.
// NOTE: Re-configuration is allowed only as SPI peripheral is idle.
// NOTE:
// NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave/FIFO mode. So disable FIFO first.
SPI_DisableFIFO(spi_base);
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE_SYNC(spi_base);
SPI_Open(spi_base,
slave ? SPI_SLAVE : SPI_MASTER,
@ -240,25 +266,15 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
// NANO130: Configure slave select signal to edge-trigger rather than level-trigger
spi_base->SSR |= SPI_SSR_SS_LTRIG_Msk;
}
// NOTE:
// NANO130: FIFO mode defaults to disabled.
SPI_EnableFIFO(spi_base, NU_SPI_FIFO_DEPTH / 2, NU_SPI_FIFO_DEPTH / 2);
}
void spi_frequency(spi_t *obj, int hz)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave/FIFO mode. So disable FIFO first.
SPI_DisableFIFO(spi_base);
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE_SYNC(spi_base);
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
// NOTE:
// NANO130: FIFO mode defaults to disabled.
SPI_EnableFIFO(spi_base, NU_SPI_FIFO_DEPTH / 2, NU_SPI_FIFO_DEPTH / 2);
}
@ -270,7 +286,8 @@ int spi_master_write(spi_t *obj, int value)
// 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
while(! spi_writeable(obj));
uint32_t TX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->TX0) : ((uint32_t) &spi_base->TX1);
@ -303,21 +320,19 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
#if DEVICE_SPISLAVE
int spi_slave_receive(spi_t *obj)
{
// 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_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE_SYNC(spi_base);
return spi_readable(obj);
};
int spi_slave_read(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// 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 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);
@ -328,11 +343,9 @@ int spi_slave_read(spi_t *obj)
void spi_slave_write(spi_t *obj, int value)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// 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
while(! spi_writeable(obj));
uint32_t TX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->TX0) : ((uint32_t) &spi_base->TX1);
@ -364,11 +377,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
// SPI IRQ is necessary for both interrupt way and DMA way
spi_enable_event(obj, event, 1);
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
// 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);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@ -473,9 +484,9 @@ void spi_abort_asynch(spi_t *obj)
spi_enable_vector_interrupt(obj, 0, 0);
spi_master_enable_interrupt(obj, 0, SPI_FIFO_RX_INTEN_MASK | SPI_FIFO_TX_INTEN_MASK);
// NOTE: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
/* Necessary for accessing FIFOCTL below */
SPI_DISABLE_SYNC(spi_base);
SPI_ClearRxFIFO(spi_base);
SPI_ClearTxFIFO(spi_base);
}

View File

@ -66,6 +66,34 @@ static struct nu_spi_var spi3_var = {
#endif
};
/* Synchronous version of SPI_ENABLE()/SPI_DISABLE() macros
*
* The SPI peripheral clock is asynchronous with the system clock. In order to make sure the SPI
* control logic is enabled/disabled, this bit indicates the real status of SPI controller.
*
* NOTE: All configurations shall be ready before calling SPI_ENABLE_SYNC().
* NOTE: Before changing the configurations of SPIx_CTL, SPIx_CLKDIV, SPIx_SSCTL and SPIx_FIFOCTL registers,
* user shall clear the SPIEN (SPIx_CTL[0]) and confirm the SPIENSTS (SPIx_STATUS[15]) is 0
* (by SPI_DISABLE_SYNC here).
*/
__STATIC_INLINE void SPI_ENABLE_SYNC(SPI_T *spi_base)
{
if (! (spi_base->CTL & SPI_CTL_SPIEN_Msk)) {
SPI_ENABLE(spi_base);
}
while (! (spi_base->STATUS & SPI_STATUS_SPIENSTS_Msk));
}
__STATIC_INLINE void SPI_DISABLE_SYNC(SPI_T *spi_base)
{
if (spi_base->CTL & SPI_CTL_SPIEN_Msk) {
// NOTE: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
}
while (spi_base->STATUS & SPI_STATUS_SPIENSTS_Msk);
}
#if DEVICE_SPI_ASYNCH
static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t enable);
static void spi_master_enable_interrupt(spi_t *obj, uint8_t enable);
@ -180,12 +208,9 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
MBED_ASSERT(bits >= NU_SPI_FRAME_MIN && bits <= NU_SPI_FRAME_MAX);
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE 1: All configurations should be ready before enabling SPI peripheral.
// NOTE 2: Re-configuration is allowed only as SPI peripheral is idle.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
SPI_Open(spi_base,
slave ? SPI_SLAVE : SPI_MASTER,
(mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3,
@ -211,15 +236,17 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
spi_base->SSCTL &= ~SPI_SSCTL_SSACTPOL_Msk;
// NOTE: SPI_SS0 is defined as the slave select input in Slave mode.
}
// NOTE: M451's/M480's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk). This will violate judgement of spi_active(). Disable it.
SPI_DISABLE_SYNC(spi_base);
}
void spi_frequency(spi_t *obj, int hz)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
}
@ -229,7 +256,7 @@ int spi_master_write(spi_t *obj, int value)
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
// NOTE: Data in receive FIFO can be read out via ICE.
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for tx buffer empty
while(! spi_writeable(obj));
@ -239,7 +266,7 @@ int spi_master_write(spi_t *obj, int value)
while (! spi_readable(obj));
int value2 = SPI_READ_RX(spi_base);
SPI_DISABLE(spi_base);
SPI_DISABLE_SYNC(spi_base);
return value2;
}
@ -264,7 +291,7 @@ int spi_slave_receive(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
return spi_readable(obj);
};
@ -273,7 +300,7 @@ int spi_slave_read(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for rx buffer full
while (! spi_readable(obj));
@ -285,7 +312,7 @@ void spi_slave_write(spi_t *obj, int value)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
// Wait for tx buffer empty
while(! spi_writeable(obj));
@ -318,8 +345,8 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
// SPI IRQ is necessary for both interrupt way and DMA way
spi_enable_event(obj, event, 1);
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
SPI_ENABLE(spi_base);
SPI_ENABLE_SYNC(spi_base);
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
// Interrupt way
@ -425,9 +452,8 @@ void spi_abort_asynch(spi_t *obj)
spi_enable_vector_interrupt(obj, 0, 0);
spi_master_enable_interrupt(obj, 0);
// FIXME: SPI H/W may get out of state without the busy check.
while (SPI_IS_BUSY(spi_base));
SPI_DISABLE(spi_base);
/* Necessary for accessing FIFOCTL below */
SPI_DISABLE_SYNC(spi_base);
SPI_ClearRxFIFO(spi_base);
SPI_ClearTxFIFO(spi_base);