mbed library sources(for async_print)
Fork of mbed-src by
Revision 549:99e4f6522a2d, committed 2015-05-26
- Comitter:
- mbed_official
- Date:
- Tue May 26 09:00:08 2015 +0100
- Parent:
- 548:1abac31e188e
- Child:
- 550:787824fdf8f9
- Commit message:
- Synchronized with git revision ddca955901f48383d8554d19a650c2c88fe3409d
Full URL: https://github.com/mbedmicro/mbed/commit/ddca955901f48383d8554d19a650c2c88fe3409d/
Changed in this revision
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c | Show annotated file Show diff for this revision Revisions of this file |
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c Fri May 22 10:45:46 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c Tue May 26 09:00:08 2015 +0100 @@ -767,8 +767,24 @@ DMA_CfgDescr_TypeDef rxDescrCfg; DMA_CfgDescr_TypeDef txDescrCfg; + /* Split up transfers if the tx length is larger than what the DMA supports. */ + const int DMA_MAX_TRANSFER = (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT); + + if (tx_length > DMA_MAX_TRANSFER) { + uint32_t max_length = DMA_MAX_TRANSFER; + + /* Make sure only an even amount of bytes are transferred + if the width is larger than 8 bits. */ + if (obj->spi.bits > 8) { + max_length = DMA_MAX_TRANSFER - (DMA_MAX_TRANSFER & 0x01); + } + + /* Update length for current transfer. */ + tx_length = max_length; + } + /* Save amount of TX done by DMA */ - obj->tx_buff.pos = tx_length; + obj->tx_buff.pos += tx_length; if(obj->spi.bits != 9) { /* Only activate RX DMA if a receive buffer is specified */ @@ -966,6 +982,18 @@ if (obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED || obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) { /* DMA implementation */ + /* If there is still data in the TX buffer, setup a new transfer. */ + if (obj->tx_buff.pos < obj->tx_buff.length) { + /* Find position and remaining length without modifying tx_buff. */ + void* tx_pointer = obj->tx_buff.buffer + obj->tx_buff.pos; + uint32_t tx_length = obj->tx_buff.length - obj->tx_buff.pos; + + /* Begin transfer. Rely on spi_activate_dma to split up the transfer further. */ + spi_activate_dma(obj, obj->rx_buff.buffer, tx_pointer, tx_length, obj->rx_buff.length); + + return 0; + } + /* If there is an RX transfer ongoing, wait for it to finish */ if (DMA_ChannelEnabled(obj->spi.dmaOptionsRX.dmaChannel)) { /* Check if we need to kick off TX transfer again to force more incoming data. */