Skip to content

Nuvoton: Fix degrading QSPI to SPI (5.15) #13537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 45 additions & 7 deletions targets/TARGET_NUVOTON/TARGET_M2354/spi_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ static struct nu_spi_var spi4_var = {
#endif
};

/* Change to QSPI version functions
*
* In most cases, we can control degraded QSPI H/W to standard through BSP SPI driver
* directly as if it is just SPI H/W. However, BSP SPI driver distinguishes among
* SPI H/W instances in below functions:
*
* SPI_Open
* SPI_Close
* SPI_SetBusClock
* SPI_GetBusClock
*
* In these cases, we must change to QSPI version instead for QSPI H/W.
*/
static int spi_is_qspi(spi_t *obj);

/* 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
Expand Down Expand Up @@ -210,7 +225,11 @@ void spi_free(spi_t *obj)
}
#endif

SPI_Close((SPI_T *) NU_MODBASE(obj->spi.spi));
if (spi_is_qspi(obj)) {
QSPI_Close((QSPI_T *) NU_MODBASE(obj->spi.spi));
} else {
SPI_Close((SPI_T *) NU_MODBASE(obj->spi.spi));
}

const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
MBED_ASSERT(modinit != NULL);
Expand Down Expand Up @@ -248,11 +267,19 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)

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,
bits,
SPI_GetBusClock(spi_base));
if (spi_is_qspi(obj)) {
QSPI_Open((QSPI_T *) spi_base,
slave ? QSPI_SLAVE : QSPI_MASTER,
(mode == 0) ? QSPI_MODE_0 : (mode == 1) ? QSPI_MODE_1 : (mode == 2) ? QSPI_MODE_2 : QSPI_MODE_3,
bits,
QSPI_GetBusClock((QSPI_T *)spi_base));
} else {
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,
bits,
SPI_GetBusClock(spi_base));
}
// NOTE: Hardcode to be MSB first.
SPI_SET_MSB_FIRST(spi_base);

Expand Down Expand Up @@ -281,7 +308,11 @@ void spi_frequency(spi_t *obj, int hz)

SPI_DISABLE_SYNC(spi_base);

SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
if (spi_is_qspi(obj)) {
QSPI_SetBusClock((QSPI_T *) NU_MODBASE(obj->spi.spi), hz);
} else {
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
}
}


Expand Down Expand Up @@ -617,6 +648,13 @@ uint8_t spi_active(spi_t *obj)
return vec ? 1 : 0;
}

static int spi_is_qspi(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);

return (spi_base == ((SPI_T *) QSPI0));
}

static int spi_writeable(spi_t * obj)
{
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive
Expand Down