8000 Run background tasks during display refresh by tannewt · Pull Request #10277 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

Run background tasks during display refresh #10277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the co 8000 mmunity.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
14 changes: 14 additions & 0 deletions ports/raspberrypi/audio_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
7 changes: 5 additions & 2 deletions shared-module/busdisplay/BusDisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions shared-module/epaperdisplay/EPaperDisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions shared-module/framebufferio/FramebufferDisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
0