diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index 1d9642a16ea10..d9adc3064a841 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -159,9 +159,13 @@ static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { !dma_channel_is_busy(dma->channel[1])) { // No data has been read, and both DMA channels have now finished, so it's safe to stop. audio_dma_stop(dma); + dma->dma_result = AUDIO_DMA_OK; + return; } } } + // Enable the channel so that it can be played. + dma_hw->ch[dma_channel].al1_ctrl |= DMA_CH1_CTRL_TRIG_EN_BITS; dma->dma_result = AUDIO_DMA_OK; } @@ -462,18 +466,26 @@ static void dma_callback_fun(void *arg) { // Load the blocks for the requested channels. uint32_t channel = 0; + size_t filled_count = 0; while (channels_to_load_mask) { if (channels_to_load_mask & 1) { if (dma->channel[0] == channel) { audio_dma_load_next_block(dma, 0); + filled_count++; } if (dma->channel[1] == channel) { audio_dma_load_next_block(dma, 1); + filled_count++; } } channels_to_load_mask >>= 1; channel++; } + // If we had to fill both buffers, then we missed the trigger from the other + // buffer. So restart the DMA. + if (filled_count == 2) { + dma_channel_start(dma->channel[0]); + } } void __not_in_flash_func(isr_dma_0)(void) { @@ -491,6 +503,8 @@ void __not_in_flash_func(isr_dma_0)(void) { audio_dma_t *dma = MP_STATE_PORT(playing_audio)[i]; // Record all channels whose DMA has completed; they need loading. dma->channels_to_load_mask |= mask; + // Disable the channel so that we don't play it without filling it. + dma_hw->ch[i].al1_ctrl &= ~DMA_CH0_CTRL_TRIG_EN_BITS; background_callback_add(&dma->callback, dma_callback_fun, (void *)dma); } if (MP_STATE_PORT(background_pio_read)[i] != NULL) { diff --git a/shared-module/busdisplay/BusDisplay.c b/shared-module/busdisplay/BusDisplay.c index 001f2f20c03e3..ac57f3bf3e019 100644 --- a/shared-module/busdisplay/BusDisplay.c +++ b/shared-module/busdisplay/BusDisplay.c @@ -296,8 +296,11 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are _send_pixels(self, (uint8_t *)buffer, subrectangle_size_bytes); displayio_display_bus_end_transaction(&self->bus); - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. + // Run background tasks so they can run during an explicit refresh. + // Auto-refresh won't run background tasks here because it is a background task itself. + RUN_BACKGROUND_TASKS; + + // Run USB background tasks so they can run during an implicit refresh. #if CIRCUITPY_TINYUSB usb_background(); #endif diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index 14fbc3341b5ff..86ecff29b1102 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -360,8 +360,11 @@ static bool epaperdisplay_epaperdisplay_refresh_area(epaperdisplay_epaperdisplay self->bus.send(self->bus.bus, DISPLAY_DATA, self->chip_select, (uint8_t *)buffer, subrectangle_size_bytes); displayio_display_bus_end_transaction(&self->bus); - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. + // Run background tasks so they can run during an explicit refresh. + // Auto-refresh won't run background tasks here because it is a background task itself. + RUN_BACKGROUND_TASKS; + + // Run USB background tasks so they can run during an implicit refresh. #if CIRCUITPY_TINYUSB usb_background(); #endif diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index c9fe52e0e40b1..4ba2b1325815c 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -200,9 +200,11 @@ static bool _refresh_area(framebufferio_framebufferdisplay_obj_t *self, const di dest += rowstride; src += rowsize; } + // Run background tasks so they can run during an explicit refresh. + // Auto-refresh won't run background tasks here because it is a background task itself. + RUN_BACKGROUND_TASKS; - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. + // Run USB background tasks so they can run during an implicit refresh. #if CIRCUITPY_TINYUSB usb_background(); #endif pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy