Перенесён из KONOR_ds18b20/lib/st7789; в OpticalTester лежала побайтово такая же копия. Ядро не включает заголовки МК и не заводит кадрового буфера: примитивы пишут пиксели потоком, поэтому драйвер работает на МК с единицами килобайт ОЗУ. Платформа подключается через ST7789_Io: обязательны write, set_command и delay_ms, остальное — по разводке платы.
281 lines
14 KiB
C
281 lines
14 KiB
C
/**
|
||
* @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 */
|