Skip to content

Commit 66182a6

Browse files
committed
[Nuvoton] Fix redundant SPI clock generation
Fix SPI clocks are generated redundantly at the end of transfer. This is also to fix FPGA CI test mbed_hal_fpga_ci_test_shield-spi/ SPI - async mode.
1 parent 2e7a6e3 commit 66182a6

File tree

10 files changed

+37
-59
lines changed

10 files changed

+37
-59
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct spi_s {
8484
int dma_chn_id_tx;
8585
int dma_chn_id_rx;
8686
uint32_t event;
87+
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
8788
uint32_t hdlr_async;
8889
};
8990

targets/TARGET_NUVOTON/TARGET_M2351/spi_api.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
407407

408408
SPI_ENABLE_SYNC(spi_base);
409409

410+
// Initialize total SPI transfer frames
411+
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
412+
410413
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
411414
// Interrupt way
412415
spi_master_write_asynch(obj, spi_fifo_depth(obj) / 2);
@@ -677,16 +680,12 @@ static uint32_t spi_event_check(spi_t *obj)
677680
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
678681
{
679682
uint32_t n_words = 0;
680-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
681-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
682-
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
683-
max_tx = NU_MIN(max_tx, tx_limit);
684683
uint8_t data_width = spi_get_data_width(obj);
685684
uint8_t bytes_per_word = (data_width + 7) / 8;
686685
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
687686
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
688687

689-
while ((n_words < max_tx) && spi_writeable(obj)) {
688+
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
690689
if (spi_is_tx_complete(obj)) {
691690
// Transmit dummy as transmit buffer is empty
692691
SPI_WRITE_TX(spi_base, 0);
@@ -709,6 +708,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
709708
obj->tx_buff.pos ++;
710709
}
711710
n_words ++;
711+
obj->spi.txrx_rmn --;
712712
}
713713

714714
//Return the number of words that have been sent
@@ -729,15 +729,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
729729
static uint32_t spi_master_read_asynch(spi_t *obj)
730730
{
731731
uint32_t n_words = 0;
732-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
733-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
734-
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
735732
uint8_t data_width = spi_get_data_width(obj);
736733
uint8_t bytes_per_word = (data_width + 7) / 8;
737734
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
738735
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
739736

740-
while ((n_words < max_rx) && spi_readable(obj)) {
737+
while (spi_readable(obj)) {
741738
if (spi_is_rx_complete(obj)) {
742739
// Disregard as receive buffer is full
743740
SPI_READ_RX(spi_base);

targets/TARGET_NUVOTON/TARGET_M451/objects.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,12 @@ struct spi_s {
8383
PinName pin_sclk;
8484
PinName pin_ssel;
8585

86-
//void (*vec)(void);
87-
8886
// Async transfer related fields
8987
DMAUsage dma_usage;
9088
int dma_chn_id_tx;
9189
int dma_chn_id_rx;
9290
uint32_t event;
93-
//void (*irq_handler_tx_async)(void);
94-
//void (*irq_handler_rx_async)(void);
91+
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
9592
};
9693

9794
struct i2c_s {

targets/TARGET_NUVOTON/TARGET_M451/spi_api.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
381381

382382
SPI_ENABLE_SYNC(spi_base);
383383

384+
// Initialize total SPI transfer frames
385+
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
386+
384387
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
385388
// Interrupt way
386389
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@@ -649,16 +652,12 @@ static uint32_t spi_event_check(spi_t *obj)
649652
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
650653
{
651654
uint32_t n_words = 0;
652-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
653-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
654-
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
655-
max_tx = NU_MIN(max_tx, tx_limit);
656655
uint8_t data_width = spi_get_data_width(obj);
657656
uint8_t bytes_per_word = (data_width + 7) / 8;
658657
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
659658
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
660659

661-
while ((n_words < max_tx) && spi_writeable(obj)) {
660+
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
662661
if (spi_is_tx_complete(obj)) {
663662
// Transmit dummy as transmit buffer is empty
664663
SPI_WRITE_TX(spi_base, 0);
@@ -682,6 +681,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
682681
obj->tx_buff.pos ++;
683682
}
684683
n_words ++;
684+
obj->spi.txrx_rmn --;
685685
}
686686

687687
//Return the number of words that have been sent
@@ -702,15 +702,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
702702
static uint32_t spi_master_read_asynch(spi_t *obj)
703703
{
704704
uint32_t n_words = 0;
705-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
706-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
707-
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
708705
uint8_t data_width = spi_get_data_width(obj);
709706
uint8_t bytes_per_word = (data_width + 7) / 8;
710707
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
711708
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
712709

713-
while ((n_words < max_rx) && spi_readable(obj)) {
710+
while (spi_readable(obj)) {
714711
if (spi_is_rx_complete(obj)) {
715712
// Disregard as receive buffer is full
716713
SPI_READ_RX(spi_base);

targets/TARGET_NUVOTON/TARGET_M480/objects.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,13 @@ struct spi_s {
8282
PinName pin_mosi;
8383
PinName pin_sclk;
8484
PinName pin_ssel;
85-
86-
//void (*vec)(void);
87-
85+
8886
// Async transfer related fields
8987
DMAUsage dma_usage;
9088
int dma_chn_id_tx;
9189
int dma_chn_id_rx;
9290
uint32_t event;
93-
//void (*irq_handler_tx_async)(void);
94-
//void (*irq_handler_rx_async)(void);
91+
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
9592
};
9693

9794
struct i2c_s {

targets/TARGET_NUVOTON/TARGET_M480/spi_api.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
394394

395395
SPI_ENABLE_SYNC(spi_base);
396396

397+
// Initialize total SPI transfer frames
398+
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
399+
397400
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
398401
// Interrupt way
399402
spi_master_write_asynch(obj, spi_fifo_depth(obj) / 2);
@@ -654,16 +657,12 @@ static uint32_t spi_event_check(spi_t *obj)
654657
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
655658
{
656659
uint32_t n_words = 0;
657-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
658-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
659-
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
660-
max_tx = NU_MIN(max_tx, tx_limit);
661660
uint8_t data_width = spi_get_data_width(obj);
662661
uint8_t bytes_per_word = (data_width + 7) / 8;
663662
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
664663
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
665664

666-
while ((n_words < max_tx) && spi_writeable(obj)) {
665+
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
667666
if (spi_is_tx_complete(obj)) {
668667
// Transmit dummy as transmit buffer is empty
669668
SPI_WRITE_TX(spi_base, 0);
@@ -686,6 +685,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
686685
obj->tx_buff.pos ++;
687686
}
688687
n_words ++;
688+
obj->spi.txrx_rmn --;
689689
}
690690

691691
//Return the number of words that have been sent
@@ -706,15 +706,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
706706
static uint32_t spi_master_read_asynch(spi_t *obj)
707707
{
708708
uint32_t n_words = 0;
709-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
710-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
711-
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
712709
uint8_t data_width = spi_get_data_width(obj);
713710
uint8_t bytes_per_word = (data_width + 7) / 8;
714711
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
715712
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
716713

717-
while ((n_words < max_rx) && spi_readable(obj)) {
714+
while (spi_readable(obj)) {
718715
if (spi_is_rx_complete(obj)) {
719716
// Disregard as receive buffer is full
720717
SPI_READ_RX(spi_base);

targets/TARGET_NUVOTON/TARGET_NANO100/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct spi_s {
8585
int dma_chn_id_tx;
8686
int dma_chn_id_rx;
8787
uint32_t event;
88+
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
8889
uint32_t hdlr_async;
8990
};
9091

targets/TARGET_NUVOTON/TARGET_NANO100/spi_api.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
435435

436436
SPI_ENABLE_SYNC(spi_base);
437437

438+
// Initialize total SPI transfer frames
439+
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
440+
438441
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
439442
// Interrupt way
440443
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@@ -714,17 +717,13 @@ static uint32_t spi_event_check(spi_t *obj)
714717
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
715718
{
716719
uint32_t n_words = 0;
717-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
718-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
719-
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
720-
max_tx = NU_MIN(max_tx, tx_limit);
721720
uint8_t data_width = spi_get_data_width(obj);
722721
uint8_t bytes_per_word = (data_width + 7) / 8;
723722
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
724723
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
725724
uint32_t TX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->TX0) : ((uint32_t) &spi_base->TX1);
726725

727-
while ((n_words < max_tx) && spi_writeable(obj)) {
726+
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
728727
if (spi_is_tx_complete(obj)) {
729728
// Transmit dummy as transmit buffer is empty
730729
M32(TX) = 0;
@@ -748,6 +747,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
748747
obj->tx_buff.pos ++;
749748
}
750749
n_words ++;
750+
obj->spi.txrx_rmn --;
751751
}
752752

753753
//Return the number of words that have been sent
@@ -768,16 +768,13 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
768768
static uint32_t spi_master_read_asynch(spi_t *obj)
769769
{
770770
uint32_t n_words = 0;
771-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
772-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
773-
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
774771
uint8_t data_width = spi_get_data_width(obj);
775772
uint8_t bytes_per_word = (data_width + 7) / 8;
776773
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
777774
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
778775
uint32_t RX = (NU_MODSUBINDEX(obj->spi.spi) == 0) ? ((uint32_t) &spi_base->RX0) : ((uint32_t) &spi_base->RX1);
779776

780-
while ((n_words < max_rx) && spi_readable(obj)) {
777+
while (spi_readable(obj)) {
781778
if (spi_is_rx_complete(obj)) {
782779
// Disregard as receive buffer is full
783780
M32(RX);

targets/TARGET_NUVOTON/TARGET_NUC472/objects.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,13 @@ struct spi_s {
7878
PinName pin_mosi;
7979
PinName pin_sclk;
8080
PinName pin_ssel;
81-
82-
//void (*vec)(void);
83-
81+
8482
// Async transfer related fields
8583
DMAUsage dma_usage;
8684
int dma_chn_id_tx;
8785
int dma_chn_id_rx;
8886
uint32_t event;
89-
//void (*irq_handler_tx_async)(void);
90-
//void (*irq_handler_rx_async)(void);
87+
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
9188
};
9289

9390
struct i2c_s {

targets/TARGET_NUVOTON/TARGET_NUC472/spi_api.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
387387

388388
SPI_ENABLE_SYNC(spi_base);
389389

390+
// Initialize total SPI transfer frames
391+
obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length);
392+
390393
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
391394
// Interrupt way
392395
spi_master_write_asynch(obj, NU_SPI_FIFO_DEPTH / 2);
@@ -645,16 +648,12 @@ static uint32_t spi_event_check(spi_t *obj)
645648
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
646649
{
647650
uint32_t n_words = 0;
648-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
649-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
650-
uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn);
651-
max_tx = NU_MIN(max_tx, tx_limit);
652651
uint8_t data_width = spi_get_data_width(obj);
653652
uint8_t bytes_per_word = (data_width + 7) / 8;
654653
uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos;
655654
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
656655

657-
while ((n_words < max_tx) && spi_writeable(obj)) {
656+
while (obj->spi.txrx_rmn && spi_writeable(obj)) {
658657
if (spi_is_tx_complete(obj)) {
659658
// Transmit dummy as transmit buffer is empty
660659
SPI_WRITE_TX(spi_base, 0);
@@ -678,6 +677,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
678677
obj->tx_buff.pos ++;
679678
}
680679
n_words ++;
680+
obj->spi.txrx_rmn --;
681681
}
682682

683683
//Return the number of words that have been sent
@@ -698,15 +698,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
698698
static uint32_t spi_master_read_asynch(spi_t *obj)
699699
{
700700
uint32_t n_words = 0;
701-
uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos;
702-
uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos;
703-
uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn);
704701
uint8_t data_width = spi_get_data_width(obj);
705702
uint8_t bytes_per_word = (data_width + 7) / 8;
706703
uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos;
707704
SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi);
708705

709-
while ((n_words < max_rx) && spi_readable(obj)) {
706+
while (spi_readable(obj)) {
710707
if (spi_is_rx_complete(obj)) {
711708
// Disregard as receive buffer is full
712709
SPI_READ_RX(spi_base);

0 commit comments

Comments
 (0)