229 lines
9.5 KiB
C
229 lines
9.5 KiB
C
/**
|
||
* @file zh_160x_i2c.h
|
||
*
|
||
* @brief Driver for 16x2 and 16x4 LCD displays via I2C PCF8574 expander.
|
||
*
|
||
* Provides a high-level API for controlling HD44780-compatible LCD modules
|
||
* connected through a PCF8574 I/O expander. Supports text output, cursor
|
||
* control, and progress bar display.
|
||
*
|
||
* Key features:
|
||
* - 4-bit interface mode for efficient data transfer
|
||
* - Support for 16x2 and 16x4 LCD configurations
|
||
* - Text, integer, and floating-point number printing
|
||
* - Custom progress bar rendering
|
||
* - Cursor visibility and blink control
|
||
*
|
||
* @note All display operations require an initialized handle obtained through zh_160x_init().
|
||
* @note The text position counter of the HD44780 controller is shared by all rows,
|
||
* so row addresses are remapped internally.
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include "zh_pcf8574.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C"
|
||
{
|
||
#endif
|
||
|
||
/**
|
||
* @brief Opaque handle for LCD 160x I2C display.
|
||
*
|
||
* Internal structure containing the PCF8574 expander handle and
|
||
* current LCD size configuration.
|
||
*/
|
||
typedef struct _zh_160x_i2c_handle_t zh_160x_i2c_handle_t;
|
||
|
||
/**
|
||
* @brief Supported LCD display sizes.
|
||
*/
|
||
typedef enum
|
||
{
|
||
ZH_LCD_16X2, /*!< LCD size 16x2 */
|
||
ZH_LCD_16X4, /*!< LCD size 16x4 */
|
||
ZH_LCD_NUM_MAX /*!< Number of supported LCD sizes */
|
||
} zh_160x_i2c_lcd_size_t;
|
||
|
||
/**
|
||
* @brief Initializes the LCD 160x display.
|
||
*
|
||
* Allocates and configures the LCD handle, then sends the initialization
|
||
* sequence to the LCD controller via the PCF8574 I2C expander.
|
||
* Configures 4-bit mode and sets default display parameters.
|
||
*
|
||
* @param[in] expander Pointer to the PCF8574 expander handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[out] handle Pointer to the output LCD handle pointer (must not be NULL and must point to a NULL pointer)
|
||
* @param[in] size LCD size configuration (must be < ZH_LCD_NUM_MAX)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if any parameter pointer is NULL or size is invalid
|
||
* @return ESP_ERR_INVALID_STATE if the output pointer already holds an initialized handle
|
||
* @return ESP_ERR_NO_MEM if memory allocation fails
|
||
* @return ESP_FAIL if LCD initialization sequence fails
|
||
*/
|
||
esp_err_t zh_160x_init(zh_pcf8574_handle_t **expander, zh_160x_i2c_handle_t **handle, zh_160x_i2c_lcd_size_t size);
|
||
|
||
/**
|
||
* @brief Deinitializes the LCD 160x display and frees the handle.
|
||
*
|
||
* Releases the allocated memory for the LCD handle and sets the output
|
||
* pointer to NULL to prevent use-after-free.
|
||
*
|
||
* @param[in,out] handle Pointer to the LCD handle (must not be NULL)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if handle pointer is NULL or points to a NULL handle
|
||
*/
|
||
esp_err_t zh_160x_deinit(zh_160x_i2c_handle_t **handle);
|
||
|
||
/**
|
||
* @brief Clears the LCD screen and moves cursor to home position.
|
||
*
|
||
* Sends the LCD clear command (0x01) to erase all displayed text
|
||
* and reset the cursor to the upper-left corner (row 0, column 0).
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if handle pointer is NULL or points to a NULL handle
|
||
* @return ESP_FAIL if sending the command fails
|
||
*/
|
||
esp_err_t zh_160x_lcd_clear(zh_160x_i2c_handle_t **handle);
|
||
|
||
/**
|
||
* @brief Sets the cursor to a specific position on the LCD.
|
||
*
|
||
* Moves the cursor to the specified row and column.
|
||
* For 16x2 displays: rows 0–1, columns 0–15.
|
||
* For 16x4 displays: rows 0–3, columns 0–15.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] row Row number (must be < 2 for 16x2 and < 4 for 16x4)
|
||
* @param[in] col Column number (must be < 16)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if any parameter pointer is NULL or coordinates are out of range
|
||
* @return ESP_FAIL if sending the command fails
|
||
*
|
||
* @note Row address mapping: row 0 = 0x00, row 1 = 0x40,
|
||
* row 2 = 0x10, row 3 = 0x50.
|
||
*/
|
||
esp_err_t zh_160x_set_cursor(zh_160x_i2c_handle_t **handle, uint8_t row, uint8_t col);
|
||
|
||
/**
|
||
* @brief Prints a string to the LCD at the current cursor position.
|
||
*
|
||
* Transmits each character of the null-terminated string to the LCD
|
||
* in 4-bit mode. The cursor advances automatically after each character.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] str Null-terminated string to display (must not be NULL)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if any parameter is NULL or handle points to a NULL handle
|
||
* @return ESP_FAIL if any character transmission fails
|
||
*/
|
||
esp_err_t zh_160x_print_char(zh_160x_i2c_handle_t **handle, const char *str);
|
||
|
||
/**
|
||
* @brief Prints an integer to the LCD at the current cursor position.
|
||
*
|
||
* Converts the integer to a decimal string and displays it.
|
||
* Supports the full range of signed 32-bit values
|
||
* (maximum 10 digits plus an optional sign).
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] num Integer value to display
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if handle pointer is NULL or points to a NULL handle
|
||
* @return ESP_FAIL if string conversion or printing fails
|
||
*/
|
||
esp_err_t zh_160x_print_int(zh_160x_i2c_handle_t **handle, int num);
|
||
|
||
/**
|
||
* @brief Prints a floating-point number to the LCD at the current cursor position.
|
||
*
|
||
* Converts the floating-point value to a decimal string with the
|
||
* specified number of decimal places and displays it. The converted
|
||
* text must fit into an internal 16-character buffer.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] num Floating-point value to display
|
||
* @param[in] precision Number of decimal places passed to snprintf (0–6 recommended)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if handle pointer is NULL or points to a NULL handle
|
||
* @return ESP_FAIL if string conversion or printing fails
|
||
*/
|
||
esp_err_t zh_160x_print_float(zh_160x_i2c_handle_t **handle, float num, uint8_t precision);
|
||
|
||
/**
|
||
* @brief Displays a progress bar on a specific row of the LCD.
|
||
*
|
||
* Renders a 16-block progress bar where filled blocks represent the
|
||
* progress percentage and empty blocks show the remainder. Filled
|
||
* blocks are printed as byte 0xFF, which displays as a solid block
|
||
* only when DDRAM location 0xFF is configured as a custom character
|
||
* (CGRAM pattern 7 on HD44780 controllers).
|
||
* Leaves the cursor at the end of the row.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] row Row number (must be < 2 for 16x2 and < 4 for 16x4)
|
||
* @param[in] progress Progress percentage (must be <= 100)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if any parameter pointer is NULL, row is out of range, or progress exceeds 100
|
||
* @return ESP_FAIL if cursor positioning or character printing fails
|
||
*/
|
||
esp_err_t zh_160x_print_progress_bar(zh_160x_i2c_handle_t **handle, uint8_t row, uint8_t progress);
|
||
|
||
/**
|
||
* @brief Clears a specific row on the LCD.
|
||
*
|
||
* Moves the cursor to the beginning of the specified row and fills
|
||
* all 16 positions with spaces to erase existing content.
|
||
* Leaves the cursor at the start of the cleared row.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] row Row number (must be < 2 for 16x2 and < 4 for 16x4)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if any parameter pointer is NULL or row is out of range
|
||
* @return ESP_FAIL if cursor positioning or character printing fails
|
||
*/
|
||
esp_err_t zh_160x_clear_row(zh_160x_i2c_handle_t **handle, uint8_t row);
|
||
|
||
/**
|
||
* @brief Enables the cursor with optional blink mode.
|
||
*
|
||
* Turns on the cursor and optionally enables blinking.
|
||
* Command 0x0F enables cursor with blink, 0x0E enables cursor only.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
* @param[in] blink Enable cursor blink mode
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if handle pointer is NULL or points to a NULL handle
|
||
* @return ESP_FAIL if sending the command fails
|
||
*/
|
||
esp_err_t zh_160x_on_cursor(zh_160x_i2c_handle_t **handle, bool blink);
|
||
|
||
/**
|
||
* @brief Hides the cursor and disables blinking.
|
||
*
|
||
* Sends command 0x0C to turn off both cursor and cursor blink.
|
||
*
|
||
* @param[in] handle Pointer to the LCD handle pointer (must not be NULL and must point to a non-NULL handle)
|
||
*
|
||
* @return ESP_OK on success
|
||
* @return ESP_ERR_INVALID_ARG if handle pointer is NULL or points to a NULL handle
|
||
* @return ESP_FAIL if sending the command fails
|
||
*/
|
||
esp_err_t zh_160x_off_cursor(zh_160x_i2c_handle_t **handle);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif |