Skip to content

Commit

Permalink
Merge pull request #13536 from OpenNuvoton/nuvoton_fix_downgrade_qspi
Browse files Browse the repository at this point in the history
Nuvoton: Fix degrading QSPI to SPI
  • Loading branch information
0xc0170 authored Sep 7, 2020
2 parents b2ac609 + ce63a17 commit 1f735a6
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 17 deletions.
52 changes: 45 additions & 7 deletions targets/TARGET_NUVOTON/TARGET_M2351/spi_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,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 @@ -209,7 +224,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 @@ -247,11 +266,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 @@ -280,7 +307,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 @@ -616,6 +647,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
56 changes: 46 additions & 10 deletions targets/TARGET_NUVOTON/TARGET_M480/spi_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ static struct nu_spi_var spi5_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 @@ -207,7 +222,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 @@ -242,11 +261,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 @@ -275,7 +302,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 @@ -611,6 +642,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) || spi_base == ((SPI_T *) QSPI1));
}

static int spi_writeable(spi_t * obj)
{
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive
Expand Down Expand Up @@ -904,9 +942,7 @@ static void spi_dma_handler_rx(uint32_t id, uint32_t event_dma)
*/
static uint32_t spi_fifo_depth(spi_t *obj)
{
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);

if (spi_base == ((SPI_T *) QSPI0) || spi_base == ((SPI_T *) QSPI1)) {
if (spi_is_qspi(obj)) {
return 8;
}

Expand Down

0 comments on commit 1f735a6

Please sign in to comment.