blob: 103b875831230d2e48b545f7a0003262635480fa [file] [log] [blame]
/*
* Copyright (c) 2022-2023 Jamie McCrae
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Public API for auxiliary (textual/non-graphical) display drivers
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_AUXDISPLAY_H_
#define ZEPHYR_INCLUDE_DRIVERS_AUXDISPLAY_H_
/**
* @brief Auxiliary (Text) Display Interface
* @defgroup auxdisplay_interface Text Display Interface
* @ingroup io_interfaces
* @{
*/
#include <stdint.h>
#include <stddef.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Used for minimum and maximum brightness/backlight values if not supported */
#define AUXDISPLAY_LIGHT_NOT_SUPPORTED 0
/** @brief Used to describe the mode of an auxiliary (text) display */
typedef uint32_t auxdisplay_mode_t;
/** @brief Used for moving the cursor or display position */
enum auxdisplay_position {
/** Moves to specified X,Y position */
AUXDISPLAY_POSITION_ABSOLUTE = 0,
/** Shifts current position by +/- X,Y position, does not take display direction into
* consideration
*/
AUXDISPLAY_POSITION_RELATIVE,
/** Shifts current position by +/- X,Y position, takes display direction into
* consideration
*/
AUXDISPLAY_POSITION_RELATIVE_DIRECTION,
AUXDISPLAY_POSITION_COUNT,
};
/** @brief Used for setting character append position */
enum auxdisplay_direction {
/** Each character will be placed to the right of existing characters */
AUXDISPLAY_DIRECTION_RIGHT = 0,
/** Each character will be placed to the left of existing characters */
AUXDISPLAY_DIRECTION_LEFT,
AUXDISPLAY_DIRECTION_COUNT,
};
/** @brief Light levels for brightness and/or backlight. If not supported by a
* display/driver, both minimum and maximum will be AUXDISPLAY_LIGHT_NOT_SUPPORTED.
*/
struct auxdisplay_light {
/** Minimum light level supported */
uint8_t minimum;
/** Maximum light level supported */
uint8_t maximum;
};
/** @brief Structure holding display capabilities. */
struct auxdisplay_capabilities {
/** Number of character columns */
uint16_t columns;
/** Number of character rows */
uint16_t rows;
/** Display-specific data (e.g. 4-bit or 8-bit mode for HD44780-based displays) */
auxdisplay_mode_t mode;
/** Brightness details for display (if supported) */
struct auxdisplay_light brightness;
/** Backlight details for display (if supported) */
struct auxdisplay_light backlight;
/** Number of custom characters supported by display (0 if unsupported) */
uint8_t custom_characters;
/** Width (in pixels) of a custom character, supplied custom characters should match. */
uint8_t custom_character_width;
/** Height (in pixels) of a custom character, supplied custom characters should match. */
uint8_t custom_character_height;
};
/** @brief Structure for a custom command. This may be extended by specific drivers. */
struct auxdisplay_custom_data {
/** Raw command data to be sent */
uint8_t *data;
/** Length of supplied data */
uint16_t len;
/** Display-driver specific options for command */
uint32_t options;
};
/** @brief Structure for a custom character. */
struct auxdisplay_character {
/** Custom character index on the display */
uint8_t index;
/** Custom character pixel data, a character must be valid for a display consisting
* of a uint8 array of size character width by character height, values should be
* 0x00 for pixel off or 0xff for pixel on, if a display supports shades then values
* between 0x00 and 0xff may be used (display driver dependent).
*/
uint8_t *data;
/** Will be updated with custom character index to use in the display write function to
* disaplay this custom character
*/
uint8_t character_code;
};
/**
* @cond INTERNAL_HIDDEN
*
* For internal use only, skip these in public documentation.
*/
/**
* @typedef auxdisplay_display_on_t
* @brief Callback API to turn display on
* See auxdisplay_display_on() for argument description
*/
typedef int (*auxdisplay_display_on_t)(const struct device *dev);
/**
* @typedef auxdisplay_display_off_t
* @brief Callback API to turn display off
* See auxdisplay_display_off() for argument description
*/
typedef int (*auxdisplay_display_off_t)(const struct device *dev);
/**
* @typedef auxdisplay_cursor_set_enabled_t
* @brief Callback API to turn display cursor visibility on or off
* See auxdisplay_cursor_set_enabled() for argument description
*/
typedef int (*auxdisplay_cursor_set_enabled_t)(const struct device *dev, bool enabled);
/**
* @typedef auxdisplay_position_blinking_set_enabled_t
* @brief Callback API to turn the current position blinking on or off
* See auxdisplay_position_blinking_set_enabled() for argument description
*/
typedef int (*auxdisplay_position_blinking_set_enabled_t)(const struct device *dev,
bool enabled);
/**
* @typedef auxdisplay_cursor_shift_set_t
* @brief Callback API to set how the cursor shifts after a character is written
* See auxdisplay_cursor_shift_set() for argument description
*/
typedef int (*auxdisplay_cursor_shift_set_t)(const struct device *dev, uint8_t direction,
bool display_shift);
/**
* @typedef auxdisplay_cursor_position_set_t
* @brief Callback API to set the cursor position
* See auxdisplay_cursor_position_set() for argument description
*/
typedef int (*auxdisplay_cursor_position_set_t)(const struct device *dev,
enum auxdisplay_position type,
int16_t x, int16_t y);
/**
* @typedef auxdisplay_cursor_position_get_t
* @brief Callback API to get the cursor position
* See auxdisplay_cursor_position_get() for argument description
*/
typedef int (*auxdisplay_cursor_position_get_t)(const struct device *dev, int16_t *x,
int16_t *y);
/**
* @typedef auxdisplay_display_position_set_t
* @brief Callback API to set the current position of the display
* See auxdisplay_display_position_set() for argument description
*/
typedef int (*auxdisplay_display_position_set_t)(const struct device *dev,
enum auxdisplay_position type,
int16_t x, int16_t y);
/**
* @typedef auxdisplay_display_position_get_t
* @brief Callback API to get the current position of the display
* See auxdisplay_display_position_get() for argument description
*/
typedef int (*auxdisplay_display_position_get_t)(const struct device *dev, int16_t *x,
int16_t *y);
/**
* @typedef auxdisplay_capabilities_get_t
* @brief Callback API to get details on the display
* See auxdisplay_capabilities_get() for argument description
*/
typedef int (*auxdisplay_capabilities_get_t)(const struct device *dev,
struct auxdisplay_capabilities *capabilities);
/**
* @typedef auxdisplay_clear_t
* @brief Callback API to clear the contents of the display
* See auxdisplay_clear() for argument description
*/
typedef int (*auxdisplay_clear_t)(const struct device *dev);
/**
* @typedef auxdisplay_brightness_get_t
* @brief Callback API to get the current and minimum/maximum supported
* brightness settings of the display
* See auxdisplay_brightness_get_api() for argument description
*/
typedef int (*auxdisplay_brightness_get_t)(const struct device *dev, uint8_t *brightness);
/**
* @typedef auxdisplay_brightness_set_t
* @brief Callback API to set the brightness of the display
* See auxdisplay_brightness_set_api() for argument description
*/
typedef int (*auxdisplay_brightness_set_t)(const struct device *dev, uint8_t brightness);
/**
* @typedef auxdisplay_backlight_get_t
* @brief Callback API to get the current and minimum/maximum supported
* backlight settings of the display
* See auxdisplay_backlight_set() for argument description
*/
typedef int (*auxdisplay_backlight_get_t)(const struct device *dev, uint8_t *backlight);
/**
* @typedef auxdisplay_backlight_set_t
* @brief Callback API to set the backlight status
* See auxdisplay_backlight_set() for argument description
*/
typedef int (*auxdisplay_backlight_set_t)(const struct device *dev, uint8_t backlight);
/**
* @typedef auxdisplay_is_busy_t
* @brief Callback API to check if the display is busy with an operation
* See auxdisplay_is_busy() for argument description
*/
typedef int (*auxdisplay_is_busy_t)(const struct device *dev);
/**
* @typedef auxdisplay_custom_character_set_t
* @brief Callback API to set a customer character on the display for usage
* See auxdisplay_custom_character_set() for argument description
*/
typedef int (*auxdisplay_custom_character_set_t)(const struct device *dev,
struct auxdisplay_character *character);
/**
* @typedef auxdisplay_write_t
* @brief Callback API to write text to the display
* See auxdisplay_write() for argument description
*/
typedef int (*auxdisplay_write_t)(const struct device *dev, const uint8_t *data, uint16_t len);
/**
* @typedef auxdisplay_custom_command_t
* @brief Callback API to send a custom command to the display
* See auxdisplay_custom_command() for argument description
*/
typedef int (*auxdisplay_custom_command_t)(const struct device *dev,
struct auxdisplay_custom_data *command);
struct auxdisplay_driver_api {
auxdisplay_display_on_t display_on;
auxdisplay_display_off_t display_off;
auxdisplay_cursor_set_enabled_t cursor_set_enabled;
auxdisplay_position_blinking_set_enabled_t position_blinking_set_enabled;
auxdisplay_cursor_shift_set_t cursor_shift_set;
auxdisplay_cursor_position_set_t cursor_position_set;
auxdisplay_cursor_position_get_t cursor_position_get;
auxdisplay_display_position_set_t display_position_set;
auxdisplay_display_position_get_t display_position_get;
auxdisplay_capabilities_get_t capabilities_get;
auxdisplay_clear_t clear;
auxdisplay_brightness_get_t brightness_get;
auxdisplay_brightness_set_t brightness_set;
auxdisplay_backlight_get_t backlight_get;
auxdisplay_backlight_set_t backlight_set;
auxdisplay_is_busy_t is_busy;
auxdisplay_custom_character_set_t custom_character_set;
auxdisplay_write_t write;
auxdisplay_custom_command_t custom_command;
};
/**
* @endcond
*/
/**
* @brief Turn display on.
*
* @param dev Auxiliary display device instance
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_display_on(const struct device *dev);
static inline int z_impl_auxdisplay_display_on(const struct device *dev)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->display_on) {
return -ENOSYS;
}
return api->display_on(dev);
}
/**
* @brief Turn display off.
*
* @param dev Auxiliary display device instance
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_display_off(const struct device *dev);
static inline int z_impl_auxdisplay_display_off(const struct device *dev)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->display_off) {
return -ENOSYS;
}
return api->display_off(dev);
}
/**
* @brief Set cursor enabled status on an auxiliary display
*
* @param dev Auxiliary display device instance
* @param enabled True to enable cursor, false to disable
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_cursor_set_enabled(const struct device *dev,
bool enabled);
static inline int z_impl_auxdisplay_cursor_set_enabled(const struct device *dev,
bool enabled)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->cursor_set_enabled) {
return -ENOSYS;
}
return api->cursor_set_enabled(dev, enabled);
}
/**
* @brief Set cursor blinking status on an auxiliary display
*
* @param dev Auxiliary display device instance
* @param enabled Set to true to enable blinking position, false to disable
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_position_blinking_set_enabled(const struct device *dev,
bool enabled);
static inline int z_impl_auxdisplay_position_blinking_set_enabled(const struct device *dev,
bool enabled)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->position_blinking_set_enabled) {
return -ENOSYS;
}
return api->position_blinking_set_enabled(dev, enabled);
}
/**
* @brief Set cursor shift after character write and display shift
*
* @param dev Auxiliary display device instance
* @param direction Sets the direction of the display when characters are written
* @param display_shift If true, will shift the display when characters are written
* (which makes it look like the display is moving, not the cursor)
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_cursor_shift_set(const struct device *dev,
uint8_t direction, bool display_shift);
static inline int z_impl_auxdisplay_cursor_shift_set(const struct device *dev,
uint8_t direction,
bool display_shift)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->cursor_shift_set) {
return -ENOSYS;
}
if (direction >= AUXDISPLAY_DIRECTION_COUNT) {
return -EINVAL;
}
return api->cursor_shift_set(dev, direction, display_shift);
}
/**
* @brief Set cursor (and write position) on an auxiliary display
*
* @param dev Auxiliary display device instance
* @param type Type of move, absolute or offset
* @param x Exact or offset X position
* @param y Exact or offset Y position
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_cursor_position_set(const struct device *dev,
enum auxdisplay_position type,
int16_t x, int16_t y);
static inline int z_impl_auxdisplay_cursor_position_set(const struct device *dev,
enum auxdisplay_position type,
int16_t x, int16_t y)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->cursor_position_set) {
return -ENOSYS;
} else if (type >= AUXDISPLAY_POSITION_COUNT) {
return -EINVAL;
} else if (type == AUXDISPLAY_POSITION_ABSOLUTE && (x < 0 || y < 0)) {
return -EINVAL;
}
return api->cursor_position_set(dev, type, x, y);
}
/**
* @brief Get current cursor on an auxiliary display
*
* @param dev Auxiliary display device instance
* @param x Will be updated with the exact X position
* @param y Will be updated with the exact Y position
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_cursor_position_get(const struct device *dev,
int16_t *x, int16_t *y);
static inline int z_impl_auxdisplay_cursor_position_get(const struct device *dev,
int16_t *x, int16_t *y)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->cursor_position_get) {
return -ENOSYS;
}
return api->cursor_position_get(dev, x, y);
}
/**
* @brief Set display position on an auxiliary display
*
* @param dev Auxiliary display device instance
* @param type Type of move, absolute or offset
* @param x Exact or offset X position
* @param y Exact or offset Y position
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_display_position_set(const struct device *dev,
enum auxdisplay_position type,
int16_t x, int16_t y);
static inline int z_impl_auxdisplay_display_position_set(const struct device *dev,
enum auxdisplay_position type,
int16_t x, int16_t y)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->display_position_set) {
return -ENOSYS;
} else if (type >= AUXDISPLAY_POSITION_COUNT) {
return -EINVAL;
} else if (type == AUXDISPLAY_POSITION_ABSOLUTE && (x < 0 || y < 0)) {
return -EINVAL;
}
return api->display_position_set(dev, type, x, y);
}
/**
* @brief Get current display position on an auxiliary display
*
* @param dev Auxiliary display device instance
* @param x Will be updated with the exact X position
* @param y Will be updated with the exact Y position
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_display_position_get(const struct device *dev,
int16_t *x, int16_t *y);
static inline int z_impl_auxdisplay_display_position_get(const struct device *dev,
int16_t *x, int16_t *y)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->display_position_get) {
return -ENOSYS;
}
return api->display_position_get(dev, x, y);
}
/**
* @brief Fetch capabilities (and details) of auxiliary display
*
* @param dev Auxiliary display device instance
* @param capabilities Will be updated with the details of the auxiliary display
*
* @retval 0 on success.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_capabilities_get(const struct device *dev,
struct auxdisplay_capabilities *capabilities);
static inline int z_impl_auxdisplay_capabilities_get(const struct device *dev,
struct auxdisplay_capabilities *capabilities)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
return api->capabilities_get(dev, capabilities);
}
/**
* @brief Clear display of auxiliary display and return to home position (note that
* this does not reset the display configuration, e.g. custom characters and
* display mode will persist).
*
* @param dev Auxiliary display device instance
*
* @retval 0 on success.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_clear(const struct device *dev);
static inline int z_impl_auxdisplay_clear(const struct device *dev)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
return api->clear(dev);
}
/**
* @brief Get the current brightness level of an auxiliary display
*
* @param dev Auxiliary display device instance
* @param brightness Will be updated with the current brightness
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_brightness_get(const struct device *dev,
uint8_t *brightness);
static inline int z_impl_auxdisplay_brightness_get(const struct device *dev,
uint8_t *brightness)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->brightness_get) {
return -ENOSYS;
}
return api->brightness_get(dev, brightness);
}
/**
* @brief Update the brightness level of an auxiliary display
*
* @param dev Auxiliary display device instance
* @param brightness The brightness level to set
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_brightness_set(const struct device *dev,
uint8_t brightness);
static inline int z_impl_auxdisplay_brightness_set(const struct device *dev,
uint8_t brightness)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->brightness_set) {
return -ENOSYS;
}
return api->brightness_set(dev, brightness);
}
/**
* @brief Get the backlight level details of an auxiliary display
*
* @param dev Auxiliary display device instance
* @param backlight Will be updated with the current backlight level
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_backlight_get(const struct device *dev,
uint8_t *backlight);
static inline int z_impl_auxdisplay_backlight_get(const struct device *dev,
uint8_t *backlight)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->backlight_get) {
return -ENOSYS;
}
return api->backlight_get(dev, backlight);
}
/**
* @brief Update the backlight level of an auxiliary display
*
* @param dev Auxiliary display device instance
* @param backlight The backlight level to set
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_backlight_set(const struct device *dev,
uint8_t backlight);
static inline int z_impl_auxdisplay_backlight_set(const struct device *dev,
uint8_t backlight)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->backlight_set) {
return -ENOSYS;
}
return api->backlight_set(dev, backlight);
}
/**
* @brief Check if an auxiliary display driver is busy
*
* @param dev Auxiliary display device instance
*
* @retval 1 on success and display busy.
* @retval 0 on success and display not busy.
* @retval -ENOSYS if not supported/implemented.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_is_busy(const struct device *dev);
static inline int z_impl_auxdisplay_is_busy(const struct device *dev)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->is_busy) {
return -ENOSYS;
}
return api->is_busy(dev);
}
/**
* @brief Sets a custom character in the display, the custom character struct
* must contain the pixel data for the custom character to add and valid
* custom character index, if successful then the character_code variable
* in the struct will be set to the character code that can be used with
* the auxdisplay_write() function to show it.
*
* A character must be valid for a display consisting of a uint8 array of
* size character width by character height, values should be 0x00 for
* pixel off or 0xff for pixel on, if a display supports shades then
* values between 0x00 and 0xff may be used (display driver dependent).
*
* @param dev Auxiliary display device instance
* @param character Pointer to custom character structure
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_custom_character_set(const struct device *dev,
struct auxdisplay_character *character);
static inline int z_impl_auxdisplay_custom_character_set(const struct device *dev,
struct auxdisplay_character *character)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->custom_character_set) {
return -ENOSYS;
}
return api->custom_character_set(dev, character);
}
/**
* @brief Write data to auxiliary display screen at current position
*
* @param dev Auxiliary display device instance
* @param data Text data to write
* @param len Length of text data to write
*
* @retval 0 on success.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_write(const struct device *dev, const uint8_t *data,
uint16_t len);
static inline int z_impl_auxdisplay_write(const struct device *dev,
const uint8_t *data, uint16_t len)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
return api->write(dev, data, len);
}
/**
* @brief Send a custom command to the display (if supported by driver)
*
* @param dev Auxiliary display device instance
* @param data Custom command structure (this may be extended by specific drivers)
*
* @retval 0 on success.
* @retval -ENOSYS if not supported/implemented.
* @retval -EINVAL if provided argument is invalid.
* @retval -errno Negative errno code on other failure.
*/
__syscall int auxdisplay_custom_command(const struct device *dev,
struct auxdisplay_custom_data *data);
static inline int z_impl_auxdisplay_custom_command(const struct device *dev,
struct auxdisplay_custom_data *data)
{
struct auxdisplay_driver_api *api = (struct auxdisplay_driver_api *)dev->api;
if (!api->custom_command) {
return -ENOSYS;
}
return api->custom_command(dev, data);
}
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#include <syscalls/auxdisplay.h>
#endif /* ZEPHYR_INCLUDE_DRIVERS_AUXDISPLAY_H_ */