From d77e5cb375920ae65654ec49148d848e164daa06 Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Tue, 3 Sep 2024 16:34:19 +0200 Subject: [PATCH 1/5] Include updates --- examples/picofuse/gpio_in/run.c | 7 +++++- include/fuse/device.h | 35 -------------------------- include/fuse/event.h | 2 ++ include/fuse/flags.h | 40 ------------------------------ include/fuse/fuse.h | 2 +- include/fuse/random.h | 1 + include/fuse/value.h | 2 ++ include/picofuse/picofuse.h | 6 +++++ src/fuse/CMakeLists.txt | 1 - src/fuse/alloc.h | 1 + src/fuse/device.c | 23 ----------------- src/fuse/event.h | 1 + src/fuse/fuse.h | 2 ++ src/fuse/list.h | 2 ++ src/fuse/string.h | 2 ++ src/fuse/value.h | 1 + src/picofuse/CMakeLists.txt | 2 ++ src/picofuse/gpio.c | 26 +++++++++++++------ src/picofuse/gpio.h | 1 + src/picofuse/main.c | 44 --------------------------------- src/picofuse/picofuse.c | 14 +++++++++++ 21 files changed, 63 insertions(+), 152 deletions(-) delete mode 100644 include/fuse/device.h delete mode 100644 include/fuse/flags.h delete mode 100644 src/fuse/device.c delete mode 100644 src/picofuse/main.c create mode 100644 src/picofuse/picofuse.c diff --git a/examples/picofuse/gpio_in/run.c b/examples/picofuse/gpio_in/run.c index 97493ed..fe9b3a4 100644 --- a/examples/picofuse/gpio_in/run.c +++ b/examples/picofuse/gpio_in/run.c @@ -2,9 +2,14 @@ int run(fuse_t *fuse) { + // Initialize picofuse + picofuse_init(fuse); + // GPIO Pin 26 input - fuse_gpio_t *pin = fuse_new_gpio(fuse, 26, FUSE_GPIO_IN); + fuse_gpio_t *pin = fuse_new_gpio(fuse, 23, FUSE_GPIO_IN); assert(pin); + fuse_printf(fuse,"gpio %v", pin); + return 0; } diff --git a/include/fuse/device.h b/include/fuse/device.h deleted file mode 100644 index 92b0178..0000000 --- a/include/fuse/device.h +++ /dev/null @@ -1,35 +0,0 @@ -/** @file device.h - * @brief Fuse device registration - */ -#ifndef FUSE_DEVICE_H -#define FUSE_DEVICE_H - -/////////////////////////////////////////////////////////////////////////////// -// TYPES - -/** @brief Fuse device context - */ -typedef void *fuse_context_t; - -/** @brief Fuse device - */ -typedef struct -{ - const char *name; - fuse_context_t *(*init)(fuse_t *fuse, void *userdata); - void (*destroy)(fuse_t *fuse, fuse_context_t *context); -} fuse_device_t; - -/////////////////////////////////////////////////////////////////////////////// -// METHODS - -/** @brief Register a fuse device - * - * @param fuse The fuse application - * @param device A pointer to the device to register - * @param user_data Additional arguments that the device needs for registration - * @returns A device context, or NULL if registration failed - */ -fuse_context_t *fuse_register(fuse_t *fuse, fuse_device_t *device, void *user_data); - -#endif diff --git a/include/fuse/event.h b/include/fuse/event.h index b6be255..6a491e0 100644 --- a/include/fuse/event.h +++ b/include/fuse/event.h @@ -6,6 +6,8 @@ #ifndef FUSE_EVENT_H #define FUSE_EVENT_H +#include "value.h" + // Define the event types #define FUSE_EVENT_NULL 0x00 ///< NULL event #define FUSE_EVENT_TIMER 0x01 ///< Timer event diff --git a/include/fuse/flags.h b/include/fuse/flags.h deleted file mode 100644 index dd9f4e4..0000000 --- a/include/fuse/flags.h +++ /dev/null @@ -1,40 +0,0 @@ -/** @file flags.h - * @brief Feature flags for fuse - * - * This file contains the feature flags for fuse - */ -#ifndef FUSE_FLAG_H -#define FUSE_FLAG_H - -/** @brief Flags for the fuse application or memory pool - */ -typedef enum -{ - FUSE_NONE = 0x000, ///< No flags - FUSE_FLAG_DEBUG = 0x100, ///< Debug mode - prints out more verbose output - FUSE_CLASS_MASK = 0x0FF, ///< Mask for the class value - FUSE_CLASS_PTR = 0x001, ///< Pointer class - FUSE_CLASS_CSTR = 0x002, ///< Immutable UTF-8 string class - FUSE_CLASS_USTR = 0x002, ///< Mutable UTF-8 string class - FUSE_CLASS_U8 = 0x003, ///< uint8_t class - FUSE_CLASS_U16 = 0x004, ///< uint16_t class - FUSE_CLASS_U32 = 0x005, ///< uint32_t class - FUSE_CLASS_U64 = 0x006, ///< uint64_t class - FUSE_CLASS_S8 = 0x007, ///< int8_t class - FUSE_CLASS_S16 = 0x008, ///< int16_t class - FUSE_CLASS_S32 = 0x009, ///< int32_t class - FUSE_CLASS_S64 = 0x00A, ///< int64_t class - FUSE_CLASS_F32 = 0x00B, ///< float32_t class - FUSE_CLASS_MAP = 0x00C, ///< fuse_map_t class - FUSE_CLASS_LIST = 0x00D ///< fuse_list_t class -} fuse_flag_t; - -/** @brief Check for existence of fuse flags - * - * @param fuse The fuse application - * @param flag The flags to check for - * @returns True if all the flags are set, false otherwise - */ -bool fuse_is(fuse_t *fuse, fuse_flag_t flag); - -#endif diff --git a/include/fuse/fuse.h b/include/fuse/fuse.h index f9a0adb..a1ac08b 100644 --- a/include/fuse/fuse.h +++ b/include/fuse/fuse.h @@ -13,7 +13,6 @@ typedef struct fuse_application fuse_t; #include "assert.h" -#include "device.h" #include "event.h" #include "list.h" #include "magic.h" @@ -22,6 +21,7 @@ typedef struct fuse_application fuse_t; #include "printf.h" #include "random.h" #include "sleep.h" +#include "string.h" #include "timer.h" #include "value.h" diff --git a/include/fuse/random.h b/include/fuse/random.h index 6898d43..bb55229 100644 --- a/include/fuse/random.h +++ b/include/fuse/random.h @@ -8,6 +8,7 @@ */ #ifndef FUSE_RANDOM_H #define FUSE_RANDOM_H + #include /** @brief Return a random unsigned 32 bit number diff --git a/include/fuse/value.h b/include/fuse/value.h index 7d3b278..b1721aa 100644 --- a/include/fuse/value.h +++ b/include/fuse/value.h @@ -8,6 +8,8 @@ #include "fuse.h" #include +#include +#include /** @brief The representation of a fuse value */ diff --git a/include/picofuse/picofuse.h b/include/picofuse/picofuse.h index 82c48ce..8a314fd 100644 --- a/include/picofuse/picofuse.h +++ b/include/picofuse/picofuse.h @@ -9,4 +9,10 @@ #include #include "gpio.h" +/* @brief Register picofuse types + * + * @param fuse The fuse application + */ +void picofuse_init(fuse_t *fuse); + #endif diff --git a/src/fuse/CMakeLists.txt b/src/fuse/CMakeLists.txt index 7121f98..7b2c5d2 100644 --- a/src/fuse/CMakeLists.txt +++ b/src/fuse/CMakeLists.txt @@ -4,7 +4,6 @@ add_library(${NAME} STATIC alloc_builtin.c base64.c data.c - device.c event.c ftostr.c fuse.c diff --git a/src/fuse/alloc.h b/src/fuse/alloc.h index c584497..fb21097 100644 --- a/src/fuse/alloc.h +++ b/src/fuse/alloc.h @@ -6,6 +6,7 @@ #include #include +#include /** @brief Represents a memory block header */ diff --git a/src/fuse/device.c b/src/fuse/device.c deleted file mode 100644 index f0a6a12..0000000 --- a/src/fuse/device.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -/////////////////////////////////////////////////////////////////////////////// -// GLOBALS - -fuse_context_t *fuse_register(fuse_t *fuse, fuse_device_t *device, void *user_data) -{ - assert(device); - assert(device->init); - - fuse_context_t *context = device->init(fuse, user_data); - if (context) - { - fuse_debugf(fuse, "fuse_register: %s context=%p\n", device->name, context); - } - else - { - fuse_debugf(fuse, "fuse_register: %s failed\n", device->name); - } - - // Return success - return context; -} diff --git a/src/fuse/event.h b/src/fuse/event.h index 4db95b2..bfb1d65 100644 --- a/src/fuse/event.h +++ b/src/fuse/event.h @@ -5,6 +5,7 @@ #define FUSE_PRIVATE_EVENT_H #include +#include /** @brief Event data */ diff --git a/src/fuse/fuse.h b/src/fuse/fuse.h index 6f0c69f..71e5e5d 100644 --- a/src/fuse/fuse.h +++ b/src/fuse/fuse.h @@ -3,8 +3,10 @@ */ #ifndef FUSE_PRIVATE_FUSE_H #define FUSE_PRIVATE_FUSE_H + #include #include +#include "alloc.h" #include "event.h" #include "list.h" diff --git a/src/fuse/list.h b/src/fuse/list.h index 6f4982b..8128daf 100644 --- a/src/fuse/list.h +++ b/src/fuse/list.h @@ -4,6 +4,8 @@ #ifndef FUSE_PRIVATE_LIST_H #define FUSE_PRIVATE_LIST_H +#include + /** @brief Represents a linked list */ struct fuse_list diff --git a/src/fuse/string.h b/src/fuse/string.h index 8a89092..b929dfe 100644 --- a/src/fuse/string.h +++ b/src/fuse/string.h @@ -4,6 +4,8 @@ #ifndef FUSE_PRIVATE_STRING_H #define FUSE_PRIVATE_STRING_H +#include "fuse.h" + /** @brief Register type for string values */ void fuse_register_value_string(fuse_t *self); diff --git a/src/fuse/value.h b/src/fuse/value.h index f019b68..922a4a9 100644 --- a/src/fuse/value.h +++ b/src/fuse/value.h @@ -5,6 +5,7 @@ #define FUSE_PRIVATE_VALUE_H #include +#include /** @brief Represents a value * diff --git a/src/picofuse/CMakeLists.txt b/src/picofuse/CMakeLists.txt index 46d9824..36c7f40 100644 --- a/src/picofuse/CMakeLists.txt +++ b/src/picofuse/CMakeLists.txt @@ -1,10 +1,12 @@ set(NAME "picofuse") add_library(${NAME} STATIC gpio.c + picofuse.c ) target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../../include + ${CMAKE_CURRENT_LIST_DIR}/../fuse ) target_link_libraries(${NAME} diff --git a/src/picofuse/gpio.c b/src/picofuse/gpio.c index 40cae44..6ec725e 100644 --- a/src/picofuse/gpio.c +++ b/src/picofuse/gpio.c @@ -1,12 +1,17 @@ #include #include #include "gpio.h" +#include "printf.h" /////////////////////////////////////////////////////////////////////////////// // DECLARATIONS static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func); +/** @brief Append a string representation of a GPIO pin + */ +static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_value_t *v); + /////////////////////////////////////////////////////////////////////////////// // GLOBALS @@ -24,7 +29,8 @@ void fuse_register_value_gpio(fuse_t *self) // Register mutex type fuse_value_desc_t fuse_gpio_type = { .size = sizeof(struct gpio_context), - .name = "GPIO" + .name = "GPIO", + .cstr = fuse_gpio_cstr }; fuse_register_value_type(self, FUSE_MAGIC_GPIO, fuse_gpio_type); @@ -108,12 +114,6 @@ static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func) // Set GPIO pin to SIO gpio_init(pin); -<<<<<<< HEAD -======= - // If true, adc_init has been called - static bool adc = false; - ->>>>>>> 2278aef4da32cc3a813ebe2a7fc33b28a0c0b093 // Set function based on function switch (func) { @@ -153,6 +153,18 @@ static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func) } } +/** @brief Append a string representation of a GPIO pin + */ +static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_value_t *v) { + assert(self); + assert(buf == NULL || sz > 0); + assert(v); + + i = chtostr_internal(buf, sz, i, '{'); + + return i; +} + /* picofuse_func_t fuse_gpio_func(uint8_t pin) { assert(pin < fuse_gpio_count()); diff --git a/src/picofuse/gpio.h b/src/picofuse/gpio.h index 8ca1e9d..3a9666e 100644 --- a/src/picofuse/gpio.h +++ b/src/picofuse/gpio.h @@ -5,6 +5,7 @@ #define FUSE_PRIVATE_GPIO_H #include +#include /** @brief GPIO context */ diff --git a/src/picofuse/main.c b/src/picofuse/main.c deleted file mode 100644 index af2d238..0000000 --- a/src/picofuse/main.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -// PUBLIC METHODS - -int fuse_main(fuse_flag_t flags, int main(fuse_t *fuse)) -{ -#ifdef TARGET_PICO - fuse_stdio_init(); -#endif - fuse_debugf(NULL, "picofuse_main: flags=%d\n", flags); - - // Create a fuse application - fuse_t *fuse = fuse_new(flags); - assert(fuse); - - // Initialize the LED - fuse_led_new(); - - // Call the main function - // If the exit code is non-zero then print - int exit_code = main(fuse); - - // De-initialize the LED - fuse_led_destroy(); - - // Release the fuse application - fuse_destroy(fuse); - - // Report terminating the application - fuse_debugf(fuse, "picofuse_main: exit code %d\n", exit_code); - - // Endless loop on the pico -#ifdef TARGET_PICO - while (1) - { - sleep_ms(1000); - } -#endif - - // Return success - return exit_code; -} diff --git a/src/picofuse/picofuse.c b/src/picofuse/picofuse.c new file mode 100644 index 0000000..603a17e --- /dev/null +++ b/src/picofuse/picofuse.c @@ -0,0 +1,14 @@ +#include +#include +#include "gpio.h" + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +void picofuse_init(fuse_t *fuse) +{ + assert(fuse); + + // Register picofuse types + fuse_register_value_gpio(fuse); +} From 7453daf96eb0d9aa27bcfade46cae00d244a87dc Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Tue, 3 Sep 2024 17:15:44 +0200 Subject: [PATCH 2/5] Updated --- examples/picofuse/gpio_in/run.c | 23 +++++++++++++++----- src/fuse/fuse.c | 4 ++-- src/fuse/fuse.h | 3 +++ src/picofuse/gpio.c | 37 +++++++++++++++++++++++++++------ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/examples/picofuse/gpio_in/run.c b/examples/picofuse/gpio_in/run.c index fe9b3a4..589b417 100644 --- a/examples/picofuse/gpio_in/run.c +++ b/examples/picofuse/gpio_in/run.c @@ -1,15 +1,28 @@ #include -int run(fuse_t *fuse) +/* @brief Callback fro when there is a rising or falling edge on GPIO32 + */ +void gpio23_callback(fuse_t *self, fuse_event_t *evt, void *user_data) +{ + assert(self); + assert(evt); + assert(user_data); + + // Print the event + fuse_printf(self, "Event: evt=%q user_data=%p\n", evt, user_data); +} + +int run(fuse_t *self) { // Initialize picofuse - picofuse_init(fuse); + picofuse_init(self); - // GPIO Pin 26 input - fuse_gpio_t *pin = fuse_new_gpio(fuse, 23, FUSE_GPIO_IN); + // GPIO Pin 26 input - BOOLSEL on the pico lipo + fuse_gpio_t *pin = fuse_new_gpio(self, 23, FUSE_GPIO_IN); assert(pin); - fuse_printf(fuse,"gpio %v", pin); + // Register a callback + assert(fuse_register_callback(self, FUSE_EVENT_GPIO, 0, gpio23_callback)); return 0; } diff --git a/src/fuse/fuse.c b/src/fuse/fuse.c index 5961c19..b567527 100644 --- a/src/fuse/fuse.c +++ b/src/fuse/fuse.c @@ -293,7 +293,7 @@ static void fuse_runloop(fuse_t *self, uint8_t q) assert(q < 2); // Run the loop - fuse_debugf(self, "fuse_runloop: core %u (exit_code=%d)\n", q, self->exit_code); + fuse_debugf(self, "fuse_runloop: core %u: start\n", q); while (!self->exit_code) { // Pop event from the event queue @@ -313,7 +313,7 @@ static void fuse_runloop(fuse_t *self, uint8_t q) drained = fuse_drain(self, 10); if (drained > 0) { - fuse_debugf(self, "fuse_runloop: drained %lu item(s)\n", drained); + fuse_debugf(self, "fuse_runloop: drained %u item(s)\n", drained); } else { diff --git a/src/fuse/fuse.h b/src/fuse/fuse.h index 71e5e5d..f14b163 100644 --- a/src/fuse/fuse.h +++ b/src/fuse/fuse.h @@ -6,8 +6,11 @@ #include #include +#include +#include #include "alloc.h" #include "event.h" +#include "fuse.h" #include "list.h" /////////////////////////////////////////////////////////////////////////////// diff --git a/src/picofuse/gpio.c b/src/picofuse/gpio.c index 6ec725e..8c66417 100644 --- a/src/picofuse/gpio.c +++ b/src/picofuse/gpio.c @@ -1,5 +1,6 @@ #include #include +#include #include "gpio.h" #include "printf.h" @@ -12,10 +13,15 @@ static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func); */ static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_value_t *v); +/** @brief Callback for interrupt + */ +static void fuse_gpio_callback(uint pin, uint32_t events); + /////////////////////////////////////////////////////////////////////////////// // GLOBALS -static bool fuse_gpio_init[NUM_BANK0_GPIOS]; +static fuse_gpio_t * fuse_gpio_pin[NUM_BANK0_GPIOS]; +static fuse_t* fuse_gpio_instance = NULL; /////////////////////////////////////////////////////////////////////////////// // LIFECYCLE @@ -30,14 +36,18 @@ void fuse_register_value_gpio(fuse_t *self) fuse_value_desc_t fuse_gpio_type = { .size = sizeof(struct gpio_context), .name = "GPIO", - .cstr = fuse_gpio_cstr + .cstr = fuse_gpio_cstr, + .qstr = fuse_gpio_cstr }; fuse_register_value_type(self, FUSE_MAGIC_GPIO, fuse_gpio_type); // Reset the GPIO pins for(size_t i = 0; i < NUM_BANK0_GPIOS; i++) { - fuse_gpio_init[i] = false; + fuse_gpio_pin[i] = NULL; } + + // Set the callback instance + fuse_gpio_instance = self; } ////////////////////////////////////////////////////////////////////////////// @@ -54,7 +64,7 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, assert(func < FUSE_GPIO_FUNC_COUNT); // If pin alreadt initialized, return - if(fuse_gpio_init[pin]) { + if(fuse_gpio_pin[pin] != NULL) { return NULL; } @@ -71,7 +81,10 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, fuse_gpio_setfunc(pin, func); // Indicate the GPIO pin is initialized - fuse_gpio_init[pin] = true; + fuse_gpio_pin[pin] = ctx; + + // Set up the interrupt + gpio_set_irq_enabled_with_callback(pin, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &fuse_gpio_callback); // Return the GPIO context return ctx; @@ -160,11 +173,23 @@ static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_ assert(buf == NULL || sz > 0); assert(v); - i = chtostr_internal(buf, sz, i, '{'); + i = cstrtostr_internal(buf, sz, i, self->desc[FUSE_MAGIC_GPIO].name); + i = utostr_internal(buf, sz, i, ((fuse_gpio_t *)v)->pin, 0); return i; } +/** @brief GPIO callback - place event on the queues + */ +static void fuse_gpio_callback(uint pin, uint32_t events) { + fuse_t* self = fuse_gpio_instance; + fuse_gpio_t* source = fuse_gpio_pin[pin]; + if(self && pin) { + fuse_event_t* evt = fuse_new_event(self, (fuse_value_t* )source, FUSE_EVENT_GPIO, (void* )events); + assert(evt); + } +} + /* picofuse_func_t fuse_gpio_func(uint8_t pin) { assert(pin < fuse_gpio_count()); From a6c0a6692595ace045603b644b7342549f27f2d5 Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Tue, 3 Sep 2024 17:27:15 +0200 Subject: [PATCH 3/5] Updates --- examples/picofuse/gpio_in/run.c | 7 ++++--- src/picofuse/gpio.c | 15 ++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/picofuse/gpio_in/run.c b/examples/picofuse/gpio_in/run.c index 589b417..0231331 100644 --- a/examples/picofuse/gpio_in/run.c +++ b/examples/picofuse/gpio_in/run.c @@ -1,6 +1,6 @@ #include -/* @brief Callback fro when there is a rising or falling edge on GPIO32 +/* @brief Callback when there is a rising or falling edge on GPIO32 */ void gpio23_callback(fuse_t *self, fuse_event_t *evt, void *user_data) { @@ -9,7 +9,7 @@ void gpio23_callback(fuse_t *self, fuse_event_t *evt, void *user_data) assert(user_data); // Print the event - fuse_printf(self, "Event: evt=%q user_data=%p\n", evt, user_data); + fuse_printf(self, "Event: evt=%v user_data=%p\n", evt, user_data); } int run(fuse_t *self) @@ -18,7 +18,8 @@ int run(fuse_t *self) picofuse_init(self); // GPIO Pin 26 input - BOOLSEL on the pico lipo - fuse_gpio_t *pin = fuse_new_gpio(self, 23, FUSE_GPIO_IN); + // We retain the GPIO pin, and theoretically it should be released before the application exits + fuse_gpio_t *pin = (fuse_gpio_t* )fuse_retain(self,(fuse_value_t* )fuse_new_gpio(self, 23, FUSE_GPIO_IN)); assert(pin); // Register a callback diff --git a/src/picofuse/gpio.c b/src/picofuse/gpio.c index 8c66417..db28843 100644 --- a/src/picofuse/gpio.c +++ b/src/picofuse/gpio.c @@ -36,8 +36,9 @@ void fuse_register_value_gpio(fuse_t *self) fuse_value_desc_t fuse_gpio_type = { .size = sizeof(struct gpio_context), .name = "GPIO", + .destroy = NULL, // TODO: We meed to have a destroy function .cstr = fuse_gpio_cstr, - .qstr = fuse_gpio_cstr + .qstr = fuse_gpio_cstr // TODO: we need to implement a qstr function }; fuse_register_value_type(self, FUSE_MAGIC_GPIO, fuse_gpio_type); @@ -69,7 +70,7 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, } // Create a new GPIO context - fuse_gpio_t *ctx = (fuse_gpio_t *)fuse_new_value_ex(self, FUSE_MAGIC_GPIO, 0, file, line); + fuse_gpio_t *ctx = (fuse_gpio_t *)fuse_new_value_ex(self, FUSE_MAGIC_GPIO, (void* )pin, file, line); if(ctx == NULL) { return NULL; } @@ -77,15 +78,15 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, // Set the GPIO pin ctx->pin = pin; - // Set the GPIO function - fuse_gpio_setfunc(pin, func); - // Indicate the GPIO pin is initialized fuse_gpio_pin[pin] = ctx; - // Set up the interrupt + // Set up the interrupt for RISE and FALL events gpio_set_irq_enabled_with_callback(pin, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &fuse_gpio_callback); + // Set the GPIO function + fuse_gpio_setfunc(pin, func); + // Return the GPIO context return ctx; } @@ -93,7 +94,7 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, /////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS -/* @brief Return the GPIO cound (GPIO[0]...G~PIO[count-1]) +/** @brief Return the GPIO cound (GPIO[0]...GPIO[count-1]) */ inline uint8_t fuse_gpio_count() { From 61149c5b8fd0805dfd6afbc3bfba97b4eaac9cbd Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Tue, 3 Sep 2024 19:21:08 +0200 Subject: [PATCH 4/5] Updated gpio --- README.md | 8 ++--- include/picofuse/gpio.h | 3 +- src/picofuse/gpio.c | 70 +++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 4b367de..bb3b22b 100755 --- a/README.md +++ b/README.md @@ -76,8 +76,6 @@ Whenever you target a different board, use `make clean` before `make picotool` a ## References - * Pico SDK - * Repository https://github.com/raspberrypi/pico-sdk - * Documentation (in PDF) https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf - - +* Pico SDK + * Repository https://github.com/raspberrypi/pico-sdk + * Documentation (in PDF) https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf diff --git a/include/picofuse/gpio.h b/include/picofuse/gpio.h index 794f024..2cf0f39 100644 --- a/include/picofuse/gpio.h +++ b/include/picofuse/gpio.h @@ -27,7 +27,8 @@ typedef enum #define fuse_new_gpio(self, pin, func) \ ((fuse_gpio_t *)fuse_new_gpio_ex((self), (pin), (func), __FILE__, __LINE__)) #else -#define fuse_new_gpio((self, pin, func)((fuse_gpio_t *)fuse_new_gpio_ex((self), (pin), (func), 0, 0)) +#define fuse_new_gpio(self, pin, func) \ + ((fuse_gpio_t *)fuse_new_gpio_ex((self), (pin), (func), 0, 0)) #endif /** @brief An opaque event object diff --git a/src/picofuse/gpio.c b/src/picofuse/gpio.c index db28843..4ec8332 100644 --- a/src/picofuse/gpio.c +++ b/src/picofuse/gpio.c @@ -7,16 +7,26 @@ /////////////////////////////////////////////////////////////////////////////// // DECLARATIONS -static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func); - -/** @brief Append a string representation of a GPIO pin +/** @brief Set the function of a GPIO pin */ -static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_value_t *v); +static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func); /** @brief Callback for interrupt */ static void fuse_gpio_callback(uint pin, uint32_t events); +/** @brief Initialize a GPIO pin and set the interrupt + */ +static bool fuse_gpio_init(fuse_t *self, fuse_value_t *value, const void *user_data); + +/** @brief Disable the interrupt on a GPIO pin + */ +static void fuse_gpio_destroy(fuse_t *self, fuse_value_t *value); + +/** @brief Append a string representation of a GPIO pin + */ +static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_value_t *v); + /////////////////////////////////////////////////////////////////////////////// // GLOBALS @@ -32,11 +42,12 @@ void fuse_register_value_gpio(fuse_t *self) { assert(self); - // Register mutex type + // Register gpio type fuse_value_desc_t fuse_gpio_type = { .size = sizeof(struct gpio_context), .name = "GPIO", - .destroy = NULL, // TODO: We meed to have a destroy function + .init = fuse_gpio_init, + .destroy = fuse_gpio_destroy, .cstr = fuse_gpio_cstr, .qstr = fuse_gpio_cstr // TODO: we need to implement a qstr function }; @@ -64,26 +75,12 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, assert(pin < fuse_gpio_count()); assert(func < FUSE_GPIO_FUNC_COUNT); - // If pin alreadt initialized, return - if(fuse_gpio_pin[pin] != NULL) { - return NULL; - } - // Create a new GPIO context fuse_gpio_t *ctx = (fuse_gpio_t *)fuse_new_value_ex(self, FUSE_MAGIC_GPIO, (void* )pin, file, line); if(ctx == NULL) { return NULL; } - // Set the GPIO pin - ctx->pin = pin; - - // Indicate the GPIO pin is initialized - fuse_gpio_pin[pin] = ctx; - - // Set up the interrupt for RISE and FALL events - gpio_set_irq_enabled_with_callback(pin, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &fuse_gpio_callback); - // Set the GPIO function fuse_gpio_setfunc(pin, func); @@ -120,6 +117,39 @@ inline bool fuse_gpio_get(fuse_gpio_t *pin, bool value) { /////////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS + +/** @brief Initialize a GPIO pin and set the interrupt + */ +static bool fuse_gpio_init(fuse_t *self, fuse_value_t *value, const void *user_data) { + assert(self); + assert(value); + assert(user_data); + + // If pin already initialized, return + fuse_gpio_t * ctx = (fuse_gpio_t * )value; + size_t pin = (size_t)user_data; + if(fuse_gpio_pin[pin] != NULL) { + return false; + } else { + fuse_gpio_pin[pin] = ctx; + ctx->pin = pin; + } + + // Set up the interrupt for RISE and FALL events + gpio_set_irq_enabled_with_callback(pin, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &fuse_gpio_callback); +} + +/** @brief Disable the interrupt on a GPIO pin + */ +static void fuse_gpio_destroy(fuse_t *self, fuse_value_t *value) { + assert(self); + assert(value); + + fuse_gpio_t * ctx = (fuse_gpio_t * )value; + fuse_debugf(self, "GPIO: Destroying %v\n",ctx); + +} + static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func) { assert(pin < fuse_gpio_count()); From dc3832af578ccef25ad00bc185cfb3023cda1a42 Mon Sep 17 00:00:00 2001 From: David Thorpe Date: Tue, 3 Sep 2024 19:53:11 +0200 Subject: [PATCH 5/5] Updated GPIO --- examples/picofuse/gpio_in/run.c | 15 +++++---- include/fuse/fuse.h | 2 +- include/fuse/{string.h => str.h} | 2 +- include/fuse/value.h | 8 ++--- src/fuse/CMakeLists.txt | 2 +- src/fuse/fuse.c | 2 +- src/fuse/{string.c => str.c} | 0 src/fuse/{string.h => str.h} | 0 src/fuse/value.c | 15 +++++---- src/picofuse/gpio.c | 55 ++++++++++++-------------------- 10 files changed, 44 insertions(+), 57 deletions(-) rename include/fuse/{string.h => str.h} (98%) rename src/fuse/{string.c => str.c} (100%) rename src/fuse/{string.h => str.h} (100%) diff --git a/examples/picofuse/gpio_in/run.c b/examples/picofuse/gpio_in/run.c index 0231331..6e7e824 100644 --- a/examples/picofuse/gpio_in/run.c +++ b/examples/picofuse/gpio_in/run.c @@ -1,8 +1,8 @@ #include -/* @brief Callback when there is a rising or falling edge on GPIO32 +/* @brief Callback when there is a rising or falling edge on GPIO pin */ -void gpio23_callback(fuse_t *self, fuse_event_t *evt, void *user_data) +void gpio_callback(fuse_t *self, fuse_event_t *evt, void *user_data) { assert(self); assert(evt); @@ -17,13 +17,14 @@ int run(fuse_t *self) // Initialize picofuse picofuse_init(self); - // GPIO Pin 26 input - BOOLSEL on the pico lipo - // We retain the GPIO pin, and theoretically it should be released before the application exits - fuse_gpio_t *pin = (fuse_gpio_t* )fuse_retain(self,(fuse_value_t* )fuse_new_gpio(self, 23, FUSE_GPIO_IN)); - assert(pin); + // GPIO inputs + assert(fuse_retain(self, fuse_new_gpio(self, 23, FUSE_GPIO_IN))); + assert(fuse_retain(self, fuse_new_gpio(self, 12, FUSE_GPIO_PULLUP))); + assert(fuse_retain(self, fuse_new_gpio(self, 13, FUSE_GPIO_PULLUP))); + assert(fuse_retain(self, fuse_new_gpio(self, 14, FUSE_GPIO_PULLUP))); // Register a callback - assert(fuse_register_callback(self, FUSE_EVENT_GPIO, 0, gpio23_callback)); + assert(fuse_register_callback(self, FUSE_EVENT_GPIO, 0, gpio_callback)); return 0; } diff --git a/include/fuse/fuse.h b/include/fuse/fuse.h index a1ac08b..4cff327 100644 --- a/include/fuse/fuse.h +++ b/include/fuse/fuse.h @@ -21,7 +21,7 @@ typedef struct fuse_application fuse_t; #include "printf.h" #include "random.h" #include "sleep.h" -#include "string.h" +#include "str.h" #include "timer.h" #include "value.h" diff --git a/include/fuse/string.h b/include/fuse/str.h similarity index 98% rename from include/fuse/string.h rename to include/fuse/str.h index 180f76d..19921fa 100644 --- a/include/fuse/string.h +++ b/include/fuse/str.h @@ -1,4 +1,4 @@ -/** @file string.h +/** @file str.h * @brief String storage and manipulation * * This file contains the function prototypes for working with UTF-8 strings diff --git a/include/fuse/value.h b/include/fuse/value.h index b1721aa..c393e9f 100644 --- a/include/fuse/value.h +++ b/include/fuse/value.h @@ -70,10 +70,10 @@ fuse_value_t *fuse_new_value_ex(fuse_t *self, const uint16_t magic, const void * * This method increments the reference count of the value, to take ownership of the value. * * @param self The fuse instance - * @param value The value to retain + * @param value The value to retain, which must be a fuse_value_t* * @return The retained value, or NULL if the value could not be retained */ -fuse_value_t *fuse_retain(fuse_t *self, fuse_value_t *value); +fuse_value_t *fuse_retain(fuse_t *self, void *value); /** @brief Release a value and destroy it if the reference count reaches 0 * @@ -81,8 +81,8 @@ fuse_value_t *fuse_retain(fuse_t *self, fuse_value_t *value); * freed. * * @param self The fuse instance - * @param ptr The value to release + * @param ptr The value to release, which must be a fuse_value_t* */ -void fuse_release(fuse_t *self, fuse_value_t *value); +void fuse_release(fuse_t *self, void *value); #endif /* FUSE_VALUE_H */ diff --git a/src/fuse/CMakeLists.txt b/src/fuse/CMakeLists.txt index 7b2c5d2..18b3a5e 100644 --- a/src/fuse/CMakeLists.txt +++ b/src/fuse/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(${NAME} STATIC random_pico.c random_posix.c sleep_posix.c - string.c + str.c strtostr.c timer_darwin.c timer_linux.c diff --git a/src/fuse/fuse.c b/src/fuse/fuse.c index b567527..0d8c34c 100644 --- a/src/fuse/fuse.c +++ b/src/fuse/fuse.c @@ -14,7 +14,7 @@ #include "number.h" #include "null.h" #include "printf.h" -#include "string.h" +#include "str.h" #include "timer.h" /////////////////////////////////////////////////////////////////////////////// diff --git a/src/fuse/string.c b/src/fuse/str.c similarity index 100% rename from src/fuse/string.c rename to src/fuse/str.c diff --git a/src/fuse/string.h b/src/fuse/str.h similarity index 100% rename from src/fuse/string.h rename to src/fuse/str.h diff --git a/src/fuse/value.c b/src/fuse/value.c index df78a7f..92ccd33 100644 --- a/src/fuse/value.c +++ b/src/fuse/value.c @@ -36,32 +36,33 @@ fuse_value_t *fuse_new_value_ex(fuse_t *self, const uint16_t magic, const void * /** @brief Retain the value and return it. */ -fuse_value_t *fuse_retain(fuse_t *self, fuse_value_t *value) +fuse_value_t *fuse_retain(fuse_t *self, void *value) { assert(self); - assert(value == NULL || fuse_allocator_magic(self->allocator, value) < FUSE_MAGIC_COUNT); + assert(value == NULL || fuse_allocator_magic(self->allocator, (fuse_value_t *)value) < FUSE_MAGIC_COUNT); // Retain value if (value != NULL) { - fuse_allocator_retain(self->allocator, value); + fuse_allocator_retain(self->allocator, (fuse_value_t *)value); } // Return value - return value; + return (fuse_value_t *)value; } /** @brief Release a value and destroy it if the reference count reaches 0 */ -void fuse_release(fuse_t *self, fuse_value_t *value) +void fuse_release(fuse_t *self, void *value) { assert(self); - assert(value == NULL || fuse_allocator_magic(self->allocator, value) < FUSE_MAGIC_COUNT); + assert(value == NULL || fuse_allocator_magic(self->allocator, (fuse_value_t *)value) < FUSE_MAGIC_COUNT); // Decrement the reference count if (value != NULL) { - if(fuse_allocator_release(self->allocator, value)) { + if (fuse_allocator_release(self->allocator, (fuse_value_t *)value)) + { // Indicate we should drain the memory pool self->drain = true; } diff --git a/src/picofuse/gpio.c b/src/picofuse/gpio.c index 4ec8332..0f7e000 100644 --- a/src/picofuse/gpio.c +++ b/src/picofuse/gpio.c @@ -2,6 +2,7 @@ #include #include #include "gpio.h" +#include "fuse.h" #include "printf.h" /////////////////////////////////////////////////////////////////////////////// @@ -76,7 +77,7 @@ fuse_gpio_t *fuse_new_gpio_ex(fuse_t *self, uint8_t pin, fuse_gpio_func_t func, assert(func < FUSE_GPIO_FUNC_COUNT); // Create a new GPIO context - fuse_gpio_t *ctx = (fuse_gpio_t *)fuse_new_value_ex(self, FUSE_MAGIC_GPIO, (void* )pin, file, line); + fuse_gpio_t *ctx = (fuse_gpio_t *)fuse_new_value_ex(self, FUSE_MAGIC_GPIO, (void* )(uintptr_t)pin, file, line); if(ctx == NULL) { return NULL; } @@ -145,11 +146,24 @@ static void fuse_gpio_destroy(fuse_t *self, fuse_value_t *value) { assert(self); assert(value); + fuse_debugf(self, "GPIO: Destroying %v\n",value); + fuse_gpio_t * ctx = (fuse_gpio_t * )value; - fuse_debugf(self, "GPIO: Destroying %v\n",ctx); + assert(ctx->pin < fuse_gpio_count()); + + // TODO + // If the pin is set to ADC, then disable it + //if(fuse_adc_channel(pin) != FUSE_ADC_INVALID) { + // fuse_adc_destroy(pin); + //} + // Cancel the interrupt + gpio_set_irq_enabled_with_callback(ctx->pin, 0xFF, false, NULL); + gpio_deinit(ctx->pin); } +/** @brief Set the function of a GPIO pin + */ static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func) { assert(pin < fuse_gpio_count()); @@ -165,9 +179,6 @@ static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func) gpio_set_dir(pin, GPIO_IN); gpio_set_pulls(pin, false, false); break; - case FUSE_GPIO_OUT: - gpio_set_dir(pin, GPIO_OUT); - break; case FUSE_GPIO_PULLDN: gpio_set_dir(pin, GPIO_IN); gpio_set_pulls(pin, false, true); @@ -176,6 +187,9 @@ static void fuse_gpio_setfunc(uint8_t pin, fuse_gpio_func_t func) gpio_set_dir(pin, GPIO_IN); gpio_set_pulls(pin, true, false); break; + case FUSE_GPIO_OUT: + gpio_set_dir(pin, GPIO_OUT); + break; case FUSE_GPIO_PWM: gpio_set_function(pin, GPIO_FUNC_PWM); break; @@ -210,7 +224,7 @@ static size_t fuse_gpio_cstr(fuse_t *self, char *buf, size_t sz, size_t i, fuse_ return i; } -/** @brief GPIO callback - place event on the queues +/** @brief GPIO interrupt callback - place event on the queues */ static void fuse_gpio_callback(uint pin, uint32_t events) { fuse_t* self = fuse_gpio_instance; @@ -220,32 +234,3 @@ static void fuse_gpio_callback(uint pin, uint32_t events) { assert(evt); } } - -/* -picofuse_func_t fuse_gpio_func(uint8_t pin) { - assert(pin < fuse_gpio_count()); - - // Get the GPIO function - uint gpio_func = gpio_get_function(pin); - switch(gpio_func) { - default: - assert(false); - } -} - -void fuse_gpio_destroy(uint8_t pin) -{ - assert(pin < fuse_gpio_count()); - - // If the pin is set to ADC, then disable it - if(fuse_adc_channel(pin) != FUSE_ADC_INVALID) { - fuse_adc_destroy(pin); - } - - gpio_deinit(pin); -} - -void fuse_gpio_event_enable(fuse_t *fuse, uint8_t pin, bool rising, bool falling) { - -} -*/