31
31
32
32
#include "shared-bindings/audiocore/RawSample.h"
33
33
#include "shared-bindings/audiocore/WaveFile.h"
34
- #include "supervisor/shared/tick .h"
34
+ #include "supervisor/background_callback .h"
35
35
36
36
#include "py/mpstate.h"
37
37
#include "py/runtime.h"
@@ -61,7 +61,6 @@ void audio_dma_free_channel(uint8_t channel) {
61
61
assert (audio_dma_allocated [channel ]);
62
62
audio_dma_disable_channel (channel );
63
63
audio_dma_allocated [channel ] = false;
64
- supervisor_disable_tick ();
65
64
}
66
65
67
66
void audio_dma_disable_channel (uint8_t channel ) {
@@ -73,7 +72,6 @@ void audio_dma_disable_channel(uint8_t channel) {
73
72
void audio_dma_enable_channel (uint8_t channel ) {
74
73
if (channel >= AUDIO_DMA_CHANNEL_COUNT )
75
74
return ;
76
- supervisor_enable_tick ();
77
75
dma_enable_channel (channel );
78
76
}
79
77
@@ -259,6 +257,15 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
259
257
dma -> beat_size *= 2 ;
260
258
}
261
259
260
+ #ifdef SAM_D5X_E5X
261
+ int irq = dma -> event_channel < 4 ? EVSYS_0_IRQn + dma -> event_channel : EVSYS_4_IRQn ;
262
+ #else
263
+ int irq = EVSYS_IRQn ;
264
+ #endif
265
+
266
+ NVIC_DisableIRQ (irq );
267
+ NVIC_ClearPendingIRQ (irq );
268
+
262
269
DmacDescriptor * first_descriptor = dma_descriptor (dma_channel );
263
270
setup_audio_descriptor (first_descriptor , dma -> beat_size , output_spacing , output_register_address );
264
271
if (single_buffer ) {
@@ -281,6 +288,8 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
281
288
dma_configure (dma_channel , dma_trigger_source , true);
282
289
audio_dma_enable_channel (dma_channel );
283
290
291
+ NVIC_EnableIRQ (irq );
292
+
284
293
return AUDIO_DMA_OK ;
285
294
}
286
295
@@ -321,9 +330,6 @@ void audio_dma_reset(void) {
321
330
for (uint8_t i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
322
331
audio_dma_state [i ] = NULL ;
323
332
audio_dma_pending [i ] = false;
324
- if (audio_dma_allocated [i ]) {
325
- supervisor_disable_tick ();
326
- }
327
333
audio_dma_allocated [i ] = false;
328
334
audio_dma_disable_channel (i );
329
335
dma_descriptor (i )-> BTCTRL .bit .VALID = false;
@@ -343,29 +349,39 @@ bool audio_dma_get_playing(audio_dma_t* dma) {
343
349
return (status & DMAC_CHINTFLAG_TERR ) == 0 ;
344
350
}
345
351
346
- // WARN(tannewt): DO NOT print from here. Printing calls background tasks such as this and causes a
347
- // stack overflow.
352
+ // WARN(tannewt): DO NOT print from here, or anything it calls. Printing calls
353
+ // background tasks such as this and causes a stack overflow.
354
+ STATIC void dma_callback_fun (void * arg ) {
355
+ audio_dma_t * dma = arg ;
356
+ if (dma == NULL ) {
357
+ return ;
358
+ }
359
+
360
+ audio_dma_load_next_block (dma );
361
+ }
348
362
349
- void audio_dma_background (void ) {
363
+ void evsyshandler_common (void ) {
350
364
for (uint8_t i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
351
- if (audio_dma_pending [i ]) {
352
- continue ;
353
- }
354
365
audio_dma_t * dma = audio_dma_state [i ];
355
366
if (dma == NULL ) {
356
367
continue ;
357
368
}
358
-
359
369
bool block_done = event_interrupt_active (dma -> event_channel );
360
370
if (!block_done ) {
361
371
continue ;
362
372
}
363
-
364
- // audio_dma_load_next_block() can call Python code, which can call audio_dma_background()
365
- // recursively at the next background processing time. So disallow recursive calls to here.
366
- audio_dma_pending [i ] = true;
367
- audio_dma_load_next_block (dma );
368
- audio_dma_pending [i ] = false;
373
+ background_callback_add (& dma -> callback , dma_callback_fun , (void * )dma );
369
374
}
370
375
}
376
+
377
+ #ifdef SAM_D5X_E5X
378
+ void EVSYS_0_Handler (void ) { evsyshandler_common (); }
379
+ void EVSYS_1_Handler (void ) { evsyshandler_common (); }
380
+ void EVSYS_2_Handler (void ) { evsyshandler_common (); }
381
+ void EVSYS_3_Handler (void ) { evsyshandler_common (); }
382
+ void EVSYS_4_Handler (void ) { evsyshandler_common (); }
383
+ #else
384
+ void EVSYS_Handler (void ) { evsyshandler_common (); }
385
+ #endif
386
+
371
387
#endif
0 commit comments