mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-04-18 17:35:05 +00:00
Implement GPIO interrupts
This commit is contained in:
parent
d2048e01b6
commit
ec0c5ae496
@ -12,7 +12,12 @@
|
|||||||
|
|
||||||
#define TAG "esp32_gpio"
|
#define TAG "esp32_gpio"
|
||||||
|
|
||||||
|
struct Esp32GpioInternal {
|
||||||
|
uint8_t isr_service_ref_count = 0;
|
||||||
|
};
|
||||||
|
|
||||||
#define GET_CONFIG(device) ((struct Esp32GpioConfig*)device->config)
|
#define GET_CONFIG(device) ((struct Esp32GpioConfig*)device->config)
|
||||||
|
#define GET_INTERNAL(device) ((struct Esp32GpioInternal*)device->internal)
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
@ -97,15 +102,59 @@ static error_t get_native_pin_number(GpioDescriptor* descriptor, void* pin_numbe
|
|||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static error_t add_callback(struct GpioDescriptor* descriptor, void (*callback)(void*), void* arg) {
|
||||||
|
auto esp_error = gpio_isr_handler_add(static_cast<gpio_num_t>(descriptor->pin), callback, arg);
|
||||||
|
return esp_err_to_error(esp_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t remove_callback(struct GpioDescriptor* descriptor) {
|
||||||
|
auto esp_error = gpio_isr_handler_remove(static_cast<gpio_num_t>(descriptor->pin));
|
||||||
|
return esp_err_to_error(esp_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t enable_interrupt(struct GpioDescriptor* descriptor) {
|
||||||
|
auto* internal = GET_INTERNAL(descriptor->controller);
|
||||||
|
if (internal->isr_service_ref_count == 0) {
|
||||||
|
auto esp_error = gpio_install_isr_service(0);
|
||||||
|
if (esp_error != ESP_OK && esp_error != ESP_ERR_INVALID_STATE) {
|
||||||
|
return esp_err_to_error(esp_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto esp_error = gpio_intr_enable(static_cast<gpio_num_t>(descriptor->pin));
|
||||||
|
if (esp_error == ESP_OK) {
|
||||||
|
internal->isr_service_ref_count++;
|
||||||
|
}
|
||||||
|
return esp_err_to_error(esp_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t disable_interrupt(struct GpioDescriptor* descriptor) {
|
||||||
|
auto* internal = GET_INTERNAL(descriptor->controller);
|
||||||
|
auto esp_error = gpio_intr_disable(static_cast<gpio_num_t>(descriptor->pin));
|
||||||
|
if (esp_error == ESP_OK && internal->isr_service_ref_count > 0) {
|
||||||
|
internal->isr_service_ref_count--;
|
||||||
|
if (internal->isr_service_ref_count == 0) {
|
||||||
|
gpio_uninstall_isr_service();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return esp_err_to_error(esp_error);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
auto pin_count = GET_CONFIG(device)->gpioCount;
|
const Esp32GpioConfig* config = GET_CONFIG(device);
|
||||||
return gpio_controller_init_descriptors(device, pin_count, nullptr);
|
device_set_driver_data(device, new Esp32GpioInternal());
|
||||||
|
return gpio_controller_init_descriptors(device, config->gpioCount, 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 gpio_controller_deinit_descriptors(device);
|
auto* internal = GET_INTERNAL(device);
|
||||||
|
if (internal->isr_service_ref_count > 0) {
|
||||||
|
gpio_uninstall_isr_service();
|
||||||
|
}
|
||||||
|
check(gpio_controller_deinit_descriptors(device) == ERROR_NONE);
|
||||||
|
delete internal;
|
||||||
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static GpioControllerApi esp32_gpio_api = {
|
const static GpioControllerApi esp32_gpio_api = {
|
||||||
@ -113,7 +162,11 @@ const static GpioControllerApi esp32_gpio_api = {
|
|||||||
.get_level = get_level,
|
.get_level = get_level,
|
||||||
.set_flags = set_flags,
|
.set_flags = set_flags,
|
||||||
.get_flags = get_flags,
|
.get_flags = get_flags,
|
||||||
.get_native_pin_number = get_native_pin_number
|
.get_native_pin_number = get_native_pin_number,
|
||||||
|
.add_callback = add_callback,
|
||||||
|
.remove_callback = remove_callback,
|
||||||
|
.enable_interrupt = enable_interrupt,
|
||||||
|
.disable_interrupt = disable_interrupt
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct Module platform_esp32_module;
|
extern struct Module platform_esp32_module;
|
||||||
|
|||||||
@ -52,6 +52,36 @@ struct GpioControllerApi {
|
|||||||
* @return ERROR_NONE if successful
|
* @return ERROR_NONE if successful
|
||||||
*/
|
*/
|
||||||
error_t (*get_native_pin_number)(struct GpioDescriptor* descriptor, void* pin_number);
|
error_t (*get_native_pin_number)(struct GpioDescriptor* descriptor, void* pin_number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a callback to be called when a GPIO interrupt occurs.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[in] callback the callback function
|
||||||
|
* @param[in] arg the argument to pass to the callback
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t (*add_callback)(struct GpioDescriptor* descriptor, void (*callback)(void*), void* arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes a callback from a GPIO interrupt.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t (*remove_callback)(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the interrupt for a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t (*enable_interrupt)(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables the interrupt for a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t (*disable_interrupt)(struct GpioDescriptor* descriptor);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GpioDescriptor* gpio_descriptor_acquire(
|
struct GpioDescriptor* gpio_descriptor_acquire(
|
||||||
@ -118,6 +148,36 @@ error_t gpio_descriptor_get_flags(struct GpioDescriptor* descriptor, gpio_flags_
|
|||||||
*/
|
*/
|
||||||
error_t gpio_descriptor_get_native_pin_number(struct GpioDescriptor* descriptor, void* pin_number);
|
error_t gpio_descriptor_get_native_pin_number(struct GpioDescriptor* descriptor, void* pin_number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a callback to be called when a GPIO interrupt occurs.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @param[in] callback the callback function
|
||||||
|
* @param[in] arg the argument to pass to the callback
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_add_callback(struct GpioDescriptor* descriptor, void (*callback)(void*), void* arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes a callback from a GPIO interrupt.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_remove_callback(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the interrupt for a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_enable_interrupt(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables the interrupt for a GPIO pin.
|
||||||
|
* @param[in] descriptor the pin descriptor
|
||||||
|
* @return ERROR_NONE if successful, ERROR_NOT_SUPPORTED if not implemented
|
||||||
|
*/
|
||||||
|
error_t gpio_descriptor_disable_interrupt(struct GpioDescriptor* descriptor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the number of pins supported by the controller.
|
* @brief Gets the number of pins supported by the controller.
|
||||||
* @param[in] device the GPIO controller device
|
* @param[in] device the GPIO controller device
|
||||||
|
|||||||
@ -130,6 +130,34 @@ error_t gpio_descriptor_get_native_pin_number(struct GpioDescriptor* descriptor,
|
|||||||
return GPIO_INTERNAL_API(driver)->get_native_pin_number(descriptor, pin_number);
|
return GPIO_INTERNAL_API(driver)->get_native_pin_number(descriptor, pin_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_add_callback(struct GpioDescriptor* descriptor, void (*callback)(void*), void* arg) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
auto* api = GPIO_INTERNAL_API(driver);
|
||||||
|
if (!api->add_callback) return ERROR_NOT_SUPPORTED;
|
||||||
|
return api->add_callback(descriptor, callback, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_remove_callback(struct GpioDescriptor* descriptor) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
auto* api = GPIO_INTERNAL_API(driver);
|
||||||
|
if (!api->remove_callback) return ERROR_NOT_SUPPORTED;
|
||||||
|
return api->remove_callback(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_enable_interrupt(struct GpioDescriptor* descriptor) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
auto* api = GPIO_INTERNAL_API(driver);
|
||||||
|
if (!api->enable_interrupt) return ERROR_NOT_SUPPORTED;
|
||||||
|
return api->enable_interrupt(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t gpio_descriptor_disable_interrupt(struct GpioDescriptor* descriptor) {
|
||||||
|
const auto* driver = device_get_driver(descriptor->controller);
|
||||||
|
auto* api = GPIO_INTERNAL_API(driver);
|
||||||
|
if (!api->disable_interrupt) return ERROR_NOT_SUPPORTED;
|
||||||
|
return api->disable_interrupt(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
error_t gpio_descriptor_get_owner_type(struct GpioDescriptor* descriptor, GpioOwnerType* owner_type) {
|
error_t gpio_descriptor_get_owner_type(struct GpioDescriptor* descriptor, GpioOwnerType* owner_type) {
|
||||||
*owner_type = descriptor->owner_type;
|
*owner_type = descriptor->owner_type;
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user