Skip to content

Commit e48994e

Browse files
jhokajarstevew817
authored andcommitted
Silabs: SPI
Changed SPI implementation: #1 To avoid clearing data from buffers, during splitted DMA transfer RX/TX buffer clear is done only when transfer is started. USART transmit is completed instead of DMA/LDMA transfer completed.
1 parent a9f0fdb commit e48994e

File tree

1 file changed

+7
-20
lines changed
  • libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32

1 file changed

+7
-20
lines changed

libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -876,10 +876,7 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, const void* txdata, int t
876876
}
877877

878878
/* Save amount of TX done by DMA */
879-
880879
obj->tx_buff.pos += tx_length;
881-
/* Clear TX registers */
882-
obj->spi.spi->CMD = USART_CMD_CLEARTX;
883880

884881
LDMA_TransferCfg_t xferConf = LDMA_TRANSFER_CFG_PERIPHERAL(dma_periph);
885882
LDMA_Descriptor_t desc = LDMA_DESCRIPTOR_SINGLE_M2P_BYTE(txdata, target_addr, tx_length);
@@ -925,9 +922,6 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, const void* txdata, int t
925922
break;
926923
}
927924

928-
/* Clear RX registers */
929-
obj->spi.spi->CMD = USART_CMD_CLEARRX;
930-
931925
LDMA_TransferCfg_t xferConf = LDMA_TRANSFER_CFG_PERIPHERAL(dma_periph);
932926
LDMA_Descriptor_t desc = LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(source_addr, rxdata, rx_length);
933927
if(obj->spi.bits >= 9){
@@ -989,9 +983,6 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, const void* txdata, int t
989983
rxDescrCfg.hprot = 0;
990984
DMA_CfgDescr(obj->spi.dmaOptionsRX.dmaChannel, true, &rxDescrCfg);
991985

992-
// Clear RX registers - Useful if previous command transfered don't
993-
obj->spi.spi->CMD = USART_CMD_CLEARRX;
994-
995986
/* Activate RX channel */
996987
DMA_ActivateBasic(obj->spi.dmaOptionsRX.dmaChannel, true, false, rxdata, (void *)&(obj->spi.spi->RXDATA),
997988
rx_length - 1);
@@ -1006,9 +997,6 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, const void* txdata, int t
1006997
txDescrCfg.hprot = 0;
1007998
DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg);
1008999

1009-
/* Clear TX registers */
1010-
obj->spi.spi->CMD = USART_CMD_CLEARTX;
1011-
10121000
/* Activate TX channel */
10131001
DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel,
10141002
true,
@@ -1028,9 +1016,6 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, const void* txdata, int t
10281016
rxDescrCfg.hprot = 0;
10291017
DMA_CfgDescr(obj->spi.dmaOptionsRX.dmaChannel, true, &rxDescrCfg);
10301018

1031-
// Clear RX registers - Useful if previous command transfered don't
1032-
obj->spi.spi->CMD = USART_CMD_CLEARRX;
1033-
10341019
/* Activate RX channel */
10351020
DMA_ActivateBasic(obj->spi.dmaOptionsRX.dmaChannel, true, false, rxdata, (void *)&(obj->spi.spi->RXDATAX),
10361021
(rx_length / 2) - 1);
@@ -1044,9 +1029,6 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, const void* txdata, int t
10441029
txDescrCfg.hprot = 0;
10451030
DMA_CfgDescr(obj->spi.dmaOptionsTX.dmaChannel, true, &txDescrCfg);
10461031

1047-
/* Clear TX registers */
1048-
obj->spi.spi->CMD = USART_CMD_CLEARTX;
1049-
10501032
/* Activate TX channel */
10511033
DMA_ActivateBasic( obj->spi.dmaOptionsTX.dmaChannel,
10521034
true,
@@ -1078,6 +1060,9 @@ void spi_master_transfer_dma(spi_t *obj, const void *txdata, void *rxdata, int t
10781060
{
10791061
/* Init DMA here to include it in the power figure */
10801062
dma_init();
1063+
/* Clear TX and RX registers */
1064+
obj->spi.spi->CMD = USART_CMD_CLEARTX;
1065+
obj->spi.spi->CMD = USART_CMD_CLEARRX;
10811066
/* If the DMA channels are already allocated, we can assume they have been setup already */
10821067
if (hint != DMA_USAGE_NEVER && obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED) {
10831068
/* setup has already been done, so just activate the transfer */
@@ -1172,8 +1157,6 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
11721157
void* tx_pointer = (char*)obj->tx_buff.buffer + obj->tx_buff.pos;
11731158
uint32_t tx_length = obj->tx_buff.length - obj->tx_buff.pos;
11741159

1175-
/* Wait previous transmit to complete */
1176-
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
11771160
/* Begin transfer. Rely on spi_activate_dma to split up the transfer further. */
11781161
spi_activate_dma(obj, obj->rx_buff.buffer, tx_pointer, tx_length, obj->rx_buff.length);
11791162

@@ -1200,6 +1183,8 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
12001183
obj->spi.dmaOptionsTX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
12011184
}
12021185

1186+
/* Wait transmit to complete, before user code is indicated*/
1187+
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
12031188
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
12041189
/* return to CPP land to say we're finished */
12051190
return SPI_EVENT_COMPLETE;
@@ -1307,6 +1292,8 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
13071292
obj->spi.dmaOptionsTX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
13081293
}
13091294

1295+
/* Wait transmit to complete, before user code is indicated*/
1296+
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
13101297
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
13111298

13121299
/* return to CPP land to say we're finished */

0 commit comments

Comments
 (0)