Skip to content

Commit 1f735a6

Browse files
authored
Merge pull request ARMmbed#13536 from OpenNuvoton/nuvoton_fix_downgrade_qspi
Nuvoton: Fix degrading QSPI to SPI
2 parents b2ac609 + ce63a17 commit 1f735a6

File tree

2 files changed

+91
-17
lines changed

2 files changed

+91
-17
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/spi_api.c

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ static struct nu_spi_var spi4_var = {
7575
#endif
7676
};
7777

78+
/* Change to QSPI version functions
79+
*
80+
* In most cases, we can control degraded QSPI H/W to standard through BSP SPI driver
81+
* directly as if it is just SPI H/W. However, BSP SPI driver distinguishes among
82+
* SPI H/W instances in below functions:
83+
*
84+
* SPI_Open
85+
* SPI_Close
86+
* SPI_SetBusClock
87+
* SPI_GetBusClock
88+
*
89+
* In these cases, we must change to QSPI version instead for QSPI H/W.
90+
*/
91+
static int spi_is_qspi(spi_t *obj);
92+
7893
/* Synchronous version of SPI_ENABLE()/SPI_DISABLE() macros
7994
*
8095
* The SPI peripheral clock is asynchronous with the system clock. In order to make sure the SPI
@@ -209,7 +224,11 @@ void spi_free(spi_t *obj)
209224
}
210225
#endif
211226

212-
SPI_Close((SPI_T *) NU_MODBASE(obj->spi.spi));
227+
if (spi_is_qspi(obj)) {
228+
QSPI_Close((QSPI_T *) NU_MODBASE(obj->spi.spi));
229+
} else {
230+
SPI_Close((SPI_T *) NU_MODBASE(obj->spi.spi));
231+
}
213232

214233
const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
215234
MBED_ASSERT(modinit != NULL);
@@ -247,11 +266,19 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
247266

248267
SPI_DISABLE_SYNC(spi_base);
249268

250-
SPI_Open(spi_base,
251-
slave ? SPI_SLAVE : SPI_MASTER,
252-
(mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3,
253-
bits,
254-
SPI_GetBusClock(spi_base));
269+
if (spi_is_qspi(obj)) {
270+
QSPI_Open((QSPI_T *) spi_base,
271+
slave ? QSPI_SLAVE : QSPI_MASTER,
272+
(mode == 0) ? QSPI_MODE_0 : (mode == 1) ? QSPI_MODE_1 : (mode == 2) ? QSPI_MODE_2 : QSPI_MODE_3,
273+
bits,
274+
QSPI_GetBusClock((QSPI_T *)spi_base));
275+
} else {
276+
SPI_Open(spi_base,
277+
slave ? SPI_SLAVE : SPI_MASTER,
278+
(mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3,
279+
bits,
280+
SPI_GetBusClock(spi_base));
281+
}
255282
// NOTE: Hardcode to be MSB first.
256283
SPI_SET_MSB_FIRST(spi_base);
257284

@@ -280,7 +307,11 @@ void spi_frequency(spi_t *obj, int hz)
280307

281308
SPI_DISABLE_SYNC(spi_base);
282309

283-
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
310+
if (spi_is_qspi(obj)) {
311+
QSPI_SetBusClock((QSPI_T *) NU_MODBASE(obj->spi.spi), hz);
312+
} else {
313+
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
314+
}
284315
}
285316

286317

@@ -616,6 +647,13 @@ uint8_t spi_active(spi_t *obj)
616647
return vec ? 1 : 0;
617648
}
618649

650+
static int spi_is_qspi(spi_t *obj)
651+
{
652+
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
653+
654+
return (spi_base == ((SPI_T *) QSPI0));
655+
}
656+
619657
static int spi_writeable(spi_t * obj)
620658
{
621659
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive

targets/TARGET_NUVOTON/TARGET_M480/spi_api.c

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ static struct nu_spi_var spi5_var = {
8181
#endif
8282
};
8383

84+
/* Change to QSPI version functions
85+
*
86+
* In most cases, we can control degraded QSPI H/W to standard through BSP SPI driver
87+
* directly as if it is just SPI H/W. However, BSP SPI driver distinguishes among
88+
* SPI H/W instances in below functions:
89+
*
90+
* SPI_Open
91+
* SPI_Close
92+
* SPI_SetBusClock
93+
* SPI_GetBusClock
94+
*
95+
* In these cases, we must change to QSPI version instead for QSPI H/W.
96+
*/
97+
static int spi_is_qspi(spi_t *obj);
98+
8499
/* Synchronous version of SPI_ENABLE()/SPI_DISABLE() macros
85100
*
86101
* The SPI peripheral clock is asynchronous with the system clock. In order to make sure the SPI
@@ -207,7 +222,11 @@ void spi_free(spi_t *obj)
207222
}
208223
#endif
209224

210-
SPI_Close((SPI_T *) NU_MODBASE(obj->spi.spi));
225+
if (spi_is_qspi(obj)) {
226+
QSPI_Close((QSPI_T *) NU_MODBASE(obj->spi.spi));
227+
} else {
228+
SPI_Close((SPI_T *) NU_MODBASE(obj->spi.spi));
229+
}
211230

212231
const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
213232
MBED_ASSERT(modinit != NULL);
@@ -242,11 +261,19 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
242261

243262
SPI_DISABLE_SYNC(spi_base);
244263

245-
SPI_Open(spi_base,
246-
slave ? SPI_SLAVE : SPI_MASTER,
247-
(mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3,
248-
bits,
249-
SPI_GetBusClock(spi_base));
264+
if (spi_is_qspi(obj)) {
265+
QSPI_Open((QSPI_T *) spi_base,
266+
slave ? QSPI_SLAVE : QSPI_MASTER,
267+
(mode == 0) ? QSPI_MODE_0 : (mode == 1) ? QSPI_MODE_1 : (mode == 2) ? QSPI_MODE_2 : QSPI_MODE_3,
268+
bits,
269+
QSPI_GetBusClock((QSPI_T *)spi_base));
270+
} else {
271+
SPI_Open(spi_base,
272+
slave ? SPI_SLAVE : SPI_MASTER,
273+
(mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3,
274+
bits,
275+
SPI_GetBusClock(spi_base));
276+
}
250277
// NOTE: Hardcode to be MSB first.
251278
SPI_SET_MSB_FIRST(spi_base);
252279

@@ -275,7 +302,11 @@ void spi_frequency(spi_t *obj, int hz)
275302

276303
SPI_DISABLE_SYNC(spi_base);
277304

278-
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
305+
if (spi_is_qspi(obj)) {
306+
QSPI_SetBusClock((QSPI_T *) NU_MODBASE(obj->spi.spi), hz);
307+
} else {
308+
SPI_SetBusClock((SPI_T *) NU_MODBASE(obj->spi.spi), hz);
309+
}
279310
}
280311

281312

@@ -611,6 +642,13 @@ uint8_t spi_active(spi_t *obj)
611642
return vec ? 1 : 0;
612643
}
613644

645+
static int spi_is_qspi(spi_t *obj)
646+
{
647+
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
648+
649+
return (spi_base == ((SPI_T *) QSPI0) || spi_base == ((SPI_T *) QSPI1));
650+
}
651+
614652
static int spi_writeable(spi_t * obj)
615653
{
616654
// Receive FIFO must not be full to avoid receive FIFO overflow on next transmit/receive
@@ -904,9 +942,7 @@ static void spi_dma_handler_rx(uint32_t id, uint32_t event_dma)
904942
*/
905943
static uint32_t spi_fifo_depth(spi_t *obj)
906944
{
907-
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
908-
909-
if (spi_base == ((SPI_T *) QSPI0) || spi_base == ((SPI_T *) QSPI1)) {
945+
if (spi_is_qspi(obj)) {
910946
return 8;
911947
}
912948

0 commit comments

Comments
 (0)