Files
templates/c/st7789/st7789.h
Andrey Kruchinkin c7798c02db feat(st7789): драйвер TFT-панелей ST7789V поверх SPI
Перенесён из KONOR_ds18b20/lib/st7789; в OpticalTester лежала побайтово
такая же копия.

Ядро не включает заголовки МК и не заводит кадрового буфера: примитивы
пишут пиксели потоком, поэтому драйвер работает на МК с единицами
килобайт ОЗУ. Платформа подключается через ST7789_Io: обязательны
write, set_command и delay_ms, остальное — по разводке платы.
2026-08-23 01:15:11 +03:00

281 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file st7789.h
* @brief Портируемый драйвер TFT-дисплеев ST7789V (SPI, RGB565).
*
* Библиотека не включает заголовки микроконтроллера и не обращается к
* регистрам: весь обмен идёт через таблицу обратных вызовов ST7789_Io,
* которую заполняет порт платы. Кадрового буфера нет — примитивы пишут
* пиксели в контроллер потоком, поэтому драйвер работает на МК с единицами
* килобайт ОЗУ.
*
* Порядок использования: заполнить ST7789_Io, взять ST7789_ConfigDefault(),
* поправить геометрию и поворот, вызвать ST7789_Init(), далее рисовать.
*/
#ifndef ST7789_H
#define ST7789_H
#include <stdint.h>
/** Ширина знакоместа встроенного шрифта при масштабе 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 */