button_init()
memset(): reset struct- Gán
read_pin,context: hàm đọc + dữ liệu đi kèm - Gán
config(nếu NULL thì dùngBUTTON_CONFIG_DEFAULT) - Đọc trạng thái ban đầu (debounce start)
button_attach_event(): gán callback cho 1 event cụ thểbutton_detach_event(): bỏ callback 1 eventbutton_attach_all_events(): gán cùng 1 callback cho tất cả eventbutton_detach_all_events(): bỏ hết callbackbutton_trigger_event(): gọi hàm callback khi event xảy ra
button_update()
- Gọi
read_pin(context): đọc GPIO qua hàm wrapper- Sử dụng
contextđể biết port/pin
- Sử dụng
- Debounce logic: lọc chống dội
- Nếu state thay đổi:
- PRESSED → gán
pressed=true- Lưu
last_press_time - Tăng
click_count(nếu trong interval) - Trigger
PRESSEDevent - Nếu advanced: trigger
SEQUENCE_START
- Lưu
- RELEASED → gán
pressed=false- Lưu
last_release_time - Nếu
ultra_longđang active → triggerULTRA_LONG_PRESS_END - Nếu
longđang active → triggerLONG_PRESS_END - Ngược lại → trigger
RELEASED
- Lưu
- PRESSED → gán
- Nếu đang PRESSED:
- Kiểm tra thời gian giữ
- Đạt
long_press_time→ triggerLONG_PRESS_START - Đạt
ultra_long_time→ triggerULTRA_LONG_PRESS_START
- Đạt
- Trigger
HOLDevent (LONG/ULTRA_LONG)
- Kiểm tra thời gian giữ
- Nếu RELEASED &
click_count > 0:- Nếu timeout
multi_click_interval:click_count==1→ triggerCLICKclick_count==2→ triggerDOUBLE_CLICKclick_count==3→ triggerTRIPLE_CLICK>=multi_click_count→ triggerSEQUENCE_COMPLETE
- Reset
click_count
- Nếu timeout
- Nếu advanced enabled → xử lý combo/pattern (extension point)
button_update_all()
- Lặp qua mảng
button[], gọibutton_update()cho từng nút
button_get_press_duration(): trả về thời gian đang giữbutton_get_click_count(): số lần click trong chuỗibutton_is_pressed(): trạng thái hiện tạibutton_is_long_pressed(): đang giữ lâu không?button_set_user_data(): gán dữ liệu tùy ý vào buttonbutton_get_user_data()button_set_custom_callback(): callback mở rộng riêngbutton_set_extension(): pointer mở rộngbutton_get_extension()
+-----------------+
| button_init() |
+-----------------+
|
+----------------+----------------+
| |
+-------------------+ +-------------------------+
| button_update() |<-------->| button_update_all() |
+-------------------+ +-------------------------+
|
+-----+-----------------------------------+
| |
Debounce + State Machine |
| |
+---------------------------+-------------+
|
+-----------------------+--------------------------+
| | |
Pressed events Released events Long/Ultra-long
(PRESSED, SEQ_START) (RELEASED, CLICK, ...) (START, HOLD, END)
+-------------------------+ +-------------------------+
| button_attach_event() | | button_trigger_event() |
| button_detach_event() |---->| gọi callback[event] |
| attach_all / detach_all | | nếu != NULL |
+-------------------------+ +-------------------------+
+--------------------------+
| Utility & Extensions |
| - get_press_duration |
| - get_click_count |
| - is_pressed |
| - set/get user_data |
| - set/get extension |
+--------------------------+
Time ↓
[User Action] [button_update()] [read_pin()] [Event Callback]
| | | |
|--- Press button ----->| | |
| |--- call ------------>| |
| | read_pin(context) | |
| |<-- return true ------| |
| | | |
| |--- debounce -------->| |
| |--- detect change ----| |
| |--- trigger --------->|--- PRESSED ----------> Callback
| | | |
| (holding...) |--- check duration ---> |
| |--- after long_press_time ------------------>| LONG_PRESS_START
| |--- periodically --------------------------->| LONG_PRESS_HOLD
| |--- after ultra_long_press_time ------------>| ULTRA_LONG_PRESS_START
| |--- periodically --------------------------->| ULTRA_LONG_PRESS_HOLD
| | | |
|--- Release button --->| | |
| |--- call ------------>| |
| | read_pin(context) | |
| |<-- return false -----| |
| |--- debounce -------->| |
| |--- detect release --> |
| |--- trigger --------->|--- RELEASED ---------> Callback
| |--- if long active --->|--- LONG_PRESS_END --> Callback
| |--- if ultra active -->|--- ULTRA_LONG_PRESS_END
| | | |
| (idle) |--- after timeout ----| |
| |--- trigger --------->|--- CLICK / DOUBLE / TRIPLE
| | | |