### Build and Test with Make Source: https://github.com/0x1abin/multibutton/blob/master/CONTRIBUTING.md Use Make for building the library and examples, and for running unit tests. ```bash make all # build library + examples make test # run unit tests ``` -------------------------------- ### Quick Start: Initialize and Use MultiButton Source: https://github.com/0x1abin/multibutton/blob/master/README.md This snippet demonstrates the basic setup for using the MultiButton library. It includes implementing a GPIO read function, defining an event callback, initializing the button, and starting the button handling. The timer interrupt must be called periodically to process button events. ```c #include "multi_button.h" static Button btn1; // 1. Implement GPIO read function uint8_t read_button_gpio(uint8_t button_id) { return HAL_GPIO_ReadPin(BUTTON1_GPIO_Port, BUTTON1_Pin); } // 2. Define event callback (receives user_data) void on_single_click(Button* btn, void* user_data) { // handle single click } // 3. Initialize and start void setup(void) { button_init(&btn1, read_button_gpio, 0, 1); // active low button_attach(&btn1, BTN_SINGLE_CLICK, on_single_click, NULL); button_start(&btn1); } // 4. Call from 5ms timer interrupt void timer_5ms_isr(void) { button_ticks(); } ``` -------------------------------- ### Build Library and Examples with CMake Source: https://github.com/0x1abin/multibutton/blob/master/README.md Commands to configure and build the multibutton library and examples using CMake. Includes running unit tests. ```bash # CMake cmake -B build -DMULTIBUTTON_BUILD_TESTS=ON -DMULTIBUTTON_BUILD_EXAMPLES=ON cmake --build build cd build && ctest ``` -------------------------------- ### Build Library and Examples with Make Source: https://github.com/0x1abin/multibutton/blob/master/README.md Commands to build the multibutton library and its examples using Make. Also includes commands for running unit tests. ```bash # Make make all # library + examples make test # run unit tests make library # static library only ``` -------------------------------- ### Build and Test with CMake Source: https://github.com/0x1abin/multibutton/blob/master/CONTRIBUTING.md Use CMake to configure, build, and test the project. Enable tests and examples during configuration. ```bash cmake -B build -DMULTIBUTTON_BUILD_TESTS=ON -DMULTIBUTTON_BUILD_EXAMPLES=ON cmake --build build cd build && ctest ``` -------------------------------- ### User Data Context Example Source: https://github.com/0x1abin/multibutton/blob/master/README.md Demonstrates how to define and use a context structure for passing user-specific data to button event callbacks. ```c typedef struct { int led_pin; int beep_count; } ButtonContext; ButtonContext ctx = { .led_pin = 13, .beep_count = 0 }; void on_click(Button* btn, void* user_data) { ButtonContext* ctx = (ButtonContext*)user_data; toggle_led(ctx->led_pin); ctx->beep_count++; } button_attach(&btn1, BTN_SINGLE_CLICK, on_click, &ctx); ``` -------------------------------- ### Core Functions Source: https://github.com/0x1abin/multibutton/blob/master/README.md These functions provide the fundamental operations for initializing, attaching events, detaching events, starting, and stopping the button state machine. ```APIDOC ## Core Functions ### `button_init` Initializes a button handle. - **Parameters**: - `handle` (Button*): Pointer to the button structure. - `pin_level` (uint8_t(*)(uint8_t)): Function to get the current pin level. - `active_level` (uint8_t): The logic level that indicates the button is pressed. - `button_id` (uint8_t): An identifier for the button. ### `button_attach` Attaches a callback function to a specific button event. - **Parameters**: - `handle` (Button*): Pointer to the button structure. - `event` (ButtonEvent): The event to attach the callback to. - `cb` (BtnCallback): The callback function to execute. - `user_data` (void*): Pointer to user-defined data to be passed to the callback. ### `button_detach` Detaches a callback function from a specific button event. - **Parameters**: - `handle` (Button*): Pointer to the button structure. - `event` (ButtonEvent): The event to detach the callback from. ### `button_start` Starts the button state machine processing. - **Returns**: - `0`: Success. - `-1`: Duplicate start. - `-2`: Invalid handle. ### `button_stop` Stops the button state machine processing. ### `button_ticks` Processes button state changes. This function should be called periodically (e.g., every 5ms) from a timer. ``` -------------------------------- ### Core Button Functions Source: https://github.com/0x1abin/multibutton/blob/master/README.md Essential functions for initializing, attaching/detaching event handlers, starting, stopping, and ticking the button state machine. ```c void button_init(Button* handle, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id); void button_attach(Button* handle, ButtonEvent event, BtnCallback cb, void* user_data); void button_detach(Button* handle, ButtonEvent event); int button_start(Button* handle); // returns 0=ok, -1=duplicate, -2=invalid void button_stop(Button* handle); void button_ticks(void); // call every 5ms from timer ``` -------------------------------- ### User Data (Context Pointer) Source: https://github.com/0x1abin/multibutton/blob/master/README.md Demonstrates how to use the `user_data` pointer to pass context information to callback functions, allowing for stateful event handling. ```APIDOC ## User Data (Context Pointer) Each callback function receives a `void* user_data` pointer, which is set during `button_attach()`. ### Example Usage ```c typedef struct { int led_pin; int beep_count; } ButtonContext; ButtonContext ctx = { .led_pin = 13, .beep_count = 0 }; void on_click(Button* btn, void* user_data) { ButtonContext* ctx = (ButtonContext*)user_data; toggle_led(ctx->led_pin); ctx->beep_count++; } button_attach(&btn1, BTN_SINGLE_CLICK, on_click, &ctx); ``` **Note**: All callbacks for the same button share the same `user_data` pointer. ``` -------------------------------- ### Configure Timer and Debounce Ticks Source: https://github.com/0x1abin/multibutton/blob/master/README.md Set the timer tick interval, debounce filter depth, and thresholds for short and long presses by editing defines in `multi_button.h`. ```c #define TICKS_INTERVAL 5 // timer tick interval (ms) #define DEBOUNCE_TICKS 3 // debounce filter depth (max 7) #define SHORT_TICKS (300 / TICKS_INTERVAL) // short press threshold #define LONG_TICKS (1000 / TICKS_INTERVAL) // long press threshold #define PRESS_REPEAT_MAX_NUM 15 // max repeat counter ``` -------------------------------- ### Button State Machine Diagram Source: https://github.com/0x1abin/multibutton/blob/master/README.md Visual representation of the button's state transitions including IDLE, PRESS, RELEASE, LONG_HOLD, and REPEAT states. ```text +-- long hold --> [LONG_HOLD] | [IDLE] -- press --> [PRESS] release ^ | | release | | v | | [RELEASE] <--------------------+ | | ^ | timeout| | quick press | | | +-------------+ [REPEAT] -- held too long --> [PRESS] ``` -------------------------------- ### Throttling Long Press Hold Callback Source: https://github.com/0x1abin/multibutton/blob/master/README.md Demonstrates how to throttle a callback for BTN_LONG_PRESS_HOLD to prevent excessive execution of expensive operations. Fires every 100ms instead of every tick. ```c void on_long_hold(Button* btn, void* user_data) { static uint16_t throttle = 0; if (++throttle < 20) return; // fire every 100ms instead throttle = 0; // ... do work ... } ``` -------------------------------- ### Utility Button Functions Source: https://github.com/0x1abin/multibutton/blob/master/README.md Helper functions to retrieve the current button event, repeat count, check press status, and reset the button state. ```c ButtonEvent button_get_event(Button* handle); // current event (polling mode) uint8_t button_get_repeat_count(Button* handle); // repeat press count int button_is_pressed(Button* handle); // 1=pressed, 0=released, -1=error void button_reset(Button* handle); // reset to idle state ``` -------------------------------- ### Implement Triple Click Detection Source: https://github.com/0x1abin/multibutton/blob/master/README.md Use the BTN_PRESS_REPEAT event and button_get_repeat_count() to implement triple click or higher N-click functionality. Register callbacks for repeat events and resolve the final click count. ```c void on_repeat_done(Button* btn, void* user_data) { // This fires when repeat press is detected // Check repeat count after timeout for final count } void on_click_resolve(Button* btn, void* user_data) { uint8_t count = button_get_repeat_count(btn); if (count == 3) { // Triple click! } } // Register for single click (fires after timeout with final repeat count) button_attach(&btn, BTN_SINGLE_CLICK, on_click_resolve, NULL); // Or check repeat count in any callback button_attach(&btn, BTN_PRESS_REPEAT, on_repeat_done, NULL); ``` -------------------------------- ### Enable Thread Safety with RTOS Mutex Source: https://github.com/0x1abin/multibutton/blob/master/README.md For RTOS environments, define lock macros to enable thread safety before including the header. On bare-metal, these macros compile to nothing. ```c #define MULTIBUTTON_THREAD_SAFE #define MULTIBUTTON_LOCK() osMutexAcquire(btn_mutex, osWaitForever) #define MULTIBUTTON_UNLOCK() osMutexRelease(btn_mutex) #include "multi_button.h" ``` -------------------------------- ### Utility Functions Source: https://github.com/0x1abin/multibutton/blob/master/README.md These functions provide ways to poll the current state and event of a button, retrieve repeat counts, check press status, and reset the button state. ```APIDOC ## Utility Functions ### `button_get_event` Gets the current event associated with the button handle (polling mode). - **Parameters**: - `handle` (Button*): Pointer to the button structure. - **Returns**: - The current `ButtonEvent`. ### `button_get_repeat_count` Gets the number of repeat presses detected for the button. - **Parameters**: - `handle` (Button*): Pointer to the button structure. - **Returns**: - The repeat press count. ### `button_is_pressed` Checks if the button is currently pressed. - **Parameters**: - `handle` (Button*): Pointer to the button structure. - **Returns**: - `1`: If pressed. - `0`: If released. - `-1`: If an error occurred. ### `button_reset` Resets the button state machine to the idle state. - **Parameters**: - `handle` (Button*): Pointer to the button structure. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.