/** * @file st7789.h * @brief Портируемый драйвер TFT-дисплеев ST7789V (SPI, RGB565). * * Библиотека не включает заголовки микроконтроллера и не обращается к * регистрам: весь обмен идёт через таблицу обратных вызовов ST7789_Io, * которую заполняет порт платы. Кадрового буфера нет — примитивы пишут * пиксели в контроллер потоком, поэтому драйвер работает на МК с единицами * килобайт ОЗУ. * * Порядок использования: заполнить ST7789_Io, взять ST7789_ConfigDefault(), * поправить геометрию и поворот, вызвать ST7789_Init(), далее рисовать. */ #ifndef ST7789_H #define ST7789_H #include /** Ширина знакоместа встроенного шрифта при масштабе 1, пикселей. */ #define ST7789_FONT_WIDTH 6U /** Высота знакоместа встроенного шрифта при масштабе 1, пикселей. */ #define ST7789_FONT_HEIGHT 8U /** Максимальный целочисленный масштаб шрифта. */ #define ST7789_FONT_MAX_SCALE 4U /** Код знака градуса во встроенном шрифте. */ #define ST7789_CHAR_DEGREE 0x7FU /** Размер потокового буфера в пикселях; определяет расход ОЗУ (по 2 байта). */ #ifndef ST7789_CHUNK_PIXELS #define ST7789_CHUNK_PIXELS 64U #endif /** * @brief Собирает цвет RGB565 из восьмибитных компонент. * * @param r Красная компонента 0..255. * @param g Зелёная компонента 0..255. * @param b Синяя компонента 0..255. * @return Значение цвета для примитивов драйвера. */ #define ST7789_RGB(r, g, b) ((uint16_t)((((uint16_t)(r) & 0xF8U) << 8) \ | (((uint16_t)(g) & 0xFCU) << 3) \ | ((uint16_t)(b) >> 3))) #define ST7789_BLACK 0x0000U /**< Чёрный. */ #define ST7789_WHITE 0xFFFFU /**< Белый. */ #define ST7789_RED 0xF800U /**< Красный. */ #define ST7789_GREEN 0x07E0U /**< Зелёный. */ #define ST7789_BLUE 0x001FU /**< Синий. */ #define ST7789_YELLOW 0xFFE0U /**< Жёлтый. */ #define ST7789_CYAN 0x07FFU /**< Голубой. */ #define ST7789_MAGENTA 0xF81FU /**< Пурпурный. */ #define ST7789_GRAY 0x8410U /**< Серый 50 %. */ #define ST7789_DARKGRAY 0x4208U /**< Тёмно-серый. */ #define ST7789_ORANGE 0xFD20U /**< Оранжевый. */ #define ST7789_NAVY 0x000FU /**< Тёмно-синий. */ /** * @brief Обратные вызовы платы, через которые драйвер работает с дисплеем. * * Обязательны только @c write, @c set_command и @c delay_ms. Остальные поля * допускают значение 0, если сигнал на плате не разведён: без @c set_reset * драйвер выполняет программный сброс командой SWRESET, без @c set_select * дисплей считается постоянно выбранным (вывод CS посажен на общий провод). */ typedef struct { /** Передаёт блок байтов по SPI: 8 бит, старший бит первым. */ void (*write)(void *context, const uint8_t *data, uint32_t size); /** Задаёт уровень линии DC: 1 — команда, 0 — данные. */ void (*set_command)(void *context, uint8_t is_command); /** Управляет выбором кристалла: 1 — выбран (CS низкий). */ void (*set_select)(void *context, uint8_t selected); /** Управляет линией RES: 1 — сброс активен (низкий уровень). */ void (*set_reset)(void *context, uint8_t asserted); /** Включает и выключает подсветку. */ void (*set_backlight)(void *context, uint8_t on); /** Задержка в миллисекундах на время инициализации панели. */ void (*delay_ms)(void *context, uint32_t milliseconds); /** Указатель платы, передаваемый во все обратные вызовы. */ void *context; } ST7789_Io; /** @brief Ориентация растра относительно нулевого поворота панели. */ typedef enum { ST7789_ROTATION_0 = 0, /**< Портрет, шлейф снизу. */ ST7789_ROTATION_90, /**< Ландшафт, поворот на 90 градусов. */ ST7789_ROTATION_180, /**< Портрет, перевёрнутый. */ ST7789_ROTATION_270 /**< Ландшафт, поворот на 270 градусов. */ } ST7789_Rotation; /** * @brief Параметры конкретной панели. * * Модули на ST7789V отличаются видимой областью и её положением в растре * контроллера 240x320: у панелей 240x240 и 240x320 смещений нет, у 135x240 * видимая область сдвинута. Значения берутся из документации модуля. */ typedef struct { uint16_t width; /**< Видимая ширина при нулевом повороте, пикселей. */ uint16_t height; /**< Видимая высота при нулевом повороте, пикселей. */ uint16_t offset_x; /**< Смещение видимой области по X при повороте 0. */ uint16_t offset_y; /**< Смещение видимой области по Y при повороте 0. */ ST7789_Rotation rotation; /**< Требуемая ориентация изображения. */ uint8_t invert; /**< 1 — инверсия (обычные IPS-модули ST7789V). */ uint8_t bgr; /**< 1 — порядок субпикселей BGR вместо RGB. */ } ST7789_Config; /** * @brief Состояние дисплея; принадлежит вызывающему коду. * * Поля @c width и @c height учитывают поворот, поэтому примитивы принимают * координаты в системе видимого изображения. */ typedef struct { ST7789_Io io; /**< Копия обратных вызовов платы. */ ST7789_Config config; /**< Копия параметров панели. */ uint16_t width; /**< Ширина изображения с учётом поворота. */ uint16_t height; /**< Высота изображения с учётом поворота. */ uint16_t offset_x; /**< Смещение окна по X с учётом поворота. */ uint16_t offset_y; /**< Смещение окна по Y с учётом поворота. */ uint8_t ready; /**< 1 после успешной инициализации. */ } ST7789_Display; /** * @brief Заполняет конфигурацию значениями типового модуля на ST7789V. * * Инверсия включена, порядок RGB, смещения нулевые, поворот нулевой. * * @param config Конфигурация, принадлежащая вызывающему коду. * @param width Видимая ширина панели при нулевом повороте. * @param height Видимая высота панели при нулевом повороте. */ void ST7789_ConfigDefault(ST7789_Config *config, uint16_t width, uint16_t height); /** * @brief Инициализирует панель и включает вывод изображения. * * Выполняет аппаратный либо программный сброс, задаёт формат пикселя RGB565, * гамму, ориентацию и включает подсветку, если её вывод разведён. * * @param display Состояние дисплея. * @param io Обратные вызовы платы; копируются внутрь состояния. * @param config Параметры панели; копируются внутрь состояния. * @return 1 при успешной инициализации, 0 при неполной таблице вызовов. */ uint8_t ST7789_Init(ST7789_Display *display, const ST7789_Io *io, const ST7789_Config *config); /** * @brief Меняет ориентацию изображения без повторной инициализации. * * @param display Инициализированный дисплей. * @param rotation Требуемая ориентация. */ void ST7789_SetRotation(ST7789_Display *display, ST7789_Rotation rotation); /** * @brief Включает или выключает подсветку панели. * * @param display Инициализированный дисплей. * @param on 1 — включить, 0 — выключить. * @note При отсутствии обратного вызова платы функция ничего не делает. */ void ST7789_Backlight(ST7789_Display *display, uint8_t on); /** * @brief Переводит панель в спящий режим и обратно. * * @param display Инициализированный дисплей. * @param sleep 1 — сон (SLPIN), 0 — рабочий режим (SLPOUT). */ void ST7789_Sleep(ST7789_Display *display, uint8_t sleep); /** * @brief Заливает весь экран одним цветом. * * @param display Инициализированный дисплей. * @param color Цвет RGB565. */ void ST7789_FillScreen(ST7789_Display *display, uint16_t color); /** * @brief Заливает прямоугольник одним цветом. * * Область обрезается по границам экрана; нулевые размеры игнорируются. * * @param display Инициализированный дисплей. * @param x Левая граница. * @param y Верхняя граница. * @param width Ширина области. * @param height Высота области. * @param color Цвет RGB565. */ void ST7789_FillRect(ST7789_Display *display, int16_t x, int16_t y, uint16_t width, uint16_t height, uint16_t color); /** * @brief Рисует рамку прямоугольника толщиной один пиксель. * * @param display Инициализированный дисплей. * @param x Левая граница. * @param y Верхняя граница. * @param width Ширина области. * @param height Высота области. * @param color Цвет RGB565. */ void ST7789_DrawRect(ST7789_Display *display, int16_t x, int16_t y, uint16_t width, uint16_t height, uint16_t color); /** * @brief Закрашивает один пиксель. * * @param display Инициализированный дисплей. * @param x Координата по горизонтали. * @param y Координата по вертикали. * @param color Цвет RGB565. */ void ST7789_DrawPixel(ST7789_Display *display, int16_t x, int16_t y, uint16_t color); /** * @brief Выводит готовый растр RGB565 построчно. * * @param display Инициализированный дисплей. * @param x Левая граница области. * @param y Верхняя граница области. * @param width Ширина растра. * @param height Высота растра. * @param pixels Массив width*height пикселей, порядок — строками. * @note Область должна целиком попадать на экран, иначе вывод отменяется. */ void ST7789_DrawBitmap(ST7789_Display *display, int16_t x, int16_t y, uint16_t width, uint16_t height, const uint16_t *pixels); /** * @brief Выводит один символ встроенного шрифта с непрозрачным фоном. * * @param display Инициализированный дисплей. * @param x Левая граница знакоместа. * @param y Верхняя граница знакоместа. * @param symbol Код символа 0x20..0x7F; прочие выводятся как пробел. * @param color Цвет штриха. * @param background Цвет фона знакоместа. * @param scale Целочисленный масштаб 1..ST7789_FONT_MAX_SCALE. */ void ST7789_DrawChar(ST7789_Display *display, int16_t x, int16_t y, char symbol, uint16_t color, uint16_t background, uint8_t scale); /** * @brief Выводит строку встроенным шрифтом с непрозрачным фоном. * * Символы за правой границей экрана отбрасываются, перевод строки не * обрабатывается. * * @param display Инициализированный дисплей. * @param x Левая граница первого знакоместа. * @param y Верхняя граница строки. * @param text Строка, завершённая нулём. * @param color Цвет штриха. * @param background Цвет фона знакомест. * @param scale Целочисленный масштаб 1..ST7789_FONT_MAX_SCALE. * @return Координата X сразу за последним выведенным знакоместом. */ int16_t ST7789_DrawString(ST7789_Display *display, int16_t x, int16_t y, const char *text, uint16_t color, uint16_t background, uint8_t scale); /** * @brief Считает ширину строки в пикселях для заданного масштаба. * * @param text Строка, завершённая нулём. * @param scale Масштаб шрифта. * @return Ширина в пикселях. */ uint16_t ST7789_TextWidth(const char *text, uint8_t scale); #endif /* ST7789_H */