@@ -767,8 +767,24 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, void* txdata, int tx_leng
767
767
DMA_CfgDescr_TypeDef rxDescrCfg ;
768
768
DMA_CfgDescr_TypeDef txDescrCfg ;
769
769
770
+ /* Split up transfers if the tx length is larger than what the DMA supports. */
771
+ const int DMA_MAX_TRANSFER = (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT );
772
+
773
+ if (tx_length > DMA_MAX_TRANSFER ) {
774
+ uint32_t max_length = DMA_MAX_TRANSFER ;
775
+
776
+ /* Make sure only an even amount of bytes are transferred
777
+ if the width is larger than 8 bits. */
778
+ if (obj -> spi .bits > 8 ) {
779
+ max_length = DMA_MAX_TRANSFER - (DMA_MAX_TRANSFER & 0x01 );
780
+ }
781
+
782
+ /* Update length for current transfer. */
783
+ tx_length = max_length ;
784
+ }
785
+
770
786
/* Save amount of TX done by DMA */
771
- obj -> tx_buff .pos = tx_length ;
787
+ obj -> tx_buff .pos + = tx_length ;
772
788
773
789
if (obj -> spi .bits != 9 ) {
774
790
/* Only activate RX DMA if a receive buffer is specified */
@@ -966,6 +982,18 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
966
982
if (obj -> spi .dmaOptionsTX .dmaUsageState == DMA_USAGE_ALLOCATED || obj -> spi .dmaOptionsTX .dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED ) {
967
983
/* DMA implementation */
968
984
985
+ /* If there is still data in the TX buffer, setup a new transfer. */
986
+ if (obj -> tx_buff .pos < obj -> tx_buff .length ) {
987
+ /* Find position and remaining length without modifying tx_buff. */
988
+ void * tx_pointer = obj -> tx_buff .buffer + obj -> tx_buff .pos ;
989
+ uint32_t tx_length = obj -> tx_buff .length - obj -> tx_buff .pos ;
990
+
991
+ /* Begin transfer. Rely on spi_activate_dma to split up the transfer further. */
992
+ spi_activate_dma (obj , obj -> rx_buff .buffer , tx_pointer , tx_length , obj -> rx_buff .length );
993
+
994
+ return 0 ;
995
+ }
996
+
969
997
/* If there is an RX transfer ongoing, wait for it to finish */
970
998
if (DMA_ChannelEnabled (obj -> spi .dmaOptionsRX .dmaChannel )) {
971
999
/* Check if we need to kick off TX transfer again to force more incoming data. */
0 commit comments