diff --git a/CMakeLists.txt b/CMakeLists.txt index 6161d4c..e24e090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,5 @@ target_sources(app PRIVATE src/events/time_sync_event.c src/events/usb_cdc_rx_event.c src/events/usb_cdc_tx_event.c - src/events/usb_device_state_event.c - src/events/usb_function_ready_event.c - src/events/usb_prepare_event.c + src/events/usb_state_event.c ) diff --git a/inc/events/usb_device_state_event.h b/inc/events/usb_device_state_event.h deleted file mode 100644 index 4e44a5d..0000000 --- a/inc/events/usb_device_state_event.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef BLINKY_USB_DEVICE_STATE_EVENT_H_ -#define BLINKY_USB_DEVICE_STATE_EVENT_H_ - -#include -#include - -#include "usb_device_module.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct usb_device_state_event { - struct app_event_header header; - enum usb_device_state state; -}; - -APP_EVENT_TYPE_DECLARE(usb_device_state_event); - -static inline void submit_usb_device_state_event(enum usb_device_state state) -{ - struct usb_device_state_event *event = new_usb_device_state_event(); - - event->state = state; - APP_EVENT_SUBMIT(event); -} - -#ifdef __cplusplus -} -#endif - -#endif /* BLINKY_USB_DEVICE_STATE_EVENT_H_ */ diff --git a/inc/events/usb_function_ready_event.h b/inc/events/usb_function_ready_event.h deleted file mode 100644 index 391135c..0000000 --- a/inc/events/usb_function_ready_event.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef BLINKY_USB_FUNCTION_READY_EVENT_H_ -#define BLINKY_USB_FUNCTION_READY_EVENT_H_ - -#include -#include - -#include "usb_device_module.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct usb_function_ready_event { - struct app_event_header header; - uint8_t function_mask; -}; - -APP_EVENT_TYPE_DECLARE(usb_function_ready_event); - -static inline void submit_usb_function_ready_event(uint8_t function_mask) -{ - struct usb_function_ready_event *event = new_usb_function_ready_event(); - - event->function_mask = function_mask; - APP_EVENT_SUBMIT(event); -} - -#ifdef __cplusplus -} -#endif - -#endif /* BLINKY_USB_FUNCTION_READY_EVENT_H_ */ diff --git a/inc/events/usb_prepare_event.h b/inc/events/usb_prepare_event.h deleted file mode 100644 index 661dd83..0000000 --- a/inc/events/usb_prepare_event.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef BLINKY_USB_PREPARE_EVENT_H_ -#define BLINKY_USB_PREPARE_EVENT_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct usb_prepare_event { - struct app_event_header header; -}; - -APP_EVENT_TYPE_DECLARE(usb_prepare_event); - -static inline void submit_usb_prepare_event(void) -{ - APP_EVENT_SUBMIT(new_usb_prepare_event()); -} - -#ifdef __cplusplus -} -#endif - -#endif /* BLINKY_USB_PREPARE_EVENT_H_ */ diff --git a/inc/events/usb_state_event.h b/inc/events/usb_state_event.h new file mode 100644 index 0000000..76fa759 --- /dev/null +++ b/inc/events/usb_state_event.h @@ -0,0 +1,82 @@ +#ifndef BLINKY_USB_STATE_EVENT_H_ +#define BLINKY_USB_STATE_EVENT_H_ + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum usb_state_event_op { + USB_STATE_EVENT_OP_SET_BITS, + USB_STATE_EVENT_OP_CLEAR_BITS, + USB_STATE_EVENT_OP_SNAPSHOT, +}; + +enum usb_state_flag { + USB_STATEF_PREPARE = BIT(0), + USB_STATEF_HID_READY = BIT(1), + USB_STATEF_CDC_READY = BIT(2), + USB_STATEF_STACK_READY = BIT(3), + USB_STATEF_POWERED = BIT(4), + USB_STATEF_ACTIVE = BIT(5), + USB_STATEF_SUSPENDED = BIT(6), + USB_STATEF_STACK_RUNNING = BIT(31), +}; + +struct usb_state_event { + struct app_event_header header; + const void *src_module_id; + const void *sink_module_id; + uint8_t op; + uint32_t flags; +}; + +APP_EVENT_TYPE_DECLARE(usb_state_event); + +static inline void submit_usb_state_event(const void *src_module_id, + const void *sink_module_id, + uint8_t op, + uint32_t flags) +{ + struct usb_state_event *event = new_usb_state_event(); + + event->src_module_id = src_module_id; + event->sink_module_id = sink_module_id; + event->op = op; + event->flags = flags; + APP_EVENT_SUBMIT(event); +} + +static inline void submit_usb_state_set(const void *src_module_id, + const void *sink_module_id, + uint32_t flags) +{ + submit_usb_state_event(src_module_id, sink_module_id, + USB_STATE_EVENT_OP_SET_BITS, flags); +} + +static inline void submit_usb_state_clear(const void *src_module_id, + const void *sink_module_id, + uint32_t flags) +{ + submit_usb_state_event(src_module_id, sink_module_id, + USB_STATE_EVENT_OP_CLEAR_BITS, flags); +} + +static inline void submit_usb_state_snapshot(const void *src_module_id, + uint32_t flags) +{ + submit_usb_state_event(src_module_id, NULL, + USB_STATE_EVENT_OP_SNAPSHOT, flags); +} + +#ifdef __cplusplus +} +#endif + +#endif /* BLINKY_USB_STATE_EVENT_H_ */ diff --git a/src/events/usb_device_state_event.c b/src/events/usb_device_state_event.c deleted file mode 100644 index e726a63..0000000 --- a/src/events/usb_device_state_event.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "usb_device_state_event.h" - -static const char *usb_device_state_name(enum usb_device_state state) -{ - switch (state) { - case USB_DEVICE_STATE_DISCONNECTED: - return "disconnected"; - case USB_DEVICE_STATE_POWERED: - return "powered"; - case USB_DEVICE_STATE_ACTIVE: - return "active"; - case USB_DEVICE_STATE_SUSPENDED: - return "suspended"; - default: - return "?"; - } -} - -static void log_usb_device_state_event(const struct app_event_header *aeh) -{ - const struct usb_device_state_event *event = - cast_usb_device_state_event(aeh); - - APP_EVENT_MANAGER_LOG(aeh, "state:%s", - usb_device_state_name(event->state)); -} - -static void profile_usb_device_state_event(struct log_event_buf *buf, - const struct app_event_header *aeh) -{ - const struct usb_device_state_event *event = - cast_usb_device_state_event(aeh); - - nrf_profiler_log_encode_uint8(buf, event->state); -} - -APP_EVENT_INFO_DEFINE(usb_device_state_event, - ENCODE(NRF_PROFILER_ARG_U8), - ENCODE("state"), - profile_usb_device_state_event); - -APP_EVENT_TYPE_DEFINE(usb_device_state_event, - log_usb_device_state_event, - &usb_device_state_event_info, - APP_EVENT_FLAGS_CREATE( - APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE)); diff --git a/src/events/usb_function_ready_event.c b/src/events/usb_function_ready_event.c deleted file mode 100644 index 8d74646..0000000 --- a/src/events/usb_function_ready_event.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "usb_function_ready_event.h" - -static const char *usb_function_name(uint8_t function_mask) -{ - switch (function_mask) { - case USB_FUNCTION_HID: - return "hid"; - case USB_FUNCTION_CDC_ACM: - return "cdc_acm"; - default: - return "?"; - } -} - -static void log_usb_function_ready_event(const struct app_event_header *aeh) -{ - const struct usb_function_ready_event *event = - cast_usb_function_ready_event(aeh); - - APP_EVENT_MANAGER_LOG(aeh, "function:%s", - usb_function_name(event->function_mask)); -} - -static void profile_usb_function_ready_event(struct log_event_buf *buf, - const struct app_event_header *aeh) -{ - const struct usb_function_ready_event *event = - cast_usb_function_ready_event(aeh); - - nrf_profiler_log_encode_uint8(buf, event->function_mask); -} - -APP_EVENT_INFO_DEFINE(usb_function_ready_event, - ENCODE(NRF_PROFILER_ARG_U8), - ENCODE("function_mask"), - profile_usb_function_ready_event); - -APP_EVENT_TYPE_DEFINE(usb_function_ready_event, - log_usb_function_ready_event, - &usb_function_ready_event_info, - APP_EVENT_FLAGS_CREATE( - APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE)); diff --git a/src/events/usb_prepare_event.c b/src/events/usb_prepare_event.c deleted file mode 100644 index 3bbfa44..0000000 --- a/src/events/usb_prepare_event.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "usb_prepare_event.h" - -static void log_usb_prepare_event(const struct app_event_header *aeh) -{ - APP_EVENT_MANAGER_LOG(aeh, "prepare"); -} - -static void profile_usb_prepare_event(struct log_event_buf *buf, - const struct app_event_header *aeh) -{ - ARG_UNUSED(buf); - ARG_UNUSED(aeh); -} - -APP_EVENT_INFO_DEFINE(usb_prepare_event, - ENCODE(), - ENCODE(), - profile_usb_prepare_event); - -APP_EVENT_TYPE_DEFINE(usb_prepare_event, - log_usb_prepare_event, - &usb_prepare_event_info, - APP_EVENT_FLAGS_CREATE( - APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE)); diff --git a/src/events/usb_state_event.c b/src/events/usb_state_event.c new file mode 100644 index 0000000..46aae02 --- /dev/null +++ b/src/events/usb_state_event.c @@ -0,0 +1,54 @@ +#include + +#include "usb_state_event.h" + +static const char *usb_state_event_op_name(uint8_t op) +{ + switch ((enum usb_state_event_op)op) { + case USB_STATE_EVENT_OP_SET_BITS: + return "set_bits"; + case USB_STATE_EVENT_OP_CLEAR_BITS: + return "clear_bits"; + case USB_STATE_EVENT_OP_SNAPSHOT: + return "snapshot"; + default: + return "?"; + } +} + +static const char *module_name_or_any(const void *module_id) +{ + return (module_id != NULL) ? module_name_get(module_id) : "*"; +} + +static void log_usb_state_event(const struct app_event_header *aeh) +{ + const struct usb_state_event *event = cast_usb_state_event(aeh); + + APP_EVENT_MANAGER_LOG(aeh, + "src:%s sink:%s op:%s flags:0x%08x", + module_name_or_any(event->src_module_id), + module_name_or_any(event->sink_module_id), + usb_state_event_op_name(event->op), + event->flags); +} + +static void profile_usb_state_event(struct log_event_buf *buf, + const struct app_event_header *aeh) +{ + const struct usb_state_event *event = cast_usb_state_event(aeh); + + nrf_profiler_log_encode_uint8(buf, event->op); + nrf_profiler_log_encode_uint32(buf, event->flags); +} + +APP_EVENT_INFO_DEFINE(usb_state_event, + ENCODE(NRF_PROFILER_ARG_U8, NRF_PROFILER_ARG_U32), + ENCODE("op", "flags"), + profile_usb_state_event); + +APP_EVENT_TYPE_DEFINE(usb_state_event, + log_usb_state_event, + &usb_state_event_info, + APP_EVENT_FLAGS_CREATE( + APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE)); diff --git a/src/protocol_module.c b/src/protocol_module.c index 95f8371..40bf560 100644 --- a/src/protocol_module.c +++ b/src/protocol_module.c @@ -25,7 +25,7 @@ #include "hid_led_event.h" #include "key_function_event.h" #include "protocol_module.h" -#include "usb_device_state_event.h" +#include "usb_state_event.h" LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); @@ -430,9 +430,14 @@ static bool handle_hid_led_event(const struct hid_led_event *event) return false; } -static bool handle_usb_device_state_event(const struct usb_device_state_event *event) +static bool handle_usb_state_event(const struct usb_state_event *event) { - usb_active = (event->state == USB_DEVICE_STATE_ACTIVE); + if ((event->op != USB_STATE_EVENT_OP_SNAPSHOT) || + (event->src_module_id != MODULE_ID(usb_device_module))) { + return false; + } + + usb_active = (event->flags & USB_STATEF_ACTIVE) != 0U; if (!usb_active) { hello_done = false; } @@ -450,8 +455,8 @@ static bool app_event_handler(const struct app_event_header *aeh) return handle_hid_led_event(cast_hid_led_event(aeh)); } - if (is_usb_device_state_event(aeh)) { - return handle_usb_device_state_event(cast_usb_device_state_event(aeh)); + if (is_usb_state_event(aeh)) { + return handle_usb_state_event(cast_usb_state_event(aeh)); } if (is_module_state_event(aeh)) { @@ -517,6 +522,6 @@ APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, hid_led_event); APP_EVENT_SUBSCRIBE(MODULE, key_function_event); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); -APP_EVENT_SUBSCRIBE(MODULE, usb_device_state_event); +APP_EVENT_SUBSCRIBE(MODULE, usb_state_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); APP_EVENT_SUBSCRIBE(MODULE, wake_up_event); diff --git a/src/usb_cdc_module.c b/src/usb_cdc_module.c index e34e8a3..2a1b385 100644 --- a/src/usb_cdc_module.c +++ b/src/usb_cdc_module.c @@ -18,10 +18,7 @@ #include "usb_cdc_rx_event.h" #include "usb_cdc_tx_event.h" -#include "usb_function_ready_event.h" -#include "usb_prepare_event.h" -#include "usb_device_module.h" -#include "usb_device_state_event.h" +#include "usb_state_event.h" LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); @@ -46,6 +43,13 @@ static bool usb_function_prepared; static bool dtr_ready; static bool rx_enabled; +static bool is_usb_owner_snapshot(const struct usb_state_event *event) +{ + return (event->op == USB_STATE_EVENT_OP_SNAPSHOT) && + (event->src_module_id == MODULE_ID(usb_device_module)) && + (event->sink_module_id == NULL); +} + static void reset_ring_buffers(void) { unsigned int key = irq_lock(); @@ -276,22 +280,21 @@ static void module_pause(void) running = false; } -static bool handle_usb_prepare_event(const struct usb_prepare_event *event) +static bool handle_usb_state_event(const struct usb_state_event *event) { - ARG_UNUSED(event); - - if (!running || usb_function_prepared) { + if (!is_usb_owner_snapshot(event)) { return false; } - usb_function_prepared = true; - submit_usb_function_ready_event(USB_FUNCTION_CDC_ACM); - return false; -} + if (running && !usb_function_prepared && + ((event->flags & USB_STATEF_PREPARE) != 0U)) { + usb_function_prepared = true; + submit_usb_state_set(MODULE_ID(MODULE), + MODULE_ID(usb_device_module), + USB_STATEF_CDC_READY); + } -static bool handle_usb_device_state_event(const struct usb_device_state_event *event) -{ - bool new_usb_active = (event->state == USB_DEVICE_STATE_ACTIVE); + bool new_usb_active = (event->flags & USB_STATEF_ACTIVE) != 0U; if (new_usb_active == usb_active) { return false; @@ -336,12 +339,8 @@ static bool handle_usb_cdc_tx_event(const struct usb_cdc_tx_event *event) static bool app_event_handler(const struct app_event_header *aeh) { - if (is_usb_device_state_event(aeh)) { - return handle_usb_device_state_event(cast_usb_device_state_event(aeh)); - } - - if (is_usb_prepare_event(aeh)) { - return handle_usb_prepare_event(cast_usb_prepare_event(aeh)); + if (is_usb_state_event(aeh)) { + return handle_usb_state_event(cast_usb_state_event(aeh)); } if (is_usb_cdc_tx_event(aeh)) { @@ -403,8 +402,7 @@ static bool app_event_handler(const struct app_event_header *aeh) APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); -APP_EVENT_SUBSCRIBE(MODULE, usb_prepare_event); -APP_EVENT_SUBSCRIBE(MODULE, usb_device_state_event); +APP_EVENT_SUBSCRIBE(MODULE, usb_state_event); APP_EVENT_SUBSCRIBE(MODULE, usb_cdc_tx_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); APP_EVENT_SUBSCRIBE(MODULE, wake_up_event); diff --git a/src/usb_device_module.c b/src/usb_device_module.c index f6c555f..4b6b778 100644 --- a/src/usb_device_module.c +++ b/src/usb_device_module.c @@ -13,10 +13,7 @@ #include -#include "usb_device_module.h" -#include "usb_device_state_event.h" -#include "usb_function_ready_event.h" -#include "usb_prepare_event.h" +#include "usb_state_event.h" LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); @@ -24,7 +21,7 @@ LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); #define USB_DEVICE_PID 0x52F0 #define USB_DEVICE_MANUFACTURER "Atguigu" #define USB_DEVICE_PRODUCT "WH Mini Keyboard" -#define USB_REQUIRED_FUNCTION_MASK (USB_FUNCTION_HID | USB_FUNCTION_CDC_ACM) +#define USB_REQUIRED_READY_MASK (USB_STATEF_HID_READY | USB_STATEF_CDC_READY) USBD_DEVICE_DEFINE(blinky_usbd, DEVICE_DT_GET(DT_NODELABEL(usbd)), USB_DEVICE_VID, USB_DEVICE_PID); @@ -42,20 +39,69 @@ static const char *const class_blocklist[] = { static bool initialized; static bool running; -static bool prepare_broadcasted; static bool usbd_initialized; static bool usb_enabled; -static uint8_t ready_function_mask; -static enum usb_device_state device_state = USB_DEVICE_STATE_DISCONNECTED; +static uint32_t usb_state_flags; -static void update_usb_device_state(enum usb_device_state state) +enum usb_runtime_state { + USB_RUNTIME_STATE_DISCONNECTED, + USB_RUNTIME_STATE_POWERED, + USB_RUNTIME_STATE_ACTIVE, + USB_RUNTIME_STATE_SUSPENDED, +}; + +static enum usb_runtime_state device_state = USB_RUNTIME_STATE_DISCONNECTED; + +static void broadcast_usb_state(void) +{ + submit_usb_state_snapshot(MODULE_ID(MODULE), usb_state_flags); +} + +static void set_usb_state_flags(uint32_t mask) +{ + usb_state_flags |= mask; +} + +static void clear_usb_state_flags(uint32_t mask) +{ + usb_state_flags &= ~mask; +} + +static void update_usb_runtime_state(enum usb_runtime_state state) { if (device_state == state) { return; } device_state = state; - submit_usb_device_state_event(state); + + switch (state) { + case USB_RUNTIME_STATE_DISCONNECTED: + clear_usb_state_flags(USB_STATEF_POWERED | + USB_STATEF_ACTIVE | + USB_STATEF_SUSPENDED); + break; + + case USB_RUNTIME_STATE_POWERED: + set_usb_state_flags(USB_STATEF_POWERED); + clear_usb_state_flags(USB_STATEF_ACTIVE | USB_STATEF_SUSPENDED); + break; + + case USB_RUNTIME_STATE_ACTIVE: + set_usb_state_flags(USB_STATEF_POWERED | USB_STATEF_ACTIVE); + clear_usb_state_flags(USB_STATEF_SUSPENDED); + break; + + case USB_RUNTIME_STATE_SUSPENDED: + set_usb_state_flags(USB_STATEF_POWERED | USB_STATEF_SUSPENDED); + clear_usb_state_flags(USB_STATEF_ACTIVE); + break; + + default: + break; + } + + broadcast_usb_state(); } static void update_power_manager_restriction(bool vbus_present) @@ -114,7 +160,7 @@ static void usbd_msg_cb(struct usbd_context *const usbd_ctx, LOG_ERR("usbd_enable failed (%d)", err); } else { usb_enabled = true; - update_usb_device_state(USB_DEVICE_STATE_POWERED); + update_usb_runtime_state(USB_RUNTIME_STATE_POWERED); } } break; @@ -130,26 +176,26 @@ static void usbd_msg_cb(struct usbd_context *const usbd_ctx, } usb_enabled = false; - update_usb_device_state(USB_DEVICE_STATE_DISCONNECTED); + update_usb_runtime_state(USB_RUNTIME_STATE_DISCONNECTED); break; case USBD_MSG_CONFIGURATION: if (msg->status) { - update_usb_device_state(USB_DEVICE_STATE_ACTIVE); + update_usb_runtime_state(USB_RUNTIME_STATE_ACTIVE); } else if (usb_enabled) { - update_usb_device_state(USB_DEVICE_STATE_POWERED); + update_usb_runtime_state(USB_RUNTIME_STATE_POWERED); } break; case USBD_MSG_SUSPEND: if (usb_enabled) { - update_usb_device_state(USB_DEVICE_STATE_SUSPENDED); + update_usb_runtime_state(USB_RUNTIME_STATE_SUSPENDED); } break; case USBD_MSG_RESUME: if (usb_enabled) { - update_usb_device_state(USB_DEVICE_STATE_ACTIVE); + update_usb_runtime_state(USB_RUNTIME_STATE_ACTIVE); } break; @@ -181,6 +227,7 @@ static int usb_stack_init(void) } usbd_initialized = true; + set_usb_state_flags(USB_STATEF_STACK_READY); if (!usbd_can_detect_vbus(&blinky_usbd)) { err = usbd_enable(&blinky_usbd); @@ -190,19 +237,33 @@ static int usb_stack_init(void) } usb_enabled = true; - update_usb_device_state(USB_DEVICE_STATE_POWERED); + update_usb_runtime_state(USB_RUNTIME_STATE_POWERED); } return 0; } +static int try_start_usb_stack(void) +{ + if (usbd_initialized) { + return 0; + } + + if ((usb_state_flags & USB_REQUIRED_READY_MASK) != USB_REQUIRED_READY_MASK) { + set_usb_state_flags(USB_STATEF_PREPARE); + return 0; + } + + clear_usb_state_flags(USB_STATEF_PREPARE); + return usb_stack_init(); +} + static int module_init(void) { - device_state = USB_DEVICE_STATE_DISCONNECTED; + device_state = USB_RUNTIME_STATE_DISCONNECTED; usb_enabled = false; - ready_function_mask = 0U; - prepare_broadcasted = false; usbd_initialized = false; + usb_state_flags = 0U; update_power_manager_restriction(false); return 0; @@ -215,16 +276,12 @@ static int module_start(void) } running = true; + set_usb_state_flags(USB_STATEF_STACK_RUNNING); - if (usbd_initialized || prepare_broadcasted) { - return 0; - } + int err = try_start_usb_stack(); - ready_function_mask = 0U; - prepare_broadcasted = true; - submit_usb_prepare_event(); - - return 0; + broadcast_usb_state(); + return err; } static void module_pause(void) @@ -234,6 +291,8 @@ static void module_pause(void) } running = false; + clear_usb_state_flags(USB_STATEF_STACK_RUNNING); + broadcast_usb_state(); } static bool handle_module_state_event(const struct module_state_event *event) @@ -266,28 +325,32 @@ static bool handle_module_state_event(const struct module_state_event *event) return false; } -static bool handle_usb_function_ready_event(const struct usb_function_ready_event *event) +static bool handle_usb_state_event(const struct usb_state_event *event) { - int err; - - if (!running || !prepare_broadcasted || usbd_initialized) { + if ((event->op == USB_STATE_EVENT_OP_SNAPSHOT) || + (event->sink_module_id != MODULE_ID(MODULE))) { return false; } - ready_function_mask |= event->function_mask; - - if ((ready_function_mask & USB_REQUIRED_FUNCTION_MASK) != - USB_REQUIRED_FUNCTION_MASK) { + if (event->op == USB_STATE_EVENT_OP_SET_BITS) { + usb_state_flags |= event->flags; + } else if (event->op == USB_STATE_EVENT_OP_CLEAR_BITS) { + usb_state_flags &= ~event->flags; + } else { return false; } - err = usb_stack_init(); + int err = running ? try_start_usb_stack() : 0; if (err) { module_set_state(MODULE_STATE_ERROR); return false; } - module_set_state(MODULE_STATE_READY); + broadcast_usb_state(); + + if (usbd_initialized) { + module_set_state(MODULE_STATE_READY); + } return false; } @@ -297,8 +360,8 @@ static bool app_event_handler(const struct app_event_header *aeh) return handle_module_state_event(cast_module_state_event(aeh)); } - if (is_usb_function_ready_event(aeh)) { - return handle_usb_function_ready_event(cast_usb_function_ready_event(aeh)); + if (is_usb_state_event(aeh)) { + return handle_usb_state_event(cast_usb_state_event(aeh)); } if (is_power_down_event(aeh)) { @@ -329,6 +392,6 @@ static bool app_event_handler(const struct app_event_header *aeh) APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); -APP_EVENT_SUBSCRIBE(MODULE, usb_function_ready_event); +APP_EVENT_SUBSCRIBE(MODULE, usb_state_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); APP_EVENT_SUBSCRIBE(MODULE, wake_up_event); diff --git a/src/usb_hid_module.c b/src/usb_hid_module.c index 67205de..1a3b6b4 100644 --- a/src/usb_hid_module.c +++ b/src/usb_hid_module.c @@ -21,10 +21,7 @@ #include "hid_tx_report_event.h" #include "keyboard_core.h" #include "set_protocol_event.h" -#include "usb_function_ready_event.h" -#include "usb_prepare_event.h" -#include "usb_device_module.h" -#include "usb_device_state_event.h" +#include "usb_state_event.h" LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); @@ -152,6 +149,13 @@ static void submit_usb_transport_state_event(void) keyboard_protocol_mode); } +static bool is_usb_owner_snapshot(const struct usb_state_event *event) +{ + return (event->op == USB_STATE_EVENT_OP_SNAPSHOT) && + (event->src_module_id == MODULE_ID(usb_device_module)) && + (event->sink_module_id == NULL); +} + static void keyboard_iface_ready(const struct device *dev, const bool ready) { struct usb_hid_interface_state *iface = iface_from_dev(dev); @@ -418,31 +422,29 @@ static void module_pause(void) submit_usb_transport_state_event(); } -static bool handle_usb_prepare_event(const struct usb_prepare_event *event) +static bool handle_usb_state_event(const struct usb_state_event *event) { - int err; - - ARG_UNUSED(event); - - if (!running || usb_function_prepared) { + if (!is_usb_owner_snapshot(event)) { return false; } - err = usb_hid_register_devices(); - if (err) { - LOG_ERR("hid_device_register failed (%d)", err); - module_set_state(MODULE_STATE_ERROR); - return false; + if (running && !usb_function_prepared && + ((event->flags & USB_STATEF_PREPARE) != 0U)) { + int err = usb_hid_register_devices(); + + if (err) { + LOG_ERR("hid_device_register failed (%d)", err); + module_set_state(MODULE_STATE_ERROR); + return false; + } + + usb_function_prepared = true; + submit_usb_state_set(MODULE_ID(MODULE), + MODULE_ID(usb_device_module), + USB_STATEF_HID_READY); } - usb_function_prepared = true; - submit_usb_function_ready_event(USB_FUNCTION_HID); - return false; -} - -static bool handle_usb_device_state_event(const struct usb_device_state_event *event) -{ - bool new_usb_active = (event->state == USB_DEVICE_STATE_ACTIVE); + bool new_usb_active = (event->flags & USB_STATEF_ACTIVE) != 0U; if (new_usb_active == usb_active) { return false; @@ -538,12 +540,8 @@ static bool app_event_handler(const struct app_event_header *aeh) return handle_hid_tx_report_event(cast_hid_tx_report_event(aeh)); } - if (is_usb_device_state_event(aeh)) { - return handle_usb_device_state_event(cast_usb_device_state_event(aeh)); - } - - if (is_usb_prepare_event(aeh)) { - return handle_usb_prepare_event(cast_usb_prepare_event(aeh)); + if (is_usb_state_event(aeh)) { + return handle_usb_state_event(cast_usb_state_event(aeh)); } if (is_module_state_event(aeh)) { @@ -602,7 +600,6 @@ static bool app_event_handler(const struct app_event_header *aeh) APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); APP_EVENT_SUBSCRIBE(MODULE, hid_tx_report_event); -APP_EVENT_SUBSCRIBE(MODULE, usb_prepare_event); -APP_EVENT_SUBSCRIBE(MODULE, usb_device_state_event); +APP_EVENT_SUBSCRIBE(MODULE, usb_state_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);