Wrapper for HD44780 automatically taking care of custom CGRAM patterns and partial redraws to optimize response times
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
hd44780-buf/src/lcdbuf.h

118 lines
4.1 KiB

/**
* HD44780 utf8-capable display buffer
*/
#ifndef HD44780UTF_LCDBUF_H
#define HD44780UTF_LCDBUF_H
#include <stdint.h>
#include "utf8.h"
#include "cgram.h"
#include "cgrom.h"
// --- settings ---
#define LINE_NUM 4
#define LINE_LEN 20
/// number of remembered dirty regions before giving up and just writing full display
#define LCDBUF_DIRTY_LIST_LEN 8
/// if a cell is marked dirty closer than this to an existing extent,
/// the extent can grows in the direction rather than creating a new one
#define LCDBUF_DIRTY_EXTEND 5
/// Char shown if the requested symbol is missing in lookup tables
#define LCDBUF_SUBSTITUTION_CHAR 0xDB // this is the katakana box (ro ロ?) in the codepage A00
/// this must contain the full width or height
typedef uint8_t lcdbuf_pos_t;
/// this must contain the total number of cells in the display
typedef uint8_t lcdbuf_count_t;
_Static_assert(LINE_NUM * LINE_LEN < 256, "LINE_NUM * LINE_LEN must fit in u8");
// ----------------
/// Number of custom CGRAM slots (always 8)
#define LCDBUF_CGRAM_CAPACITY 8
/** Indicates a range of screen cells that were changed and must be written to HW */
struct LcdBuf_DirtyExtent {
lcdbuf_pos_t row;
lcdbuf_pos_t col;
lcdbuf_count_t count;
};
/** Struct for one CGRAM slot */
struct LcdBuf_CgramState {
/** UTF8 uint shown in this slot */
uint32_t uint;
/** Array index in the custom symbols table, use for look-up when writing the font data to HW */
uint16_t symbol_index;
/** Number of occurrences of this symbol in the screen array */
lcdbuf_count_t refcount;
/** This CGRAM slot needs to be written to HW */
bool dirty;
};
struct LcdBuffer {
/** The raw screen buffer. Custom symbols are 0x00-0x07 */
uint8_t screen[LINE_NUM][LINE_LEN];
/** CGRAM state array */
struct LcdBuf_CgramState cgram[LCDBUF_CGRAM_CAPACITY];
/** Hardware CGROM lookup table, used to map UTF8 to existing ROM symbols */
const struct LcdBuf_CGROM_Entry *cgrom;
/** Defined custom display pattern of utf8 symbols */
const struct LcdBuf_CGRAM_Symbol *custom_symbols;
/** Array of dirty extents - ranges in the display that need to be flushed to HW */
struct LcdBuf_DirtyExtent dirty_extents[LCDBUF_DIRTY_LIST_LEN];
/** If the dirty extents array was not sufficient to hold all changes, this flag is set,
* indicating the dirty_extents array should be disregarded. */
bool full_repaint_required;
/* Visible cursor - is restored after flushing */
uint8_t cursor_style; // two bits - blink 0b01, bar 0b10
lcdbuf_pos_t cursor_row;
lcdbuf_pos_t cursor_col;
bool cursor_dirty;
};
/** Initialize the struct */
void LcdBuffer_Init(struct LcdBuffer *self, const struct LcdBuf_CGROM_Entry *cgrom, const struct LcdBuf_CGRAM_Symbol *custom_symbols);
/** Clear the screen */
void LcdBuffer_Clear(struct LcdBuffer *self);
/** Write what needs to be written to the HW, clear all dirty marks */
void LcdBuffer_Flush(struct LcdBuffer *self);
/** Fully write everything to the display */
void LcdBuffer_FlushAll(struct LcdBuffer *self);
/** Set one utf8 character at a position */
void LcdBuffer_Set(struct LcdBuffer *self, lcdbuf_pos_t row, lcdbuf_pos_t col, struct Utf8Char ch);
/** Write a UTF8 string at a position */
void LcdBuffer_Write(struct LcdBuffer *self, lcdbuf_pos_t row, lcdbuf_pos_t col, char *utf_string);
/** Set visible cursor position and style. style is 2 bits: blink 0b01, bar 0b10 */
void LcdBuffer_SetCursor(struct LcdBuffer *self, lcdbuf_pos_t row, lcdbuf_pos_t col, uint8_t cursor_style);
/* Callbacks - need to be implemented by the application! */
/** Clear the entire screen (CGRAM can be left unchanged, but they will be written anew if needed) */
extern void LcdBuffer_IO_Clear();
/** Write character data at position */
extern void LcdBuffer_IO_WriteAt(lcdbuf_pos_t row, lcdbuf_pos_t col, const uint8_t *buf, lcdbuf_count_t len);
/** Write CGRAM data. Data is always 8 bytes long. */
extern void LcdBuffer_IO_WriteCGRAM(uint8_t position, const uint8_t *data);
/** Set cursor pos & style */
extern void LcdBuffer_IO_SetCursorPos(lcdbuf_pos_t cursor_row, lcdbuf_pos_t cursor_col);
extern void LcdBuffer_IO_SetCursorStyle(uint8_t cursor_style);
#endif //HD44780UTF_LCDBUF_H