mirror of https://github.com/ARMmbed/mbed-os.git
[NANO130] Fix SPI slave failed
parent
71cd9c3b55
commit
b219a3ee18
|
@ -43,7 +43,8 @@ struct nu_spi_var {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: NANO130 doesn't support relocating vector table. ISR vector passed into NVIC_SetVector() can only be weak symbol defined in startup_Nano100Series.c.
|
// NOTE:
|
||||||
|
// NANO130: No support for relocating vector table. ISR vector passed into NVIC_SetVector() can only be weak symbol defined in startup_Nano100Series.c.
|
||||||
void SPI0_IRQHandler(void);
|
void SPI0_IRQHandler(void);
|
||||||
void SPI1_IRQHandler(void);
|
void SPI1_IRQHandler(void);
|
||||||
void SPI2_IRQHandler(void);
|
void SPI2_IRQHandler(void);
|
||||||
|
@ -200,12 +201,13 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
||||||
|
|
||||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
|
|
||||||
// NOTE 1: All configurations should be ready before enabling SPI peripheral.
|
// NOTE: All configurations should be ready before enabling SPI peripheral.
|
||||||
// NOTE 2: Re-configuration is allowed only as SPI peripheral is idle.
|
// NOTE: Re-configuration is allowed only as SPI peripheral is idle.
|
||||||
// NOTE 3: On NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave mode. Cannot use to judge busy or not.
|
// NOTE:
|
||||||
if (! (spi_base->CTL & SPI_CTL_SLAVE_Msk)) {
|
// NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave/FIFO mode. So disable FIFO first.
|
||||||
while (SPI_IS_BUSY(spi_base));
|
SPI_DisableFIFO(spi_base);
|
||||||
}
|
while (SPI_IS_BUSY(spi_base));
|
||||||
|
|
||||||
|
|
||||||
SPI_Open(spi_base,
|
SPI_Open(spi_base,
|
||||||
slave ? SPI_SLAVE : SPI_MASTER,
|
slave ? SPI_SLAVE : SPI_MASTER,
|
||||||
|
@ -214,8 +216,6 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
||||||
SPI_GetBusClock(spi_base));
|
SPI_GetBusClock(spi_base));
|
||||||
// NOTE: Hardcode to be MSB first.
|
// NOTE: Hardcode to be MSB first.
|
||||||
SPI_SET_MSB_FIRST(spi_base);
|
SPI_SET_MSB_FIRST(spi_base);
|
||||||
// NOTE: On NANO130, FIFO mode defaults to disabled in SPI_Open(), so place SPI_EnableFIFO() after SPI_Open().
|
|
||||||
SPI_EnableFIFO(spi_base, NU_SPI_FIFO_DEPTH / 2, NU_SPI_FIFO_DEPTH / 2);
|
|
||||||
|
|
||||||
if (! slave) {
|
if (! slave) {
|
||||||
// Master
|
// Master
|
||||||
|
@ -246,19 +246,29 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
||||||
spi_base->SSR &= ~SPI_SS1_ACTIVE_HIGH;
|
spi_base->SSR &= ~SPI_SS1_ACTIVE_HIGH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// NOTE:
|
||||||
|
// 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)
|
void spi_frequency(spi_t *obj, int hz)
|
||||||
{
|
{
|
||||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
|
|
||||||
// NOTE: On NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave mode. Cannot use to judge busy or not.
|
// NANO130, SPI_CTL.GO_BUSY always reads as 1 in slave/FIFO mode. So disable FIFO first.
|
||||||
if (! (spi_base->CTL & SPI_CTL_SLAVE_Msk)) {
|
SPI_DisableFIFO(spi_base);
|
||||||
while (SPI_IS_BUSY(spi_base));
|
while (SPI_IS_BUSY(spi_base));
|
||||||
}
|
|
||||||
|
|
||||||
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,7 +277,9 @@ int spi_master_write(spi_t *obj, int value)
|
||||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
|
|
||||||
// NOTE: Data in receive FIFO can be read out via ICE.
|
// NOTE: Data in receive FIFO can be read out via ICE.
|
||||||
// NOTE: On NANO130, not required as FIFO mode is enabled.
|
// 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_TRIGGER(spi_base);
|
//SPI_TRIGGER(spi_base);
|
||||||
|
|
||||||
// Wait for tx buffer empty
|
// Wait for tx buffer empty
|
||||||
|
@ -286,7 +298,9 @@ int spi_master_write(spi_t *obj, int value)
|
||||||
#if DEVICE_SPISLAVE
|
#if DEVICE_SPISLAVE
|
||||||
int spi_slave_receive(spi_t *obj)
|
int spi_slave_receive(spi_t *obj)
|
||||||
{
|
{
|
||||||
// NOTE: On NANO130, not required as FIFO mode is enabled.
|
// 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_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
//SPI_TRIGGER(spi_base);
|
//SPI_TRIGGER(spi_base);
|
||||||
|
|
||||||
|
@ -297,7 +311,9 @@ int spi_slave_read(spi_t *obj)
|
||||||
{
|
{
|
||||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
|
|
||||||
// NOTE: On NANO130, not required as FIFO mode is enabled.
|
// 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_TRIGGER(spi_base);
|
//SPI_TRIGGER(spi_base);
|
||||||
|
|
||||||
// Wait for rx buffer full
|
// Wait for rx buffer full
|
||||||
|
@ -311,7 +327,9 @@ void spi_slave_write(spi_t *obj, int value)
|
||||||
{
|
{
|
||||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
|
|
||||||
// NOTE: On NANO130, not required as FIFO mode is enabled.
|
// 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_TRIGGER(spi_base);
|
//SPI_TRIGGER(spi_base);
|
||||||
|
|
||||||
// Wait for tx buffer empty
|
// Wait for tx buffer empty
|
||||||
|
@ -347,7 +365,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
|
||||||
spi_enable_event(obj, event, 1);
|
spi_enable_event(obj, event, 1);
|
||||||
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
|
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
|
||||||
|
|
||||||
// NOTE: On NANO130, not required as FIFO mode is enabled.
|
// 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_TRIGGER(spi_base);
|
//SPI_TRIGGER(spi_base);
|
||||||
|
|
||||||
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
|
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
|
||||||
|
@ -594,7 +614,8 @@ static void spi_master_enable_interrupt(spi_t *obj, uint8_t enable, uint32_t mas
|
||||||
{
|
{
|
||||||
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
|
||||||
|
|
||||||
// NOTE: On NANO130, SPI_IE_MASK/SPI_STATUS_INTSTS_Msk are for unit transfer IE/EF. Don't get confused.
|
// NOTE:
|
||||||
|
// NANO130: SPI_IE_MASK/SPI_STATUS_INTSTS_Msk are for unit transfer IE/EF. Don't get confused.
|
||||||
if (enable) {
|
if (enable) {
|
||||||
//SPI_SET_SUSPEND_CYCLE(spi_base, 4);
|
//SPI_SET_SUSPEND_CYCLE(spi_base, 4);
|
||||||
// Enable tx/rx FIFO threshold interrupt
|
// Enable tx/rx FIFO threshold interrupt
|
||||||
|
|
Loading…
Reference in New Issue