Skip to content

Commit 9e72756

Browse files
committed
[Nuvoton] Use vector rather than SPI_CTL_SPIEN_Msk to judge if asynchronous transfer is on-going (spi_active)
1 parent 643d772 commit 9e72756

File tree

4 files changed

+96
-51
lines changed

4 files changed

+96
-51
lines changed

targets/TARGET_NUVOTON/TARGET_M451/spi_api.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
161161
obj->spi.event = 0;
162162
obj->spi.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
163163
obj->spi.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
164+
165+
/* NOTE: We use vector to judge if asynchronous transfer is on-going (spi_active).
166+
* At initial time, asynchronous transfer is not on-going and so vector must
167+
* be cleared to zero for correct judgement. */
168+
NVIC_SetVector(modinit->irq_n, 0);
164169
#endif
165170

166171
// Mark this module to be inited.
@@ -231,8 +236,9 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
231236
spi_base->SSCTL &= ~SPI_SSCTL_SSACTPOL_Msk;
232237
}
233238

234-
// NOTE: M451's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk). This will violate judgement of spi_active(). Disable it.
235-
SPI_DISABLE_SYNC(spi_base);
239+
/* NOTE: M451's/M480's/M2351's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk).
240+
* We cannot use SPI_CTL_SPIEN_Msk for judgement of spi_active().
241+
* Judge with vector instead. */
236242
}
237243

238244
void spi_frequency(spi_t *obj, int hz)
@@ -259,9 +265,9 @@ int spi_master_write(spi_t *obj, int value)
259265
// Wait for rx buffer full
260266
while (! spi_readable(obj));
261267
int value2 = SPI_READ_RX(spi_base);
262-
263-
SPI_DISABLE_SYNC(spi_base);
264-
268+
269+
/* We don't call SPI_DISABLE_SYNC here for performance. */
270+
265271
return value2;
266272
}
267273

@@ -477,20 +483,14 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
477483

478484
uint8_t spi_active(spi_t *obj)
479485
{
480-
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
481-
// FIXME
482-
/*
483-
if ((obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length)
484-
|| (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) ){
485-
return 1;
486-
} else {
487-
// interrupts are disabled, all transaction have been completed
488-
// TODO: checking rx fifo, it reports data eventhough RFDF is not set
489-
return DSPI_HAL_GetIntMode(obj->spi.address, kDspiRxFifoDrainRequest);
490-
}*/
491-
492-
//return SPI_IS_BUSY(spi_base);
493-
return (spi_base->CTL & SPI_CTL_SPIEN_Msk);
486+
const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
487+
MBED_ASSERT(modinit != NULL);
488+
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
489+
490+
/* Vector will be cleared when asynchronous transfer is finished or aborted.
491+
Use it to judge if asynchronous transfer is on-going. */
492+
uint32_t vec = NVIC_GetVector(modinit->irq_n);
493+
return vec ? 1 : 0;
494494
}
495495

496496
static int spi_writeable(spi_t * obj)
@@ -525,8 +525,8 @@ static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t en
525525
NVIC_EnableIRQ(modinit->irq_n);
526526
}
527527
else {
528-
//NVIC_SetVector(modinit->irq_n, handler);
529528
NVIC_DisableIRQ(modinit->irq_n);
529+
NVIC_SetVector(modinit->irq_n, 0);
530530
}
531531
}
532532

targets/TARGET_NUVOTON/TARGET_M480/spi_api.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
170170
obj->spi.event = 0;
171171
obj->spi.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
172172
obj->spi.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
173+
174+
/* NOTE: We use vector to judge if asynchronous transfer is on-going (spi_active).
175+
* At initial time, asynchronous transfer is not on-going and so vector must
176+
* be cleared to zero for correct judgement. */
177+
NVIC_SetVector(modinit->irq_n, 0);
173178
#endif
174179

175180
// Mark this module to be inited.
@@ -236,8 +241,9 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
236241
spi_base->SSCTL &= ~SPI_SSCTL_SSACTPOL_Msk;
237242
}
238243

239-
// NOTE: M451's/M480's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk). This will violate judgement of spi_active(). Disable it.
240-
SPI_DISABLE_SYNC(spi_base);
244+
/* NOTE: M451's/M480's/M2351's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk).
245+
* We cannot use SPI_CTL_SPIEN_Msk for judgement of spi_active().
246+
* Judge with vector instead. */
241247
}
242248

243249
void spi_frequency(spi_t *obj, int hz)
@@ -265,7 +271,7 @@ int spi_master_write(spi_t *obj, int value)
265271
while (! spi_readable(obj));
266272
int value2 = SPI_READ_RX(spi_base);
267273

268-
SPI_DISABLE_SYNC(spi_base);
274+
/* We don't call SPI_DISABLE_SYNC here for performance. */
269275

270276
return value2;
271277
}
@@ -479,9 +485,14 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
479485

480486
uint8_t spi_active(spi_t *obj)
481487
{
482-
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
488+
const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
489+
MBED_ASSERT(modinit != NULL);
490+
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
483491

484-
return (spi_base->CTL & SPI_CTL_SPIEN_Msk);
492+
/* Vector will be cleared when asynchronous transfer is finished or aborted.
493+
Use it to judge if asynchronous transfer is on-going. */
494+
uint32_t vec = NVIC_GetVector(modinit->irq_n);
495+
return vec ? 1 : 0;
485496
}
486497

487498
static int spi_writeable(spi_t * obj)
@@ -515,6 +526,7 @@ static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t en
515526
NVIC_EnableIRQ(modinit->irq_n);
516527
} else {
517528
NVIC_DisableIRQ(modinit->irq_n);
529+
NVIC_SetVector(modinit->irq_n, 0);
518530
}
519531
}
520532

targets/TARGET_NUVOTON/TARGET_NANO100/spi_api.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
182182
obj->spi.event = 0;
183183
obj->spi.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
184184
obj->spi.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
185+
186+
/* NOTE: We use vector to judge if asynchronous transfer is on-going (spi_active).
187+
* At initial time, asynchronous transfer is not on-going and so vector must
188+
* be cleared to zero for correct judgement. */
189+
/* NOTE: On NANO130, vector table is fixed in ROM and cannot be modified. */
190+
#if 0
191+
NVIC_SetVector(modinit->irq_n, 0);
192+
#else
193+
obj->spi.hdlr_async = 0;
194+
#endif
185195
#endif
186196

187197
// Mark this module to be inited.
@@ -266,6 +276,10 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
266276
// NANO130: Configure slave select signal to edge-trigger rather than level-trigger
267277
spi_base->SSR |= SPI_SSR_SS_LTRIG_Msk;
268278
}
279+
280+
/* NOTE: M451's/M480's/M2351's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk).
281+
* We cannot use SPI_CTL_SPIEN_Msk for judgement of spi_active().
282+
* Judge with vector instead. */
269283
}
270284

271285
void spi_frequency(spi_t *obj, int hz)
@@ -297,7 +311,9 @@ int spi_master_write(spi_t *obj, int value)
297311
while (! spi_readable(obj));
298312
uint32_t RX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->RX0) : ((uint32_t) &spi_base->RX1);
299313
int value2 = M32(RX);
300-
314+
315+
/* We don't call SPI_DISABLE_SYNC here for performance. */
316+
301317
return value2;
302318
}
303319

@@ -511,9 +527,19 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
511527

512528
uint8_t spi_active(spi_t *obj)
513529
{
514-
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
515-
516-
return SPI_IS_BUSY(spi_base);
530+
const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
531+
MBED_ASSERT(modinit != NULL);
532+
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
533+
534+
/* Vector will be cleared when asynchronous transfer is finished or aborted.
535+
Use it to judge if asynchronous transfer is on-going. */
536+
/* NOTE: On NANO130, vector table is fixed in ROM and cannot be modified. */
537+
#if 0
538+
uint32_t vec = NVIC_GetVector(modinit->irq_n);
539+
return vec ? 1 : 0;
540+
#else
541+
return obj->spi.hdlr_async ? 1 : 0;
542+
#endif
517543
}
518544

519545
void SPI0_IRQHandler(void)
@@ -567,13 +593,20 @@ static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t en
567593
if (enable) {
568594
var->obj = obj;
569595
obj->spi.hdlr_async = handler;
596+
/* NOTE: On NANO130, vector table is fixed in ROM and cannot be modified. */
597+
#if 0
570598
NVIC_SetVector(modinit->irq_n, (uint32_t) var->vec);
599+
#endif
571600
NVIC_EnableIRQ(modinit->irq_n);
572601
}
573602
else {
574603
NVIC_DisableIRQ(modinit->irq_n);
604+
/* NOTE: On NANO130, vector table is fixed in ROM and cannot be modified. */
605+
#if 0
606+
NVIC_SetVector(modinit->irq_n, 0);
607+
#endif
575608
var->obj = NULL;
576-
obj->spi.hdlr_async = handler;
609+
obj->spi.hdlr_async = 0;
577610
}
578611
}
579612

targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
165165
obj->spi.event = 0;
166166
obj->spi.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
167167
obj->spi.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
168+
169+
/* NOTE: We use vector to judge if asynchronous transfer is on-going (spi_active).
170+
* At initial time, asynchronous transfer is not on-going and so vector must
171+
* be cleared to zero for correct judgement. */
172+
NVIC_SetVector(modinit->irq_n, 0);
168173
#endif
169174

170175
// Mark this module to be inited.
@@ -236,9 +241,10 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
236241
spi_base->SSCTL &= ~SPI_SSCTL_SSACTPOL_Msk;
237242
// NOTE: SPI_SS0 is defined as the slave select input in Slave mode.
238243
}
239-
240-
// NOTE: M451's/M480's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk). This will violate judgement of spi_active(). Disable it.
241-
SPI_DISABLE_SYNC(spi_base);
244+
245+
/* NOTE: M451's/M480's/M2351's SPI_Open() will enable SPI transfer (SPI_CTL_SPIEN_Msk).
246+
* We cannot use SPI_CTL_SPIEN_Msk for judgement of spi_active().
247+
* Judge with vector instead. */
242248
}
243249

244250
void spi_frequency(spi_t *obj, int hz)
@@ -265,9 +271,9 @@ int spi_master_write(spi_t *obj, int value)
265271
// Wait for rx buffer full
266272
while (! spi_readable(obj));
267273
int value2 = SPI_READ_RX(spi_base);
268-
269-
SPI_DISABLE_SYNC(spi_base);
270-
274+
275+
/* We don't call SPI_DISABLE_SYNC here for performance. */
276+
271277
return value2;
272278
}
273279

@@ -479,20 +485,14 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
479485

480486
uint8_t spi_active(spi_t *obj)
481487
{
482-
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
483-
// FIXME
484-
/*
485-
if ((obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length)
486-
|| (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) ){
487-
return 1;
488-
} else {
489-
// interrupts are disabled, all transaction have been completed
490-
// TODO: checking rx fifo, it reports data eventhough RFDF is not set
491-
return DSPI_HAL_GetIntMode(obj->spi.address, kDspiRxFifoDrainRequest);
492-
}*/
493-
494-
//return SPI_IS_BUSY(spi_base);
495-
return (spi_base->CTL & SPI_CTL_SPIEN_Msk);
488+
const struct nu_modinit_s *modinit = get_modinit(obj->spi.spi, spi_modinit_tab);
489+
MBED_ASSERT(modinit != NULL);
490+
MBED_ASSERT(modinit->modname == (int) obj->spi.spi);
491+
492+
/* Vector will be cleared when asynchronous transfer is finished or aborted.
493+
Use it to judge if asynchronous transfer is on-going. */
494+
uint32_t vec = NVIC_GetVector(modinit->irq_n);
495+
return vec ? 1 : 0;
496496
}
497497

498498
static int spi_writeable(spi_t * obj)
@@ -527,8 +527,8 @@ static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t en
527527
NVIC_EnableIRQ(modinit->irq_n);
528528
}
529529
else {
530-
//NVIC_SetVector(modinit->irq_n, handler);
531530
NVIC_DisableIRQ(modinit->irq_n);
531+
NVIC_SetVector(modinit->irq_n, 0);
532532
}
533533
}
534534

0 commit comments

Comments
 (0)