This commit is contained in:
2026-02-01 12:56:05 +01:00
parent f51adeecca
commit 0bdbcb1657
857 changed files with 0 additions and 97661 deletions

View File

@@ -0,0 +1,355 @@
/**
* @file gpio_wrapper_example.cpp
* @brief Example of integrating ASF Logger with GPIO wrapper
* @author Mahmoud Elmohtady
* @company Nabd solutions - ASF
* @copyright Copyright (c) 2025
*/
#include "logger.hpp"
#include "gpio.hpp"
// Module-specific log tag and IDs
static const char* TAG = "GPIO_WRAPPER";
namespace GpioLogIds {
// Info messages (2001-2199)
static const uint32_t WRAPPER_INIT = 2001;
static const uint32_t WRAPPER_DESTROY = 2002;
static const uint32_t PIN_CONFIGURED = 2003;
static const uint32_t ISR_INSTALLED = 2004;
static const uint32_t INTERRUPT_ATTACHED = 2005;
static const uint32_t INTERRUPT_DETACHED = 2006;
// Debug messages (2201-2399)
static const uint32_t PIN_LEVEL_SET = 2201;
static const uint32_t PIN_LEVEL_READ = 2202;
static const uint32_t PIN_TOGGLED = 2203;
// Warning messages (2401-2599)
static const uint32_t ISR_ALREADY_INSTALLED = 2401;
static const uint32_t PORT_NOT_INITIALIZED = 2402;
// Error messages (2601-2799)
static const uint32_t INVALID_PIN = 2601;
static const uint32_t CONFIG_FAILED = 2602;
static const uint32_t SET_LEVEL_FAILED = 2603;
static const uint32_t ISR_INSTALL_FAILED = 2604;
static const uint32_t INTERRUPT_ATTACH_FAILED = 2605;
static const uint32_t INTERRUPT_DETACH_FAILED = 2606;
}
/**
* @brief Example GPIO wrapper with ASF Logger integration
*/
class GpioWithLogger
{
public:
GpioWithLogger() : m_isrInstalled_(false)
{
ASF_LOGI(TAG, GpioLogIds::WRAPPER_INIT, "GPIO wrapper initialized");
}
~GpioWithLogger()
{
if (m_isrInstalled_) {
uninstallIsr();
}
ASF_LOGI(TAG, GpioLogIds::WRAPPER_DESTROY, "GPIO wrapper destroyed");
}
bool configure(uint32_t pin, GpioMode mode)
{
ASF_LOGI(TAG, GpioLogIds::PIN_CONFIGURED, "Configuring GPIO pin %lu", pin);
if (!isValidPin(pin)) {
ASF_LOGE(TAG, GpioLogIds::INVALID_PIN, "Invalid GPIO pin: %lu", pin);
return false;
}
gpio_config_t config = {};
config.pin_bit_mask = (1ULL << pin);
config.mode = convertMode(mode);
config.intr_type = GPIO_INTR_DISABLE;
// Configure pull-up/down based on mode
switch (mode) {
case GpioMode::INPUT_PULLUP:
config.pull_up_en = GPIO_PULLUP_ENABLE;
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
ASF_LOGD(TAG, GpioLogIds::PIN_CONFIGURED, "Pin %lu configured with pull-up", pin);
break;
case GpioMode::INPUT_PULLDOWN:
config.pull_up_en = GPIO_PULLUP_DISABLE;
config.pull_down_en = GPIO_PULLDOWN_ENABLE;
ASF_LOGD(TAG, GpioLogIds::PIN_CONFIGURED, "Pin %lu configured with pull-down", pin);
break;
default:
config.pull_up_en = GPIO_PULLUP_DISABLE;
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
ASF_LOGD(TAG, GpioLogIds::PIN_CONFIGURED, "Pin %lu configured without pull resistors", pin);
break;
}
esp_err_t ret = gpio_config(&config);
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::CONFIG_FAILED, "Failed to configure GPIO pin %lu: %s",
pin, esp_err_to_name(ret));
return false;
}
ASF_LOGI(TAG, GpioLogIds::PIN_CONFIGURED, "GPIO pin %lu configured successfully", pin);
return true;
}
bool setLevel(uint32_t pin, uint32_t level)
{
if (!isValidPin(pin)) {
ASF_LOGE(TAG, GpioLogIds::INVALID_PIN, "Invalid GPIO pin: %lu", pin);
return false;
}
esp_err_t ret = gpio_set_level(static_cast<gpio_num_t>(pin), level);
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::SET_LEVEL_FAILED, "Failed to set GPIO pin %lu level: %s",
pin, esp_err_to_name(ret));
return false;
}
ASF_LOGD(TAG, GpioLogIds::PIN_LEVEL_SET, "GPIO pin %lu set to level %lu", pin, level);
return true;
}
int32_t getLevel(uint32_t pin)
{
if (!isValidPin(pin)) {
ASF_LOGE(TAG, GpioLogIds::INVALID_PIN, "Invalid GPIO pin: %lu", pin);
return -1;
}
int level = gpio_get_level(static_cast<gpio_num_t>(pin));
ASF_LOGD(TAG, GpioLogIds::PIN_LEVEL_READ, "GPIO pin %lu level read: %d", pin, level);
return level;
}
bool toggleLevel(uint32_t pin)
{
int32_t currentLevel = getLevel(pin);
if (currentLevel < 0) {
return false;
}
bool result = setLevel(pin, currentLevel == 0 ? 1 : 0);
if (result) {
ASF_LOGD(TAG, GpioLogIds::PIN_TOGGLED, "GPIO pin %lu toggled from %ld to %d",
pin, currentLevel, currentLevel == 0 ? 1 : 0);
}
return result;
}
bool installIsr(int flags = 0)
{
if (m_isrInstalled_) {
ASF_LOGW(TAG, GpioLogIds::ISR_ALREADY_INSTALLED, "GPIO ISR already installed");
return true;
}
esp_err_t ret = gpio_install_isr_service(flags);
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::ISR_INSTALL_FAILED, "Failed to install GPIO ISR service: %s",
esp_err_to_name(ret));
return false;
}
m_isrInstalled_ = true;
ASF_LOGI(TAG, GpioLogIds::ISR_INSTALLED, "GPIO ISR service installed successfully");
return true;
}
bool uninstallIsr()
{
if (!m_isrInstalled_) {
ASF_LOGW(TAG, GpioLogIds::PORT_NOT_INITIALIZED, "GPIO ISR not installed");
return true;
}
gpio_uninstall_isr_service();
m_isrInstalled_ = false;
ASF_LOGI(TAG, GpioLogIds::ISR_INSTALLED, "GPIO ISR service uninstalled");
return true;
}
bool attachInterrupt(uint32_t pin, GpioIntType intType, GpioCallback callback, void* arg)
{
if (!isValidPin(pin)) {
ASF_LOGE(TAG, GpioLogIds::INVALID_PIN, "Invalid GPIO pin: %lu", pin);
return false;
}
if (!m_isrInstalled_) {
ASF_LOGW(TAG, GpioLogIds::PORT_NOT_INITIALIZED, "GPIO ISR not installed, installing now");
if (!installIsr()) {
return false;
}
}
// Set interrupt type
esp_err_t ret = gpio_set_intr_type(static_cast<gpio_num_t>(pin), convertIntType(intType));
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::INTERRUPT_ATTACH_FAILED,
"Failed to set interrupt type for pin %lu: %s", pin, esp_err_to_name(ret));
return false;
}
// Add ISR handler
ret = gpio_isr_handler_add(static_cast<gpio_num_t>(pin),
reinterpret_cast<gpio_isr_t>(callback), arg);
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::INTERRUPT_ATTACH_FAILED,
"Failed to add ISR handler for pin %lu: %s", pin, esp_err_to_name(ret));
return false;
}
ASF_LOGI(TAG, GpioLogIds::INTERRUPT_ATTACHED, "Interrupt attached to GPIO pin %lu", pin);
return true;
}
bool detachInterrupt(uint32_t pin)
{
if (!isValidPin(pin)) {
ASF_LOGE(TAG, GpioLogIds::INVALID_PIN, "Invalid GPIO pin: %lu", pin);
return false;
}
// Disable interrupt
esp_err_t ret = gpio_set_intr_type(static_cast<gpio_num_t>(pin), GPIO_INTR_DISABLE);
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::INTERRUPT_DETACH_FAILED,
"Failed to disable interrupt for pin %lu: %s", pin, esp_err_to_name(ret));
return false;
}
// Remove ISR handler
ret = gpio_isr_handler_remove(static_cast<gpio_num_t>(pin));
if (ret != ESP_OK) {
ASF_LOGE(TAG, GpioLogIds::INTERRUPT_DETACH_FAILED,
"Failed to remove ISR handler for pin %lu: %s", pin, esp_err_to_name(ret));
return false;
}
ASF_LOGI(TAG, GpioLogIds::INTERRUPT_DETACHED, "Interrupt detached from GPIO pin %lu", pin);
return true;
}
static bool isValidPin(uint32_t pin)
{
return GPIO_IS_VALID_GPIO(pin);
}
private:
bool m_isrInstalled_;
gpio_mode_t convertMode(GpioMode mode)
{
switch (mode) {
case GpioMode::INPUT:
case GpioMode::INPUT_PULLUP:
case GpioMode::INPUT_PULLDOWN:
return GPIO_MODE_INPUT;
case GpioMode::OUTPUT:
return GPIO_MODE_OUTPUT;
case GpioMode::OUTPUT_OD:
return GPIO_MODE_OUTPUT_OD;
default:
return GPIO_MODE_INPUT;
}
}
gpio_int_type_t convertIntType(GpioIntType intType)
{
switch (intType) {
case GpioIntType::DISABLE:
return GPIO_INTR_DISABLE;
case GpioIntType::RISING_EDGE:
return GPIO_INTR_POSEDGE;
case GpioIntType::FALLING_EDGE:
return GPIO_INTR_NEGEDGE;
case GpioIntType::ANY_EDGE:
return GPIO_INTR_ANYEDGE;
case GpioIntType::LOW_LEVEL:
return GPIO_INTR_LOW_LEVEL;
case GpioIntType::HIGH_LEVEL:
return GPIO_INTR_HIGH_LEVEL;
default:
return GPIO_INTR_DISABLE;
}
}
};
/**
* @brief Example usage of GPIO wrapper with ASF Logger
*/
void exampleUsage()
{
// Initialize ASF Logger
asf::logger::LoggerConfig config = asf::logger::getDefaultConfig();
config.minLevel = asf::logger::LogLevel::DEBUG; // Enable debug messages
asf::logger::initialize(config);
ASF_LOGI("MAIN", 1001, "Starting GPIO wrapper example");
// Create GPIO instance
GpioWithLogger gpio;
// Configure GPIO pin as output
if (gpio.configure(2, GpioMode::OUTPUT)) {
ASF_LOGI("MAIN", 1002, "GPIO pin 2 configured as output");
// Set pin high
gpio.setLevel(2, 1);
// Toggle pin
gpio.toggleLevel(2);
} else {
ASF_LOGE("MAIN", 1003, "Failed to configure GPIO pin 2");
}
// Configure GPIO pin as input with pull-up
if (gpio.configure(4, GpioMode::INPUT_PULLUP)) {
ASF_LOGI("MAIN", 1004, "GPIO pin 4 configured as input with pull-up");
// Read pin level
int32_t level = gpio.getLevel(4);
ASF_LOGI("MAIN", 1005, "GPIO pin 4 level: %ld", level);
}
ASF_LOGI("MAIN", 1006, "GPIO wrapper example completed");
}
/**
* @brief Interrupt handler example
*/
void IRAM_ATTR gpioInterruptHandler(uint32_t pin, void* arg)
{
// Note: In interrupt context, logging should be minimal
// Consider using a queue to defer logging to a task
ASF_LOGI("ISR", 9001, "Interrupt on pin %lu", pin);
}
/**
* @brief Example with interrupt handling
*/
void interruptExample()
{
ASF_LOGI("MAIN", 1007, "Starting interrupt example");
GpioWithLogger gpio;
// Configure pin as input
gpio.configure(5, GpioMode::INPUT);
// Attach interrupt
gpio.attachInterrupt(5, GpioIntType::FALLING_EDGE, gpioInterruptHandler, nullptr);
ASF_LOGI("MAIN", 1008, "Interrupt example setup complete");
}