mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-20 15:35:05 +00:00
GPIO ownership WIP
This commit is contained in:
parent
adb23a0e66
commit
5605c3ce0a
@ -8,6 +8,7 @@
|
|||||||
#include <tactility/log.h>
|
#include <tactility/log.h>
|
||||||
#include <tactility/drivers/gpio.h>
|
#include <tactility/drivers/gpio.h>
|
||||||
#include <tactility/drivers/gpio_controller.h>
|
#include <tactility/drivers/gpio_controller.h>
|
||||||
|
#include <tactility/drivers/gpio_descriptor.h>
|
||||||
|
|
||||||
#define TAG "esp32_gpio"
|
#define TAG "esp32_gpio"
|
||||||
|
|
||||||
@ -15,20 +16,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
static error_t set_level(Device* device, gpio_pin_t pin, bool high) {
|
static error_t set_level(GpioDescriptor* descriptor, bool high) {
|
||||||
auto esp_error = gpio_set_level(static_cast<gpio_num_t>(pin), high);
|
auto esp_error = gpio_set_level(static_cast<gpio_num_t>(descriptor->pin), high);
|
||||||
return esp_err_to_error(esp_error);
|
return esp_err_to_error(esp_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static error_t get_level(Device* device, gpio_pin_t pin, bool* high) {
|
static error_t get_level(GpioDescriptor* descriptor, bool* high) {
|
||||||
*high = gpio_get_level(static_cast<gpio_num_t>(pin)) != 0;
|
*high = gpio_get_level(static_cast<gpio_num_t>(descriptor->pin)) != 0;
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static error_t set_options(Device* device, gpio_pin_t pin, gpio_flags_t options) {
|
static error_t set_options(GpioDescriptor* descriptor, gpio_flags_t options) {
|
||||||
const Esp32GpioConfig* config = GET_CONFIG(device);
|
const Esp32GpioConfig* config = GET_CONFIG(descriptor->controller);
|
||||||
|
|
||||||
if (pin >= config->gpioCount) {
|
if (descriptor->pin >= config->gpioCount) {
|
||||||
return ERROR_INVALID_ARGUMENT;
|
return ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ static error_t set_options(Device* device, gpio_pin_t pin, gpio_flags_t options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const gpio_config_t esp_config = {
|
const gpio_config_t esp_config = {
|
||||||
.pin_bit_mask = 1ULL << pin,
|
.pin_bit_mask = 1ULL << descriptor->pin,
|
||||||
.mode = mode,
|
.mode = mode,
|
||||||
.pull_up_en = (options & GPIO_PULL_UP) ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE,
|
.pull_up_en = (options & GPIO_PULL_UP) ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE,
|
||||||
.pull_down_en = (options & GPIO_PULL_DOWN) ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE,
|
.pull_down_en = (options & GPIO_PULL_DOWN) ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE,
|
||||||
@ -58,9 +59,9 @@ static error_t set_options(Device* device, gpio_pin_t pin, gpio_flags_t options)
|
|||||||
return esp_err_to_error(esp_error);
|
return esp_err_to_error(esp_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_options(Device* device, gpio_pin_t pin, gpio_flags_t* options) {
|
static error_t get_options(GpioDescriptor* descriptor, gpio_flags_t* options) {
|
||||||
gpio_io_config_t esp_config;
|
gpio_io_config_t esp_config;
|
||||||
if (gpio_get_io_config(static_cast<gpio_num_t>(pin), &esp_config) != ESP_OK) {
|
if (gpio_get_io_config(static_cast<gpio_num_t>(descriptor->pin), &esp_config) != ESP_OK) {
|
||||||
return ERROR_RESOURCE;
|
return ERROR_RESOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,27 +91,31 @@ static int get_options(Device* device, gpio_pin_t pin, gpio_flags_t* options) {
|
|||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t get_pin_count(struct Device* device, uint32_t* count) {
|
static error_t get_pin_number(struct GpioDescriptor* descriptor, gpio_pin_t* pin) {
|
||||||
*count = GET_CONFIG(device)->gpioCount;
|
if (!descriptor) return ERROR_INVALID_ARGUMENT;
|
||||||
|
*pin = descriptor->pin;
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static error_t start(Device* device) {
|
static error_t start(Device* device) {
|
||||||
ESP_LOGI(TAG, "start %s", device->name);
|
ESP_LOGI(TAG, "start %s", device->name);
|
||||||
return ERROR_NONE;
|
auto pin_count = GET_CONFIG(device)->gpioCount;
|
||||||
|
return gpio_controller_init_descriptors(device, pin_count, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static error_t stop(Device* device) {
|
static error_t stop(Device* device) {
|
||||||
ESP_LOGI(TAG, "stop %s", device->name);
|
ESP_LOGI(TAG, "stop %s", device->name);
|
||||||
return ERROR_NONE;
|
return gpio_controller_deinit_descriptors(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
const static GpioControllerApi esp32_gpio_api = {
|
const static GpioControllerApi esp32_gpio_api = {
|
||||||
|
.acquire_descriptor = acquire_descriptor,
|
||||||
|
.release_descriptor = release_descriptor,
|
||||||
|
.get_pin_number = get_pin_number,
|
||||||
.set_level = set_level,
|
.set_level = set_level,
|
||||||
.get_level = get_level,
|
.get_level = get_level,
|
||||||
.set_options = set_options,
|
.set_options = set_options,
|
||||||
.get_options = get_options,
|
.get_options = get_options
|
||||||
.get_pin_count = get_pin_count
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct Module platform_module;
|
extern struct Module platform_module;
|
||||||
|
|||||||
@ -32,7 +32,6 @@
|
|||||||
#include <tactility/lvgl_module.h>
|
#include <tactility/lvgl_module.h>
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include "tactility/drivers/root.h"
|
|
||||||
#include <Tactility/InitEsp.h>
|
#include <Tactility/InitEsp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -7,22 +7,16 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Logical GPIO pin identifier used by the HAL. Typically maps to the SoC GPIO number. */
|
/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */
|
||||||
typedef unsigned int GpioPin;
|
typedef unsigned int GpioPin;
|
||||||
/** Value indicating that no GPIO pin is used/applicable. */
|
|
||||||
|
/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */
|
||||||
#define GPIO_NO_PIN -1
|
#define GPIO_NO_PIN -1
|
||||||
|
|
||||||
/** Read the current logic level of a pin.
|
/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */
|
||||||
* The pin should be configured for input or input/output.
|
|
||||||
* @param[in] pin The pin to read.
|
|
||||||
* @return true if the level is high, false if low. If the pin is invalid, the
|
|
||||||
* behavior is implementation-defined and may return false.
|
|
||||||
*/
|
|
||||||
bool tt_hal_gpio_get_level(GpioPin pin);
|
bool tt_hal_gpio_get_level(GpioPin pin);
|
||||||
|
|
||||||
/** Get the number of GPIO pins available on this platform.
|
/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */
|
||||||
* @return The count of valid GPIO pins.
|
|
||||||
*/
|
|
||||||
int tt_hal_gpio_get_pin_count();
|
int tt_hal_gpio_get_pin_count();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -7,33 +7,12 @@ extern "C" {
|
|||||||
|
|
||||||
using namespace tt::hal;
|
using namespace tt::hal;
|
||||||
|
|
||||||
static Device* find_first_gpio_controller() {
|
|
||||||
Device* device_result = nullptr;
|
|
||||||
device_for_each_of_type(&GPIO_CONTROLLER_TYPE, &device_result, [](Device* device, void* context) {
|
|
||||||
if (device_is_ready(device)) {
|
|
||||||
auto** device_result_ptr = static_cast<Device**>(context);
|
|
||||||
*device_result_ptr = device;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
return device_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tt_hal_gpio_get_level(GpioPin pin) {
|
bool tt_hal_gpio_get_level(GpioPin pin) {
|
||||||
Device* device_result = find_first_gpio_controller();
|
return false;
|
||||||
if (device_result == nullptr) return false;
|
|
||||||
bool pin_state = false;
|
|
||||||
if (gpio_controller_get_level(device_result, pin, &pin_state) != ERROR_NONE) return false;
|
|
||||||
return pin_state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tt_hal_gpio_get_pin_count() {
|
int tt_hal_gpio_get_pin_count() {
|
||||||
Device* device_result = find_first_gpio_controller();
|
return 0;
|
||||||
if (device_result == nullptr) return 0;
|
|
||||||
uint32_t pin_count = 0;
|
|
||||||
if (gpio_controller_get_pin_count(device_result, &pin_count) != ERROR_NONE) return 0;
|
|
||||||
return (int)pin_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,12 +38,25 @@ typedef enum {
|
|||||||
GPIO__MAX,
|
GPIO__MAX,
|
||||||
} GpioInterruptType;
|
} GpioInterruptType;
|
||||||
|
|
||||||
|
enum GpioOwnerType {
|
||||||
|
/** @brief Pin is unclaimed/free */
|
||||||
|
GPIO_OWNER_NONE,
|
||||||
|
/** @brief Pin is owned by a hog */
|
||||||
|
GPIO_OWNER_HOG,
|
||||||
|
/** @brief Pin is claimed by a regular consumer */
|
||||||
|
GPIO_OWNER_GPIO,
|
||||||
|
/** @brief Pin is owned by SPI. This is a special case because of CS pin transfer from hog to SPI controller. */
|
||||||
|
GPIO_OWNER_SPI
|
||||||
|
};
|
||||||
|
|
||||||
/** The index of a GPIO pin on a GPIO Controller */
|
/** The index of a GPIO pin on a GPIO Controller */
|
||||||
typedef uint8_t gpio_pin_t;
|
typedef uint8_t gpio_pin_t;
|
||||||
|
|
||||||
/** Specifies the configuration flags for a GPIO pin (or set of pins) */
|
/** Specifies the configuration flags for a GPIO pin (or set of pins) */
|
||||||
typedef uint16_t gpio_flags_t;
|
typedef uint16_t gpio_flags_t;
|
||||||
|
|
||||||
|
typedef uint8_t gpio_level_t;
|
||||||
|
|
||||||
/** A configuration for a single GPIO pin */
|
/** A configuration for a single GPIO pin */
|
||||||
struct GpioPinConfig {
|
struct GpioPinConfig {
|
||||||
/** GPIO device controlling the pin */
|
/** GPIO device controlling the pin */
|
||||||
|
|||||||
@ -12,104 +12,127 @@ extern "C" {
|
|||||||
struct Device;
|
struct Device;
|
||||||
|
|
||||||
struct GpioControllerApi {
|
struct GpioControllerApi {
|
||||||
|
struct GpioDescriptor* (*acquire_descriptor)(
|
||||||
|
struct Device* controller,
|
||||||
|
gpio_pin_t pin_number,
|
||||||
|
enum GpioOwnerType owner,
|
||||||
|
void* owner_context
|
||||||
|
);
|
||||||
|
|
||||||
|
error_t (*release_descriptor)(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the pin number associated with a descriptor.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[out] pin pointer to store the pin number
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t (*get_pin_number)(struct GpioDescriptor* descriptor, gpio_pin_t* pin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the logical level of a GPIO pin.
|
* @brief Sets the logical level of a GPIO pin.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in,out] descriptor the pin descriptor
|
||||||
* @param[in] pin the pin index
|
|
||||||
* @param[in] high true to set the pin high, false to set it low
|
* @param[in] high true to set the pin high, false to set it low
|
||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
error_t (*set_level)(struct Device* device, gpio_pin_t pin, bool high);
|
error_t (*set_level)(struct GpioDescriptor* descriptor, bool high);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the logical level of a GPIO pin.
|
* @brief Gets the logical level of a GPIO pin.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in] descriptor the pin descriptor
|
||||||
* @param[in] pin the pin index
|
|
||||||
* @param[out] high pointer to store the pin level
|
* @param[out] high pointer to store the pin level
|
||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
error_t (*get_level)(struct Device* device, gpio_pin_t pin, bool* high);
|
error_t (*get_level)(struct GpioDescriptor* descriptor, bool* high);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures the options for a GPIO pin.
|
* @brief Configures the options for a GPIO pin.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in,out] descriptor the pin descriptor
|
||||||
* @param[in] pin the pin index
|
|
||||||
* @param[in] options configuration flags (direction, pull-up/down, etc.)
|
* @param[in] options configuration flags (direction, pull-up/down, etc.)
|
||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
error_t (*set_options)(struct Device* device, gpio_pin_t pin, gpio_flags_t options);
|
error_t (*set_options)(struct GpioDescriptor* descriptor, gpio_flags_t options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the configuration options for a GPIO pin.
|
* @brief Gets the configuration options for a GPIO pin.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in] descriptor the pin descriptor
|
||||||
* @param[in] pin the pin index
|
|
||||||
* @param[out] options pointer to store the configuration flags
|
* @param[out] options pointer to store the configuration flags
|
||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
error_t (*get_options)(struct Device* device, gpio_pin_t pin, gpio_flags_t* options);
|
error_t (*get_options)(struct GpioDescriptor* descriptor, gpio_flags_t* options);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the number of pins supported by the controller.
|
|
||||||
* @param[in] device the GPIO controller device
|
|
||||||
* @param[out] count pointer to store the number of pins
|
|
||||||
* @return ERROR_NONE if successful
|
|
||||||
*/
|
|
||||||
error_t (*get_pin_count)(struct Device* device, uint32_t* count);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
struct GpioDescriptor* acquire_descriptor(
|
||||||
* @brief Sets the logical level of a GPIO pin.
|
struct Device* controller,
|
||||||
* @param[in] device the GPIO controller device
|
gpio_pin_t pin_number,
|
||||||
* @param[in] pin the pin index
|
enum GpioOwnerType owner,
|
||||||
* @param[in] high true to set the pin high, false to set it low
|
void* owner_context
|
||||||
* @return ERROR_NONE if successful
|
);
|
||||||
*/
|
|
||||||
error_t gpio_controller_set_level(struct Device* device, gpio_pin_t pin, bool high);
|
error_t release_descriptor(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the logical level of a GPIO pin.
|
* @brief Gets the number of pins supported by the controller.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in] device the GPIO controller device
|
||||||
* @param[in] pin the pin index
|
* @param[out] count pointer to store the number of pins
|
||||||
* @param[out] high pointer to store the pin level
|
|
||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
error_t gpio_controller_get_level(struct Device* device, gpio_pin_t pin, bool* high);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configures the options for a GPIO pin.
|
|
||||||
* @param[in] device the GPIO controller device
|
|
||||||
* @param[in] pin the pin index
|
|
||||||
* @param[in] options configuration flags (direction, pull-up/down, etc.)
|
|
||||||
* @return ERROR_NONE if successful
|
|
||||||
*/
|
|
||||||
error_t gpio_controller_set_options(struct Device* device, gpio_pin_t pin, gpio_flags_t options);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the configuration options for a GPIO pin.
|
|
||||||
* @param[in] device the GPIO controller device
|
|
||||||
* @param[in] pin the pin index
|
|
||||||
* @param[out] options pointer to store the configuration flags
|
|
||||||
* @return ERROR_NONE if successful
|
|
||||||
*/
|
|
||||||
error_t gpio_controller_get_options(struct Device* device, gpio_pin_t pin, gpio_flags_t* options);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the number of pins supported by the controller.
|
|
||||||
* @param[in] device the GPIO controller device
|
|
||||||
* @param[out] count pointer to store the number of pins
|
|
||||||
* @return ERROR_NONE if successful
|
|
||||||
*/
|
|
||||||
error_t gpio_controller_get_pin_count(struct Device* device, uint32_t* count);
|
error_t gpio_controller_get_pin_count(struct Device* device, uint32_t* count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures the options for a GPIO pin using a pin configuration structure.
|
* @brief Gets the pin number associated with a descriptor.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in] descriptor the pin descriptor
|
||||||
* @param[in] config the pin configuration structure
|
* @param[out] pin pointer to store the pin number
|
||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
static inline error_t gpio_set_options_config(struct Device* device, const struct GpioPinConfig* config) {
|
error_t gpio_descriptor_pin_number(struct GpioDescriptor* descriptor, gpio_pin_t* pin);
|
||||||
return gpio_controller_set_options(device, config->pin, config->flags);
|
|
||||||
}
|
/**
|
||||||
|
* @brief Sets the logical level of a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[in] high true to set the pin high, false to set it low
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_set_level(struct GpioDescriptor* descriptor, bool high);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the logical level of a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[out] high pointer to store the pin level
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_get_level(struct GpioDescriptor* descriptor, bool* high);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures the options for a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[in] options configuration flags (direction, pull-up/down, etc.)
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_set_options(struct GpioDescriptor* descriptor, gpio_flags_t options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the configuration options for a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[out] options pointer to store the configuration flags
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_get_options(struct GpioDescriptor* descriptor, gpio_flags_t* options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes GPIO descriptors for a controller.
|
||||||
|
* @param[in,out] device the GPIO controller device
|
||||||
|
* @param[in] owner_data pointer to store in the descriptor's owner_data field
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t gpio_controller_init_descriptors(struct Device* device, uint32_t pin_count, void* owner_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitializes GPIO descriptors for a controller.
|
||||||
|
* @param[in,out] device the GPIO controller device
|
||||||
|
* @return ERROR_NONE if successful
|
||||||
|
*/
|
||||||
|
error_t gpio_controller_deinit_descriptors(struct Device* device);
|
||||||
|
|
||||||
extern const struct DeviceType GPIO_CONTROLLER_TYPE;
|
extern const struct DeviceType GPIO_CONTROLLER_TYPE;
|
||||||
|
|
||||||
|
|||||||
20
TactilityKernel/Include/tactility/drivers/gpio_descriptor.h
Normal file
20
TactilityKernel/Include/tactility/drivers/gpio_descriptor.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
struct GpioDescriptor {
|
||||||
|
/** @brief The controller that owns this pin */
|
||||||
|
struct Device* controller;
|
||||||
|
/** @brief Physical pin number */
|
||||||
|
gpio_pin_t pin;
|
||||||
|
/** @brief Current owner */
|
||||||
|
enum GpioOwnerType owner_type;
|
||||||
|
/** @brief Owner identity for validation */
|
||||||
|
void* owner_context;
|
||||||
|
/** @brief Pin level */
|
||||||
|
gpio_level_t level;
|
||||||
|
/** @brief Pin configuration flags */
|
||||||
|
gpio_flags_t flags;
|
||||||
|
/** @brief Implementation-specific context (e.g. from esp32 controller internally) */
|
||||||
|
void* controller_context;
|
||||||
|
};
|
||||||
@ -3,33 +3,116 @@
|
|||||||
#include <tactility/driver.h>
|
#include <tactility/driver.h>
|
||||||
#include <tactility/drivers/gpio_controller.h>
|
#include <tactility/drivers/gpio_controller.h>
|
||||||
|
|
||||||
#define GPIO_DRIVER_API(driver) ((struct GpioControllerApi*)driver->api)
|
#include <tactility/concurrent/mutex.h>
|
||||||
|
#include <tactility/drivers/gpio_descriptor.h>
|
||||||
|
|
||||||
|
#define GPIO_INTERNAL_API(driver) ((struct GpioControllerApi*)driver->api)
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
error_t gpio_controller_set_level(Device* device, gpio_pin_t pin, bool high) {
|
struct GpioControllerData {
|
||||||
const auto* driver = device_get_driver(device);
|
struct Mutex mutex;
|
||||||
return GPIO_DRIVER_API(driver)->set_level(device, pin, high);
|
uint32_t pin_count;
|
||||||
|
struct GpioDescriptor* descriptors;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GpioDescriptor* acquire_descriptor(
|
||||||
|
struct Device* controller,
|
||||||
|
gpio_pin_t pin_number,
|
||||||
|
enum GpioOwnerType owner,
|
||||||
|
void* owner_context
|
||||||
|
) {
|
||||||
|
auto* data = (struct GpioControllerData*)device_get_driver_data(controller);
|
||||||
|
|
||||||
|
mutex_lock(&data->mutex);
|
||||||
|
if (pin_number >= data->pin_count) {
|
||||||
|
mutex_unlock(&data->mutex);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GpioDescriptor* desc = &data->descriptors[pin_number];
|
||||||
|
if (desc->owner_type != GPIO_OWNER_NONE) {
|
||||||
|
mutex_unlock(&data->mutex);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc->owner_type = owner;
|
||||||
|
desc->owner_context = owner_context;
|
||||||
|
mutex_unlock(&data->mutex);
|
||||||
|
|
||||||
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t gpio_controller_get_level(Device* device, gpio_pin_t pin, bool* high) {
|
error_t release_descriptor(struct GpioDescriptor* descriptor) {
|
||||||
const auto* driver = device_get_driver(device);
|
descriptor->owner_type = GPIO_OWNER_NONE;
|
||||||
return GPIO_DRIVER_API(driver)->get_level(device, pin, high);
|
descriptor->owner_context = nullptr;
|
||||||
}
|
return ERROR_NONE;
|
||||||
|
|
||||||
error_t gpio_controller_set_options(Device* device, gpio_pin_t pin, gpio_flags_t options) {
|
|
||||||
const auto* driver = device_get_driver(device);
|
|
||||||
return GPIO_DRIVER_API(driver)->set_options(device, pin, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
error_t gpio_controller_get_options(Device* device, gpio_pin_t pin, gpio_flags_t* options) {
|
|
||||||
const auto* driver = device_get_driver(device);
|
|
||||||
return GPIO_DRIVER_API(driver)->get_options(device, pin, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t gpio_controller_get_pin_count(struct Device* device, uint32_t* count) {
|
error_t gpio_controller_get_pin_count(struct Device* device, uint32_t* count) {
|
||||||
const auto* driver = device_get_driver(device);
|
auto* data = (struct GpioControllerData*)device_get_driver_data(device);
|
||||||
return GPIO_DRIVER_API(driver)->get_pin_count(device, count);
|
*count = data->pin_count;
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_controller_init_descriptors(struct Device* device, uint32_t pin_count, void* controller_context) {
|
||||||
|
auto* data = (struct GpioControllerData*)malloc(sizeof(struct GpioControllerData));
|
||||||
|
if (!data) return ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
data->pin_count = pin_count;
|
||||||
|
data->descriptors = (struct GpioDescriptor*)calloc(pin_count, sizeof(struct GpioDescriptor));
|
||||||
|
if (!data->descriptors) {
|
||||||
|
free(data);
|
||||||
|
return ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < pin_count; ++i) {
|
||||||
|
data->descriptors[i].controller = device;
|
||||||
|
data->descriptors[i].pin = (gpio_pin_t)i;
|
||||||
|
data->descriptors[i].owner_type = GPIO_OWNER_NONE;
|
||||||
|
data->descriptors[i].controller_context = controller_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_construct(&data->mutex);
|
||||||
|
device_set_driver_data(device, data);
|
||||||
|
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_controller_deinit_descriptors(struct Device* device) {
|
||||||
|
auto* data = (struct GpioControllerData*)device_get_driver_data(device);
|
||||||
|
|
||||||
|
free(data->descriptors);
|
||||||
|
mutex_destruct(&data->mutex);
|
||||||
|
free(data);
|
||||||
|
device_set_driver_data(device, nullptr);
|
||||||
|
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_set_level(struct GpioDescriptor* descriptor, bool high) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
return GPIO_INTERNAL_API(driver)->set_level(descriptor, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_get_level(struct GpioDescriptor* descriptor, bool* high) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
return GPIO_INTERNAL_API(driver)->get_level(descriptor, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_set_options(struct GpioDescriptor* descriptor, gpio_flags_t options) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
return GPIO_INTERNAL_API(driver)->set_options(descriptor, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_get_options(struct GpioDescriptor* descriptor, gpio_flags_t* options) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
return GPIO_INTERNAL_API(driver)->get_options(descriptor, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_get_pin_number(struct GpioDescriptor* descriptor, gpio_pin_t* pin) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
return GPIO_INTERNAL_API(driver)->get_pin_number(descriptor, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct DeviceType GPIO_CONTROLLER_TYPE {
|
const struct DeviceType GPIO_CONTROLLER_TYPE {
|
||||||
|
|||||||
@ -59,11 +59,13 @@ const struct ModuleSymbol KERNEL_SYMBOLS[] = {
|
|||||||
DEFINE_MODULE_SYMBOL(driver_find_compatible),
|
DEFINE_MODULE_SYMBOL(driver_find_compatible),
|
||||||
DEFINE_MODULE_SYMBOL(driver_get_device_type),
|
DEFINE_MODULE_SYMBOL(driver_get_device_type),
|
||||||
// drivers/gpio_controller
|
// drivers/gpio_controller
|
||||||
DEFINE_MODULE_SYMBOL(gpio_controller_set_level),
|
DEFINE_MODULE_SYMBOL(gpio_descriptor_set_level),
|
||||||
DEFINE_MODULE_SYMBOL(gpio_controller_get_level),
|
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_level),
|
||||||
DEFINE_MODULE_SYMBOL(gpio_controller_set_options),
|
DEFINE_MODULE_SYMBOL(gpio_descriptor_set_options),
|
||||||
DEFINE_MODULE_SYMBOL(gpio_controller_get_options),
|
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_options),
|
||||||
DEFINE_MODULE_SYMBOL(gpio_controller_get_pin_count),
|
DEFINE_MODULE_SYMBOL(gpio_controller_get_pin_count),
|
||||||
|
DEFINE_MODULE_SYMBOL(gpio_controller_init_descriptors),
|
||||||
|
DEFINE_MODULE_SYMBOL(gpio_controller_deinit_descriptors),
|
||||||
DEFINE_MODULE_SYMBOL(GPIO_CONTROLLER_TYPE),
|
DEFINE_MODULE_SYMBOL(GPIO_CONTROLLER_TYPE),
|
||||||
// drivers/i2c_controller
|
// drivers/i2c_controller
|
||||||
DEFINE_MODULE_SYMBOL(i2c_controller_read),
|
DEFINE_MODULE_SYMBOL(i2c_controller_read),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user