#pragma once #include #include #ifdef __cplusplus extern "C" { #endif /* ============================================================ === Конфигурация времени компиляции ============================================================ */ /* * Максимальное количество буферов, * доступное в данной сборке. * * RP2040: обычно 1 * RP2350: можно 2 */ #ifndef DISPLAY_MAX_BUFFERS #define DISPLAY_MAX_BUFFERS 2 #endif /* ============================================================ === Режимы ============================================================ */ typedef enum { /* * SAFE: * - сменой буферов управляет движок * - нет разрывов кадра при 2 буферах * - возможны блокировки */ DISPLAY_MODE_SAFE = 0, /* * RAW: * - сменой буферов управляет пользователь * - движок не блокирует * - возможны разрывы кадра */ DISPLAY_MODE_RAW } display_mode_t; /* ============================================================ === Колбэк ============================================================ */ typedef void (*display_frame_done_cb_t)(void); /* ============================================================ === Конфигурация ============================================================ */ typedef struct { uint16_t width; uint16_t height; /* * 1 или 2. * Должно быть <= DISPLAY_MAX_BUFFERS. */ uint8_t buffer_count; display_mode_t mode; /* * Вызывается после завершения DMA * через display_poll(). * Может быть NULL. */ display_frame_done_cb_t frame_done_cb; } display_config_t; /* ============================================================ === Жизненный цикл ============================================================ */ /* * Инициализация движка дисплея. * Выделяет буферы и инициализирует HW. */ void display_init(const display_config_t* cfg); /* ============================================================ === Доступ к буферам ============================================================ */ /* * Неблокирующая попытка получить буфер для рисования. * * Возвращает NULL если буфер сейчас недоступен * (например, SAFE + 1 буфер и DMA активен). */ uint16_t* display_try_acquire_draw_buffer(void); /* * Блокирующее получение буфера для рисования. */ uint16_t* display_acquire_draw_buffer_blocking(void); /* * Совместимость со старым API. * Начиная с текущей версии работает как non-blocking alias: * эквивалентно display_try_acquire_draw_buffer(). */ uint16_t* display_get_draw_buffer(void); /* * Буфер, который сейчас передаётся DMA. */ uint16_t* display_get_scanout_buffer(void); /* ============================================================ === Управление буферами (только режим RAW) ============================================================ */ /* * Явная смена ролей буферов рисования и вывода. * * Возвращает false если: * - не RAW режим * - меньше 2 буферов * - DMA активен */ bool display_swap_buffers(void); /* ============================================================ === Управление кадром ============================================================ */ /* * Запуск передачи текущего буфера вывода. * * Возвращает false если DMA активен. */ bool display_submit(void); /* * true если DMA не активен. */ bool display_ready(void); /* * Блокирующее ожидание завершения DMA. */ void display_wait(void); /* * Обработка отложенного события завершения кадра. * Должна вызываться из основного цикла. */ void display_poll(void); /* ============================================================ === Хук IRQ ============================================================ */ /* * Должен вызываться из реального обработчика DMA IRQ. */ void display_dma_irq_handler(void); #ifdef __cplusplus } #endif