2727
2828#include <string.h>
2929
30+ #include "mphalport.h"
3031#include "py/gc.h"
3132#include "py/mpstate.h"
3233
@@ -66,6 +67,7 @@ void init_shared_dma(void) {
6667
6768 DMAC -> CTRL .reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN0 ;
6869
70+ // Non-audio channels will be configured on demand.
6971 for (uint8_t i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
7072 dma_configure (i , 0 , true);
7173 }
@@ -155,15 +157,17 @@ static int32_t shared_dma_transfer(void* peripheral,
155157 SercomSpi * s = & ((Sercom * ) peripheral )-> SPI ;
156158 s -> INTFLAG .reg = SERCOM_SPI_INTFLAG_RXC | SERCOM_SPI_INTFLAG_DRE ;
157159 }
158- // Start the RX job first so we don't miss the first byte. The TX job clocks
159- // the output.
160+
161+ // Start the RX job first so we don't miss the first byte. The TX job clocks the output.
162+ // Disable interrupts during startup to make sure both RX and TX start at just about the same time.
163+ mp_hal_disable_all_interrupts ();
160164 if (rx_active ) {
161165 dma_enable_channel (SHARED_RX_CHANNEL );
162166 }
163167 if (tx_active ) {
164168 dma_enable_channel (SHARED_TX_CHANNEL );
165169 }
166-
170+ mp_hal_enable_all_interrupts ();
167171
168172 if (!sercom ) {
169173 if (rx_active ) {
@@ -177,7 +181,7 @@ static int32_t shared_dma_transfer(void* peripheral,
177181 // legitimate state for a DMA channel to be in (apparently), so we can't use that alone as a check.
178182 // Instead, let's look at the ACTIVE flag. When DMA is hung, everything in ACTIVE is zeros.
179183 bool is_okay = false;
180- for (int i = 0 ; i < 10 && !is_okay ; i ++ ) {
184+ for (int i = 0 ; i < 10 && !is_okay ; i ++ ) {
181185 bool complete = true;
182186 if (rx_active ) {
183187 if (DMAC -> Channel [SHARED_RX_CHANNEL ].CHSTATUS .reg & 0x3 )
@@ -190,7 +194,7 @@ static int32_t shared_dma_transfer(void* peripheral,
190194 is_okay = is_okay || (DMAC -> ACTIVE .bit .ABUSY || complete );
191195 }
192196 if (!is_okay ) {
193- for (int i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
197+ for (int i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
194198 if (DMAC -> Channel [i ].CHCTRLA .bit .ENABLE ) {
195199 DMAC -> Channel [i ].CHCTRLA .bit .ENABLE = 0 ;
196200 DMAC -> Channel [i ].CHCTRLA .bit .ENABLE = 1 ;
0 commit comments