New kernel drivers and more (#560)
- Added kernel base drivers for: display, pointer (touch, mouse, etc.), keyboard, adc, power supply and backlight - Implement new kernel driver modules: `st7789-module` and `gt911-module` - Implement ESP32 ADC "oneshot" kernel driver - Implement ESP32 backlight kernel driver with ledc API - Implemented `battery-sense` driver that allows for voltage measurement and creates a power supply child device - Updated github actions - Updated flash scripts - Fix for esp32 legacy driver conflict with ADC - Created separate `lilygo-tdeck` and `lilygo-tdeck-plus` devices - Created `lilygo-module` with LilyGO kernel drivers - Fix for intermittent errors in build related to code generation of `devicetree.c` - `lvgl-module` can now map kernel drivers onto LVGL devices - Created `KernelDisplayApp` as a mirror of `HalDisplayApp` (formerly `DisplayApp`) - Removed `struct` and `enum` prefix in a lot of kernel driver cpp source files - `lilygo-tdeck` and `lilygo-tdeck-plus` are now fully relying on kernel drivers and don't use any of the old HAL
This commit is contained in:
committed by
GitHub
parent
c4406b24ba
commit
50c0a14a93
@@ -0,0 +1 @@
|
||||
description: ADC controller
|
||||
@@ -0,0 +1,19 @@
|
||||
description: Battery voltage sense via an ADC channel behind a voltage divider
|
||||
|
||||
compatible: "battery-sense"
|
||||
|
||||
properties:
|
||||
io-channel:
|
||||
type: phandles
|
||||
required: true
|
||||
description: The ADC object paired with a channel index e.g. `<&adc1 3>`
|
||||
reference-voltage-mv:
|
||||
type: int
|
||||
required: true
|
||||
description: The ADC's effective full-scale reference voltage at the channel's configured attenuation, in mV.
|
||||
multiplier:
|
||||
type: int
|
||||
default: 1000
|
||||
description: |
|
||||
Voltage divider correction factor, fixed-point with 3 decimals (1000 = 1.000, i.e. no division).
|
||||
battery_mv = adc_mv * multiplier / 1000.
|
||||
@@ -0,0 +1,5 @@
|
||||
description: Pointer placeholder
|
||||
|
||||
compatible: "pointer-placeholder"
|
||||
|
||||
properties: {}
|
||||
@@ -1,5 +0,0 @@
|
||||
description: Touch placeholder
|
||||
|
||||
compatible: "touch-placeholder"
|
||||
|
||||
properties: {}
|
||||
+2
-2
@@ -2,13 +2,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/bindings/bindings.h>
|
||||
#include <tactility/drivers/touch_placeholder.h>
|
||||
#include <tactility/drivers/battery_sense.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICETREE(touch_placeholder, struct TouchPlaceholderConfig)
|
||||
DEFINE_DEVICETREE(battery_sense, struct BatterySenseConfig)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tactility/bindings/bindings.h>
|
||||
#include <tactility/drivers/pointer_placeholder.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICETREE(pointer_placeholder, struct PointerPlaceholderConfig)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct Device;
|
||||
|
||||
#define ADC_CHANNEL_SPEC_NONE ((struct AdcChannelSpec) { NULL, 0 })
|
||||
|
||||
/** The index of a channel on an ADC controller */
|
||||
typedef uint8_t adc_channel_index_t;
|
||||
|
||||
/**
|
||||
* Specifies a channel on a specific ADC controller.
|
||||
* Used by the devicetree, drivers and application code to refer to ADC channels.
|
||||
*/
|
||||
struct AdcChannelSpec {
|
||||
/** ADC device controlling the channel */
|
||||
struct Device* adc_controller;
|
||||
/** The channel's index on the device */
|
||||
adc_channel_index_t channel;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
#include <tactility/freertos/freertos.h>
|
||||
#include <tactility/error.h>
|
||||
|
||||
struct Device;
|
||||
|
||||
/**
|
||||
* @brief API for ADC controller drivers.
|
||||
*/
|
||||
struct AdcControllerApi {
|
||||
/**
|
||||
* @brief Reads the raw conversion result of an ADC channel.
|
||||
* @param[in] device the ADC controller device
|
||||
* @param[in] channel the channel index to read
|
||||
* @param[out] out_raw the raw conversion result
|
||||
* @param[in] timeout the maximum time to wait for the operation to complete
|
||||
* @retval ERROR_NONE when the read operation was successful
|
||||
* @retval ERROR_OUT_OF_RANGE when the channel index is not configured
|
||||
* @retval ERROR_TIMEOUT when the operation timed out
|
||||
*/
|
||||
error_t (*read_raw)(struct Device* device, uint8_t channel, int* out_raw, TickType_t timeout);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Reads the raw conversion result of an ADC channel using the specified controller.
|
||||
* @param[in] device the ADC controller device
|
||||
* @param[in] channel the channel index to read
|
||||
* @param[out] out_raw the raw conversion result
|
||||
* @param[in] timeout the maximum time to wait for the operation to complete
|
||||
* @retval ERROR_NONE when the read operation was successful
|
||||
*/
|
||||
error_t adc_controller_read_raw(struct Device* device, uint8_t channel, int* out_raw, TickType_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Reads the raw conversion result of the ADC channel described by the given spec.
|
||||
* @param[in] spec the channel spec, as acquired from a devicetree phandle reference (e.g. `<&adc0 3>`)
|
||||
* @param[out] out_raw the raw conversion result
|
||||
* @param[in] timeout the maximum time to wait for the operation to complete
|
||||
* @retval ERROR_NONE when the read operation was successful
|
||||
*/
|
||||
error_t adc_channel_read_raw(const struct AdcChannelSpec* spec, int* out_raw, TickType_t timeout);
|
||||
|
||||
extern const struct DeviceType ADC_CONTROLLER_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/error.h>
|
||||
|
||||
/**
|
||||
* @brief Inclusive range of brightness levels accepted by a backlight driver.
|
||||
*/
|
||||
struct BrightnessLevelRange {
|
||||
uint8_t min;
|
||||
uint8_t max;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief API for backlight drivers.
|
||||
*
|
||||
* @note The minimum brightness level (see get_min_brightness()) turns the backlight fully off.
|
||||
* There is no separate on/off control: to turn the backlight off, call set_brightness() with
|
||||
* the minimum value; to turn it back on, set any value above the minimum.
|
||||
*/
|
||||
struct BacklightApi {
|
||||
/**
|
||||
* @brief Sets the backlight brightness.
|
||||
* @param[in] device the backlight device
|
||||
* @param[in] brightness the brightness level, expected to be within [get_min_brightness(), get_max_brightness()]
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_brightness)(struct Device* device, uint8_t brightness);
|
||||
|
||||
/**
|
||||
* @brief Sets the backlight brightness to its devicetree-configured default level.
|
||||
* @param[in] device the backlight device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_brightness_default)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the current backlight brightness.
|
||||
* @param[in] device the backlight device
|
||||
* @param[out] out_brightness the current brightness level
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*get_brightness)(struct Device* device, uint8_t* out_brightness);
|
||||
|
||||
/**
|
||||
* @brief Gets the minimum brightness level. Setting the brightness to this value turns the backlight off.
|
||||
* @param[in] device the backlight device
|
||||
* @return the minimum brightness level
|
||||
*/
|
||||
uint8_t (*get_min_brightness)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the maximum (full-strength) brightness level.
|
||||
* @param[in] device the backlight device
|
||||
* @return the maximum brightness level
|
||||
*/
|
||||
uint8_t (*get_max_brightness)(struct Device* device);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Sets the backlight brightness using the specified backlight device.
|
||||
*/
|
||||
error_t backlight_set_brightness(struct Device* device, uint8_t brightness);
|
||||
|
||||
/**
|
||||
* @brief Sets the backlight brightness to its devicetree-configured default level using the specified backlight device.
|
||||
*/
|
||||
error_t backlight_set_brightness_default(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the current backlight brightness using the specified backlight device.
|
||||
*/
|
||||
error_t backlight_get_brightness(struct Device* device, uint8_t* out_brightness);
|
||||
|
||||
/**
|
||||
* @brief Gets the minimum brightness level using the specified backlight device. This level turns the backlight off.
|
||||
*/
|
||||
uint8_t backlight_get_min_brightness(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the maximum brightness level using the specified backlight device.
|
||||
*/
|
||||
uint8_t backlight_get_max_brightness(struct Device* device);
|
||||
|
||||
extern const struct DeviceType BACKLIGHT_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tactility/drivers/adc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct BatterySenseConfig {
|
||||
/** The ADC channel connected to the battery sense circuit */
|
||||
struct AdcChannelSpec io_channel;
|
||||
/** The ADC's effective full-scale reference voltage at the channel's configured attenuation, in mV */
|
||||
uint32_t reference_voltage_mv;
|
||||
/** Voltage divider correction factor, fixed-point with 3 decimals (1000 = 1.000, i.e. no division) */
|
||||
uint32_t multiplier;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -5,7 +5,253 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/error.h>
|
||||
|
||||
/**
|
||||
* @brief Pixel color formats supported by display panel drivers.
|
||||
*/
|
||||
enum DisplayColorFormat {
|
||||
DISPLAY_COLOR_FORMAT_MONOCHROME = 0x0, // 1 bpp
|
||||
DISPLAY_COLOR_FORMAT_BGR565 = 0x1,
|
||||
DISPLAY_COLOR_FORMAT_BGR565_SWAPPED = 0x2,
|
||||
DISPLAY_COLOR_FORMAT_RGB565 = 0x3,
|
||||
DISPLAY_COLOR_FORMAT_RGB565_SWAPPED = 0x4,
|
||||
DISPLAY_COLOR_FORMAT_RGB888 = 0x5,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief API for display panel drivers.
|
||||
*/
|
||||
struct DisplayApi {
|
||||
/**
|
||||
* @brief Performs a hardware reset of the panel (e.g. toggling a reset GPIO).
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*reset)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Sends the panel's initialization command sequence. Call after reset().
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*init)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Draws pixel data into the given rectangle.
|
||||
* @param[in] device the display device
|
||||
* @param[in] x_start left edge (inclusive)
|
||||
* @param[in] y_start top edge (inclusive)
|
||||
* @param[in] x_end right edge (exclusive)
|
||||
* @param[in] y_end bottom edge (exclusive)
|
||||
* @param[in] color_data pixel data in the panel's configured color format
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*draw_bitmap)(struct Device* device, int32_t x_start, int32_t y_start, int32_t x_end, int32_t y_end, const void* color_data);
|
||||
|
||||
/**
|
||||
* @brief Mirrors the image along the X and/or Y axis.
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*mirror)(struct Device* device, bool x_axis, bool y_axis);
|
||||
|
||||
/**
|
||||
* @brief Swaps the X and Y axes (rotates the coordinate system).
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*swap_xy)(struct Device* device, bool swap_axes);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X and Y axes are currently swapped.
|
||||
* @param[in] device the display device
|
||||
* @return true if swapped
|
||||
*/
|
||||
bool (*get_swap_xy)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X axis is currently mirrored.
|
||||
* @param[in] device the display device
|
||||
* @return true if mirrored
|
||||
*/
|
||||
bool (*get_mirror_x)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the Y axis is currently mirrored.
|
||||
* @param[in] device the display device
|
||||
* @return true if mirrored
|
||||
*/
|
||||
bool (*get_mirror_y)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Sets a coordinate offset applied to all draw operations.
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_gap)(struct Device* device, int32_t x_gap, int32_t y_gap);
|
||||
|
||||
/**
|
||||
* @brief Inverts the panel's color output.
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*invert_color)(struct Device* device, bool invert_color_data);
|
||||
|
||||
/**
|
||||
* @brief Turns the panel's display output on or off.
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*disp_on_off)(struct Device* device, bool on_off);
|
||||
|
||||
/**
|
||||
* @brief Puts the panel into or out of its low-power sleep mode.
|
||||
* @param[in] device the display device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*disp_sleep)(struct Device* device, bool sleep);
|
||||
|
||||
/**
|
||||
* @brief Gets the panel's pixel color format.
|
||||
* @param[in] device the display device
|
||||
* @return the color format
|
||||
*/
|
||||
enum DisplayColorFormat (*get_color_format)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the panel's horizontal resolution in pixels.
|
||||
* @param[in] device the display device
|
||||
* @return the horizontal resolution
|
||||
*/
|
||||
uint16_t (*get_resolution_x)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the panel's vertical resolution in pixels.
|
||||
* @param[in] device the display device
|
||||
* @return the vertical resolution
|
||||
*/
|
||||
uint16_t (*get_resolution_y)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets a pointer to one of the panel's frame buffers, for panels that expose direct frame buffer access.
|
||||
* @param[in] device the display device
|
||||
* @param[in] index the frame buffer index (see get_frame_buffer_count())
|
||||
* @param[out] out_buffer the buffer pointer
|
||||
*/
|
||||
void (*get_frame_buffer)(struct Device* device, uint8_t index, void** out_buffer);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of frame buffers exposed by the panel via get_frame_buffer(). 0 when unsupported.
|
||||
* @param[in] device the display device
|
||||
* @return the frame buffer count
|
||||
*/
|
||||
uint8_t (*get_frame_buffer_count)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the backlight device associated with this display, if any.
|
||||
* @param[in] device the display device
|
||||
* @param[out] backlight the associated backlight device
|
||||
* @retval ERROR_NONE when a backlight is available and *backlight was set
|
||||
* @retval ERROR_NOT_SUPPORTED when this display has no associated backlight
|
||||
*/
|
||||
error_t (*get_backlight)(struct Device* device, struct Device** backlight);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Performs a hardware reset of the panel using the specified display.
|
||||
*/
|
||||
error_t display_reset(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Sends the panel's initialization command sequence using the specified display.
|
||||
*/
|
||||
error_t display_init(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Draws pixel data into the given rectangle using the specified display.
|
||||
*/
|
||||
error_t display_draw_bitmap(struct Device* device, int32_t x_start, int32_t y_start, int32_t x_end, int32_t y_end, const void* color_data);
|
||||
|
||||
/**
|
||||
* @brief Mirrors the image along the X and/or Y axis using the specified display.
|
||||
*/
|
||||
error_t display_mirror(struct Device* device, bool x_axis, bool y_axis);
|
||||
|
||||
/**
|
||||
* @brief Swaps the X and Y axes using the specified display.
|
||||
*/
|
||||
error_t display_swap_xy(struct Device* device, bool swap_axes);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X and Y axes are currently swapped using the specified display.
|
||||
*/
|
||||
bool display_get_swap_xy(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X axis is currently mirrored using the specified display.
|
||||
*/
|
||||
bool display_get_mirror_x(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the Y axis is currently mirrored using the specified display.
|
||||
*/
|
||||
bool display_get_mirror_y(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Sets a coordinate offset applied to all draw operations using the specified display.
|
||||
*/
|
||||
error_t display_set_gap(struct Device* device, int32_t x_gap, int32_t y_gap);
|
||||
|
||||
/**
|
||||
* @brief Inverts the panel's color output using the specified display.
|
||||
*/
|
||||
error_t display_invert_color(struct Device* device, bool invert_color_data);
|
||||
|
||||
/**
|
||||
* @brief Turns the panel's display output on or off using the specified display.
|
||||
*/
|
||||
error_t display_disp_on_off(struct Device* device, bool on_off);
|
||||
|
||||
/**
|
||||
* @brief Puts the panel into or out of its low-power sleep mode using the specified display.
|
||||
*/
|
||||
error_t display_disp_sleep(struct Device* device, bool sleep);
|
||||
|
||||
/**
|
||||
* @brief Gets the pixel color format using the specified display.
|
||||
*/
|
||||
enum DisplayColorFormat display_get_color_format(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the horizontal resolution in pixels using the specified display.
|
||||
*/
|
||||
uint16_t display_get_resolution_x(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the vertical resolution in pixels using the specified display.
|
||||
*/
|
||||
uint16_t display_get_resolution_y(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets a pointer to one of the panel's frame buffers using the specified display.
|
||||
*/
|
||||
void display_get_frame_buffer(struct Device* device, uint8_t index, void** out_buffer);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of frame buffers exposed by the panel using the specified display.
|
||||
*/
|
||||
uint8_t display_get_frame_buffer_count(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Gets the backlight device associated with the specified display, if any.
|
||||
* @retval ERROR_NONE when a backlight is available and *backlight was set
|
||||
* @retval ERROR_NOT_SUPPORTED when the display has no associated backlight
|
||||
*/
|
||||
error_t display_get_backlight(struct Device* device, struct Device** backlight);
|
||||
|
||||
extern const struct DeviceType DISPLAY_TYPE;
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/error.h>
|
||||
|
||||
/**
|
||||
* @brief A single key event read from a keyboard device.
|
||||
*/
|
||||
struct KeyboardKeyData {
|
||||
/** @brief The key code. Driver-defined (e.g. ASCII/UTF-8 codepoint, scan code, or LVGL key code). */
|
||||
uint32_t key;
|
||||
/** @brief True if the key was pressed, false if released. */
|
||||
bool pressed;
|
||||
/**
|
||||
* @brief True if another key event is already queued and read_key() should be called again
|
||||
* immediately to drain it. False if this was the last pending event.
|
||||
*/
|
||||
bool continue_reading;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief API for keyboard drivers.
|
||||
*/
|
||||
struct KeyboardApi {
|
||||
/**
|
||||
* @brief Reads the next pending key event, if any.
|
||||
* @param[in] device the keyboard device
|
||||
* @param[out] data the key event data
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*read_key)(struct Device* device, struct KeyboardKeyData* data);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Reads the next pending key event using the specified keyboard device.
|
||||
*/
|
||||
error_t keyboard_read_key(struct Device* device, struct KeyboardKeyData* data);
|
||||
|
||||
extern const struct DeviceType KEYBOARD_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,151 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/error.h>
|
||||
#include <tactility/freertos/freertos.h>
|
||||
|
||||
/**
|
||||
* @brief API for pointer controller drivers.
|
||||
*/
|
||||
struct PointerApi {
|
||||
/**
|
||||
* @brief Puts the pointer controller into its low-power sleep mode.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*enter_sleep)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Wakes the pointer controller from sleep mode.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*exit_sleep)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Performs a blocking read of the latest touch data from the controller into its internal state.
|
||||
* Call this before get_touched_points().
|
||||
* @param[in] device the pointer device
|
||||
* @param[in] timeout the maximum time to wait for the operation to complete
|
||||
* @retval ERROR_NONE when the read operation was successful
|
||||
* @retval ERROR_TIMEOUT when the operation timed out
|
||||
*/
|
||||
error_t (*read_data)(struct Device* device, TickType_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the coordinates most recently read by read_data().
|
||||
* @param[in] device the pointer device
|
||||
* @param[out] x array of X coordinates
|
||||
* @param[out] y array of Y coordinates
|
||||
* @param[out] strength optional array of touch strengths (nullable)
|
||||
* @param[out] point_count the number of points currently touched
|
||||
* @param[in] max_point_count the maximum number of points the arrays can hold
|
||||
* @return true when touched and coordinates are available
|
||||
*/
|
||||
bool (*get_touched_points)(struct Device* device, uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* point_count, uint8_t max_point_count);
|
||||
|
||||
/**
|
||||
* @brief Sets whether the X and Y axes should be swapped.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_swap_xy)(struct Device* device, bool swap);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X and Y axes are swapped.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*get_swap_xy)(struct Device* device, bool* swap);
|
||||
|
||||
/**
|
||||
* @brief Sets whether the X axis should be mirrored.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_mirror_x)(struct Device* device, bool mirror);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X axis is mirrored.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*get_mirror_x)(struct Device* device, bool* mirror);
|
||||
|
||||
/**
|
||||
* @brief Sets whether the Y axis should be mirrored.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_mirror_y)(struct Device* device, bool mirror);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the Y axis is mirrored.
|
||||
* @param[in] device the pointer device
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*get_mirror_y)(struct Device* device, bool* mirror);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Puts the pointer controller into its low-power sleep mode using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_enter_sleep(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Wakes the pointer controller from sleep mode using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_exit_sleep(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Performs a blocking read of the latest touch data using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_read_data(struct Device* device, TickType_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the coordinates most recently read using the specified pointer device.
|
||||
*/
|
||||
bool pointer_get_touched_points(struct Device* device, uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* point_count, uint8_t max_point_count);
|
||||
|
||||
/**
|
||||
* @brief Sets whether the X and Y axes should be swapped using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_set_swap_xy(struct Device* device, bool swap);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X and Y axes are swapped using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_get_swap_xy(struct Device* device, bool* swap);
|
||||
|
||||
/**
|
||||
* @brief Sets whether the X axis should be mirrored using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_set_mirror_x(struct Device* device, bool mirror);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the X axis is mirrored using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_get_mirror_x(struct Device* device, bool* mirror);
|
||||
|
||||
/**
|
||||
* @brief Sets whether the Y axis should be mirrored using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_set_mirror_y(struct Device* device, bool mirror);
|
||||
|
||||
/**
|
||||
* @brief Gets whether the Y axis is mirrored using the specified pointer device.
|
||||
*/
|
||||
error_t pointer_get_mirror_y(struct Device* device, bool* mirror);
|
||||
|
||||
extern const struct DeviceType POINTER_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct TouchPlaceholderConfig {
|
||||
struct PointerPlaceholderConfig {
|
||||
uint8_t _unused;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/error.h>
|
||||
|
||||
/**
|
||||
* @brief Properties that a power supply device can report.
|
||||
*/
|
||||
enum PowerSupplyProperty {
|
||||
/** [0, 1]: whether the battery is currently charging */
|
||||
POWER_SUPPLY_PROP_IS_CHARGING,
|
||||
/** mA: battery current, positive while charging, negative while discharging */
|
||||
POWER_SUPPLY_PROP_CURRENT,
|
||||
/** mV: battery voltage */
|
||||
POWER_SUPPLY_PROP_VOLTAGE,
|
||||
/** [0, 100]: battery charge level */
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Holds the value of a single power supply property.
|
||||
*/
|
||||
union PowerSupplyPropertyValue {
|
||||
int int_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief API for power supply drivers.
|
||||
*
|
||||
* @note supports_charge_control(), supports_quick_charge() and supports_power_off() gate
|
||||
* their respective functions: when a capability is not supported, the driver's implementation
|
||||
* of the related getter/setter is expected to be a NO-OP (getters returning false/0).
|
||||
*/
|
||||
struct PowerSupplyApi {
|
||||
/**
|
||||
* @brief Checks whether a property is supported by this device.
|
||||
* @param[in] device the power supply device
|
||||
* @param[in] property the property to check
|
||||
* @return true if the property is supported
|
||||
*/
|
||||
bool (*supports_property)(struct Device* device, enum PowerSupplyProperty property);
|
||||
|
||||
/**
|
||||
* @brief Gets the current value of a property.
|
||||
* @param[in] device the power supply device
|
||||
* @param[in] property the property to read
|
||||
* @param[out] out_value the property value
|
||||
* @retval ERROR_NOT_SUPPORTED when the property is not supported
|
||||
* @retval ERROR_NOT_FOUND when the property is (temporarily) not available
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*get_property)(struct Device* device, enum PowerSupplyProperty property, union PowerSupplyPropertyValue* out_value);
|
||||
|
||||
/**
|
||||
* @brief Checks whether this device supports enabling/disabling charging.
|
||||
*/
|
||||
bool (*supports_charge_control)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Checks whether charging is currently allowed.
|
||||
*/
|
||||
bool (*is_allowed_to_charge)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Enables or disables charging.
|
||||
* @retval ERROR_NOT_SUPPORTED when charge control is not supported
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_allowed_to_charge)(struct Device* device, bool allowed);
|
||||
|
||||
/**
|
||||
* @brief Checks whether this device supports quick charging.
|
||||
*/
|
||||
bool (*supports_quick_charge)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Checks whether quick charging is currently enabled.
|
||||
*/
|
||||
bool (*is_quick_charge_enabled)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Enables or disables quick charging.
|
||||
* @retval ERROR_NOT_SUPPORTED when quick charging is not supported
|
||||
* @retval ERROR_NONE when the operation was successful
|
||||
*/
|
||||
error_t (*set_quick_charge_enabled)(struct Device* device, bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Checks whether this device can power off the system.
|
||||
*/
|
||||
bool (*supports_power_off)(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Powers off the system.
|
||||
* @retval ERROR_NOT_SUPPORTED when power off is not supported
|
||||
* @retval ERROR_NONE when the operation was successful (this call typically does not return)
|
||||
*/
|
||||
error_t (*power_off)(struct Device* device);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Checks whether a property is supported using the specified power supply device.
|
||||
*/
|
||||
bool power_supply_supports_property(struct Device* device, enum PowerSupplyProperty property);
|
||||
|
||||
/**
|
||||
* @brief Gets the current value of a property using the specified power supply device.
|
||||
*/
|
||||
error_t power_supply_get_property(struct Device* device, enum PowerSupplyProperty property, union PowerSupplyPropertyValue* out_value);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified power supply device supports enabling/disabling charging.
|
||||
*/
|
||||
bool power_supply_supports_charge_control(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Checks whether charging is currently allowed on the specified power supply device.
|
||||
*/
|
||||
bool power_supply_is_allowed_to_charge(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Enables or disables charging on the specified power supply device.
|
||||
*/
|
||||
error_t power_supply_set_allowed_to_charge(struct Device* device, bool allowed);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified power supply device supports quick charging.
|
||||
*/
|
||||
bool power_supply_supports_quick_charge(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Checks whether quick charging is currently enabled on the specified power supply device.
|
||||
*/
|
||||
bool power_supply_is_quick_charge_enabled(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Enables or disables quick charging on the specified power supply device.
|
||||
*/
|
||||
error_t power_supply_set_quick_charge_enabled(struct Device* device, bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified power supply device can power off the system.
|
||||
*/
|
||||
bool power_supply_supports_power_off(struct Device* device);
|
||||
|
||||
/**
|
||||
* @brief Powers off the system using the specified power supply device.
|
||||
*/
|
||||
error_t power_supply_power_off(struct Device* device);
|
||||
|
||||
extern const struct DeviceType POWER_SUPPLY_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,14 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <tactility/device.h>
|
||||
|
||||
extern const struct DeviceType TOUCH_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/adc_controller.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#define ADC_CONTROLLER_DRIVER_API(driver) ((struct AdcControllerApi*)driver->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t adc_controller_read_raw(Device* device, uint8_t channel, int* out_raw, TickType_t timeout) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return ADC_CONTROLLER_DRIVER_API(driver)->read_raw(device, channel, out_raw, timeout);
|
||||
}
|
||||
|
||||
error_t adc_channel_read_raw(const struct AdcChannelSpec* spec, int* out_raw, TickType_t timeout) {
|
||||
return adc_controller_read_raw(spec->adc_controller, spec->channel, out_raw, timeout);
|
||||
}
|
||||
|
||||
const struct DeviceType ADC_CONTROLLER_TYPE {
|
||||
.name = "adc-controller"
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/backlight.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#define BACKLIGHT_DRIVER_API(driver) ((struct BacklightApi*)driver->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t backlight_set_brightness(Device* device, uint8_t brightness) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return BACKLIGHT_DRIVER_API(driver)->set_brightness(device, brightness);
|
||||
}
|
||||
|
||||
error_t backlight_set_brightness_default(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return BACKLIGHT_DRIVER_API(driver)->set_brightness_default(device);
|
||||
}
|
||||
|
||||
error_t backlight_get_brightness(Device* device, uint8_t* out_brightness) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return BACKLIGHT_DRIVER_API(driver)->get_brightness(device, out_brightness);
|
||||
}
|
||||
|
||||
uint8_t backlight_get_min_brightness(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return BACKLIGHT_DRIVER_API(driver)->get_min_brightness(device);
|
||||
}
|
||||
|
||||
uint8_t backlight_get_max_brightness(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return BACKLIGHT_DRIVER_API(driver)->get_max_brightness(device);
|
||||
}
|
||||
|
||||
const DeviceType BACKLIGHT_TYPE {
|
||||
.name = "backlight"
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/check.h>
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/drivers/adc_controller.h>
|
||||
#include <tactility/drivers/battery_sense.h>
|
||||
#include <tactility/drivers/power_supply.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
// Raw-to-millivolt conversion assumes a 12-bit ADC, since the generic ADC API doesn't expose resolution.
|
||||
#define ADC_MAX_RAW 4095
|
||||
|
||||
// Rough LiPo discharge curve, used to estimate a charge percentage from the sensed voltage since
|
||||
// this driver has no calibrated fuel gauge to read one from directly.
|
||||
#define BATTERY_MIN_MV 3200
|
||||
#define BATTERY_MAX_MV 4200
|
||||
|
||||
// The power-supply child's config pointer isn't set; it reads its settings from its parent's config instead.
|
||||
#define GET_PARENT_CONFIG(device) ((const BatterySenseConfig*)device_get_parent(device)->config)
|
||||
|
||||
extern "C" {
|
||||
|
||||
static bool supports_property(Device*, PowerSupplyProperty property) {
|
||||
return property == POWER_SUPPLY_PROP_VOLTAGE || property == POWER_SUPPLY_PROP_CAPACITY;
|
||||
}
|
||||
|
||||
static error_t read_battery_mv(Device* device, int* out_mv) {
|
||||
const auto* config = GET_PARENT_CONFIG(device);
|
||||
int raw;
|
||||
error_t error = adc_channel_read_raw(&config->io_channel, &raw, portMAX_DELAY);
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
int64_t adc_mv = ((int64_t)raw * config->reference_voltage_mv) / ADC_MAX_RAW;
|
||||
*out_mv = (int)((adc_mv * config->multiplier) / 1000);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static int estimate_capacity_from_mv(int battery_mv) {
|
||||
if (battery_mv <= BATTERY_MIN_MV) return 0;
|
||||
if (battery_mv >= BATTERY_MAX_MV) return 100;
|
||||
return (battery_mv - BATTERY_MIN_MV) * 100 / (BATTERY_MAX_MV - BATTERY_MIN_MV);
|
||||
}
|
||||
|
||||
static error_t get_property(Device* device, PowerSupplyProperty property, PowerSupplyPropertyValue* out_value) {
|
||||
if (property != POWER_SUPPLY_PROP_VOLTAGE && property != POWER_SUPPLY_PROP_CAPACITY) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int battery_mv;
|
||||
error_t error = read_battery_mv(device, &battery_mv);
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
out_value->int_value = (property == POWER_SUPPLY_PROP_VOLTAGE) ? battery_mv : estimate_capacity_from_mv(battery_mv);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static bool supports_charge_control(Device*) { return false; }
|
||||
static bool is_allowed_to_charge(Device*) { return false; }
|
||||
static error_t set_allowed_to_charge(Device*, bool) { return ERROR_NOT_SUPPORTED; }
|
||||
static bool supports_quick_charge(Device*) { return false; }
|
||||
static bool is_quick_charge_enabled(Device*) { return false; }
|
||||
static error_t set_quick_charge_enabled(Device*, bool) { return ERROR_NOT_SUPPORTED; }
|
||||
static bool supports_power_off(Device*) { return false; }
|
||||
static error_t power_off(Device*) { return ERROR_NOT_SUPPORTED; }
|
||||
|
||||
static constexpr PowerSupplyApi BATTERY_SENSE_POWER_SUPPLY_API = {
|
||||
.supports_property = supports_property,
|
||||
.get_property = get_property,
|
||||
.supports_charge_control = supports_charge_control,
|
||||
.is_allowed_to_charge = is_allowed_to_charge,
|
||||
.set_allowed_to_charge = set_allowed_to_charge,
|
||||
.supports_quick_charge = supports_quick_charge,
|
||||
.is_quick_charge_enabled = is_quick_charge_enabled,
|
||||
.set_quick_charge_enabled = set_quick_charge_enabled,
|
||||
.supports_power_off = supports_power_off,
|
||||
.power_off = power_off,
|
||||
};
|
||||
|
||||
// Registered (driver_construct_add() in kernel_init.cpp) so driver_bind() has a valid ->internal,
|
||||
// but never matched against a devicetree node: battery_sense_driver wires it up directly by pointer.
|
||||
Driver battery_sense_power_supply_driver = {
|
||||
.name = "battery-sense-power-supply",
|
||||
.compatible = (const char*[]) { "battery-sense-power-supply", nullptr },
|
||||
.start_device = nullptr,
|
||||
.stop_device = nullptr,
|
||||
.api = &BATTERY_SENSE_POWER_SUPPLY_API,
|
||||
.device_type = &POWER_SUPPLY_TYPE,
|
||||
.owner = nullptr,
|
||||
.internal = nullptr
|
||||
};
|
||||
|
||||
struct BatterySenseInternal {
|
||||
Device* power_supply_device = nullptr;
|
||||
};
|
||||
|
||||
static error_t create_power_supply_child(Device* parent, Device*& out_child) {
|
||||
auto* child = new(std::nothrow) Device { .address = 0, .name = "battery-sense-power-supply", .config = nullptr, .parent = nullptr, .internal = nullptr };
|
||||
if (child == nullptr) {
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
error_t error = device_construct(child);
|
||||
if (error != ERROR_NONE) {
|
||||
delete child;
|
||||
return error;
|
||||
}
|
||||
|
||||
device_set_parent(child, parent);
|
||||
device_set_driver(child, &battery_sense_power_supply_driver);
|
||||
|
||||
error = device_add(child);
|
||||
if (error != ERROR_NONE) {
|
||||
device_destruct(child);
|
||||
delete child;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = device_start(child);
|
||||
if (error != ERROR_NONE) {
|
||||
device_remove(child);
|
||||
device_destruct(child);
|
||||
delete child;
|
||||
return error;
|
||||
}
|
||||
|
||||
out_child = child;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static void destroy_power_supply_child(Device* child) {
|
||||
check(device_stop(child) == ERROR_NONE);
|
||||
check(device_remove(child) == ERROR_NONE);
|
||||
check(device_destruct(child) == ERROR_NONE);
|
||||
delete child;
|
||||
}
|
||||
|
||||
static error_t start(Device* device) {
|
||||
auto* internal = new(std::nothrow) BatterySenseInternal();
|
||||
if (internal == nullptr) {
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
error_t error = create_power_supply_child(device, internal->power_supply_device);
|
||||
if (error != ERROR_NONE) {
|
||||
delete internal;
|
||||
return error;
|
||||
}
|
||||
|
||||
device_set_driver_data(device, internal);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t stop(Device* device) {
|
||||
auto* internal = (BatterySenseInternal*)device_get_driver_data(device);
|
||||
destroy_power_supply_child(internal->power_supply_device);
|
||||
device_set_driver_data(device, nullptr);
|
||||
delete internal;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
Driver battery_sense_driver = {
|
||||
.name = "battery-sense",
|
||||
.compatible = (const char*[]) { "battery-sense", nullptr },
|
||||
.start_device = start,
|
||||
.stop_device = stop,
|
||||
.api = nullptr,
|
||||
.device_type = nullptr,
|
||||
.owner = nullptr,
|
||||
.internal = nullptr
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,8 +1,101 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/display.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#define DISPLAY_DRIVER_API(driver) ((struct DisplayApi*)driver->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t display_reset(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->reset(device);
|
||||
}
|
||||
|
||||
error_t display_init(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->init(device);
|
||||
}
|
||||
|
||||
error_t display_draw_bitmap(Device* device, int32_t x_start, int32_t y_start, int32_t x_end, int32_t y_end, const void* color_data) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->draw_bitmap(device, x_start, y_start, x_end, y_end, color_data);
|
||||
}
|
||||
|
||||
error_t display_mirror(Device* device, bool x_axis, bool y_axis) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->mirror(device, x_axis, y_axis);
|
||||
}
|
||||
|
||||
error_t display_swap_xy(Device* device, bool swap_axes) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->swap_xy(device, swap_axes);
|
||||
}
|
||||
|
||||
bool display_get_swap_xy(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_swap_xy(device);
|
||||
}
|
||||
|
||||
bool display_get_mirror_x(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_mirror_x(device);
|
||||
}
|
||||
|
||||
bool display_get_mirror_y(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_mirror_y(device);
|
||||
}
|
||||
|
||||
error_t display_set_gap(Device* device, int32_t x_gap, int32_t y_gap) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->set_gap(device, x_gap, y_gap);
|
||||
}
|
||||
|
||||
error_t display_invert_color(Device* device, bool invert_color_data) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->invert_color(device, invert_color_data);
|
||||
}
|
||||
|
||||
error_t display_disp_on_off(Device* device, bool on_off) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->disp_on_off(device, on_off);
|
||||
}
|
||||
|
||||
error_t display_disp_sleep(Device* device, bool sleep) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->disp_sleep(device, sleep);
|
||||
}
|
||||
|
||||
enum DisplayColorFormat display_get_color_format(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_color_format(device);
|
||||
}
|
||||
|
||||
uint16_t display_get_resolution_x(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_resolution_x(device);
|
||||
}
|
||||
|
||||
uint16_t display_get_resolution_y(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_resolution_y(device);
|
||||
}
|
||||
|
||||
void display_get_frame_buffer(Device* device, uint8_t index, void** out_buffer) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
DISPLAY_DRIVER_API(driver)->get_frame_buffer(device, index, out_buffer);
|
||||
}
|
||||
|
||||
uint8_t display_get_frame_buffer_count(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_frame_buffer_count(device);
|
||||
}
|
||||
|
||||
error_t display_get_backlight(Device* device, Device** backlight) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return DISPLAY_DRIVER_API(driver)->get_backlight(device, backlight);
|
||||
}
|
||||
|
||||
const struct DeviceType DISPLAY_TYPE {
|
||||
.name = "display"
|
||||
};
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t grove_set_mode(struct Device* device, enum GroveMode mode) {
|
||||
error_t grove_set_mode(Device* device, GroveMode mode) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GROVE_DRIVER_API(driver)->set_mode(device, mode);
|
||||
}
|
||||
|
||||
error_t grove_get_mode(struct Device* device, enum GroveMode* mode) {
|
||||
error_t grove_get_mode(Device* device, GroveMode* mode) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GROVE_DRIVER_API(driver)->get_mode(device, mode);
|
||||
}
|
||||
|
||||
const struct DeviceType GROVE_TYPE {
|
||||
const DeviceType GROVE_TYPE {
|
||||
.name = "grove"
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/keyboard.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#define KEYBOARD_DRIVER_API(driver) ((struct KeyboardApi*)driver->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t keyboard_read_key(Device* device, KeyboardKeyData* data) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return KEYBOARD_DRIVER_API(driver)->read_key(device, data);
|
||||
}
|
||||
|
||||
const DeviceType KEYBOARD_TYPE {
|
||||
.name = "keyboard"
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/pointer.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#define POINTER_DRIVER_API(driver) ((struct PointerApi*)driver->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t pointer_enter_sleep(struct Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->enter_sleep(device);
|
||||
}
|
||||
|
||||
error_t pointer_exit_sleep(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->exit_sleep(device);
|
||||
}
|
||||
|
||||
error_t pointer_read_data(Device* device, TickType_t timeout) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->read_data(device, timeout);
|
||||
}
|
||||
|
||||
bool pointer_get_touched_points(Device* device, uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* point_count, uint8_t max_point_count) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->get_touched_points(device, x, y, strength, point_count, max_point_count);
|
||||
}
|
||||
|
||||
error_t pointer_set_swap_xy(Device* device, bool swap) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->set_swap_xy(device, swap);
|
||||
}
|
||||
|
||||
error_t pointer_get_swap_xy(Device* device, bool* swap) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->get_swap_xy(device, swap);
|
||||
}
|
||||
|
||||
error_t pointer_set_mirror_x(Device* device, bool mirror) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->set_mirror_x(device, mirror);
|
||||
}
|
||||
|
||||
error_t pointer_get_mirror_x(Device* device, bool* mirror) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->get_mirror_x(device, mirror);
|
||||
}
|
||||
|
||||
error_t pointer_set_mirror_y(Device* device, bool mirror) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->set_mirror_y(device, mirror);
|
||||
}
|
||||
|
||||
error_t pointer_get_mirror_y(Device* device, bool* mirror) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POINTER_DRIVER_API(driver)->get_mirror_y(device, mirror);
|
||||
}
|
||||
|
||||
const struct DeviceType POINTER_TYPE {
|
||||
.name = "pointer"
|
||||
};
|
||||
|
||||
}
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/touch_placeholder.h>
|
||||
#include <tactility/drivers/pointer_placeholder.h>
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/drivers/touch.h>
|
||||
#include <tactility/drivers/pointer.h>
|
||||
#include <tactility/module.h>
|
||||
|
||||
extern "C" {
|
||||
@@ -12,13 +12,13 @@ static error_t stop(Device*) { return ERROR_NONE; }
|
||||
|
||||
extern Module root_module;
|
||||
|
||||
Driver touch_placeholder_driver = {
|
||||
.name = "touch_placeholder",
|
||||
.compatible = (const char*[]) { "touch-placeholder", nullptr },
|
||||
Driver pointer_placeholder_driver = {
|
||||
.name = "pointer_placeholder",
|
||||
.compatible = (const char*[]) { "pointer-placeholder", nullptr },
|
||||
.start_device = start,
|
||||
.stop_device = stop,
|
||||
.api = nullptr,
|
||||
.device_type = &TOUCH_TYPE,
|
||||
.device_type = &POINTER_TYPE,
|
||||
.owner = &root_module,
|
||||
.internal = nullptr
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/power_supply.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#define POWER_SUPPLY_DRIVER_API(driver) ((PowerSupplyApi*)driver->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool power_supply_supports_property(Device* device, PowerSupplyProperty property) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->supports_property(device, property);
|
||||
}
|
||||
|
||||
error_t power_supply_get_property(Device* device, PowerSupplyProperty property, union PowerSupplyPropertyValue* out_value) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->get_property(device, property, out_value);
|
||||
}
|
||||
|
||||
bool power_supply_supports_charge_control(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->supports_charge_control(device);
|
||||
}
|
||||
|
||||
bool power_supply_is_allowed_to_charge(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->is_allowed_to_charge(device);
|
||||
}
|
||||
|
||||
error_t power_supply_set_allowed_to_charge(Device* device, bool allowed) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->set_allowed_to_charge(device, allowed);
|
||||
}
|
||||
|
||||
bool power_supply_supports_quick_charge(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->supports_quick_charge(device);
|
||||
}
|
||||
|
||||
bool power_supply_is_quick_charge_enabled(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->is_quick_charge_enabled(device);
|
||||
}
|
||||
|
||||
error_t power_supply_set_quick_charge_enabled(Device* device, bool enabled) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->set_quick_charge_enabled(device, enabled);
|
||||
}
|
||||
|
||||
bool power_supply_supports_power_off(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->supports_power_off(device);
|
||||
}
|
||||
|
||||
error_t power_supply_power_off(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return POWER_SUPPLY_DRIVER_API(driver)->power_off(device);
|
||||
}
|
||||
|
||||
const DeviceType POWER_SUPPLY_TYPE {
|
||||
.name = "power_supply"
|
||||
};
|
||||
|
||||
}
|
||||
@@ -6,17 +6,17 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t rtc_get_time(struct Device* device, struct RtcDateTime* dt) {
|
||||
error_t rtc_get_time(Device* device, RtcDateTime* dt) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return RTC_DRIVER_API(driver)->get_time(device, dt);
|
||||
}
|
||||
|
||||
error_t rtc_set_time(struct Device* device, const struct RtcDateTime* dt) {
|
||||
error_t rtc_set_time(Device* device, const RtcDateTime* dt) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return RTC_DRIVER_API(driver)->set_time(device, dt);
|
||||
}
|
||||
|
||||
const struct DeviceType RTC_TYPE {
|
||||
const DeviceType RTC_TYPE {
|
||||
.name = "rtc"
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
const struct DeviceType SDCARD_TYPE {
|
||||
const DeviceType SDCARD_TYPE {
|
||||
.name = "sdcard"
|
||||
};
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t spi_controller_lock(struct Device* device) {
|
||||
error_t spi_controller_lock(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return SPI_DRIVER_API(driver)->lock(device);
|
||||
}
|
||||
|
||||
error_t spi_controller_try_lock(struct Device* device, TickType_t timeout) {
|
||||
error_t spi_controller_try_lock(Device* device, TickType_t timeout) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return SPI_DRIVER_API(driver)->try_lock(device, timeout);
|
||||
}
|
||||
|
||||
error_t spi_controller_unlock(struct Device* device) {
|
||||
error_t spi_controller_unlock(Device* device) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return SPI_DRIVER_API(driver)->unlock(device);
|
||||
}
|
||||
|
||||
const struct DeviceType SPI_CONTROLLER_TYPE {
|
||||
const DeviceType SPI_CONTROLLER_TYPE {
|
||||
.name = "spi-controller"
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/drivers/touch.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
const struct DeviceType TOUCH_TYPE {
|
||||
.name = "touch"
|
||||
};
|
||||
|
||||
}
|
||||
@@ -16,10 +16,14 @@ static error_t start() {
|
||||
if (driver_construct_add(&root_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
extern Driver display_placeholder_driver;
|
||||
if (driver_construct_add(&display_placeholder_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
extern Driver touch_placeholder_driver;
|
||||
if (driver_construct_add(&touch_placeholder_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
extern Driver pointer_placeholder_driver;
|
||||
if (driver_construct_add(&pointer_placeholder_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
extern Driver spi_peripheral_driver;
|
||||
if (driver_construct_add(&spi_peripheral_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
extern Driver battery_sense_driver;
|
||||
if (driver_construct_add(&battery_sense_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
extern Driver battery_sense_power_supply_driver;
|
||||
if (driver_construct_add(&battery_sense_power_supply_driver) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user