cleanup sw req
This commit is contained in:
@@ -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");
|
||||
}
|
||||
Reference in New Issue
Block a user