Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

usbus: allow to forward EP0 transfer events to other handlers #19493

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions bootloaders/riotboot_dfu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ APPLICATION = riotboot_dfu
# Add RIOTBOOT USB DFU integration
USEMODULE += riotboot_usb_dfu

# Use xtimer for scheduled reboot
USEMODULE += ztimer
USEMODULE += ztimer_init

# USB device vendor and product ID
# pid.codes test VID/PID, not globally unique

Expand Down
9 changes: 4 additions & 5 deletions bootloaders/riotboot_dfu/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@
#include "panic.h"
#include "riotboot/slot.h"
#include "riotboot/usb_dfu.h"
#include "ztimer.h"

#include "riotboot/bootloader_selection.h"
#include "ztimer.h"

#ifdef BTN_BOOTLOADER_PIN
#include "periph/gpio.h"
Expand Down Expand Up @@ -74,9 +73,9 @@ void kernel_init(void)
}
}

/* Init ztimer before starting DFU mode */
ztimer_init();

if (IS_USED(MODULE_ZTIMER)) {
ztimer_init();
}
benpicco marked this conversation as resolved.
Show resolved Hide resolved
/* Flash the unused slot if magic word is set */
riotboot_usb_dfu_init(0);

Expand Down
1 change: 0 additions & 1 deletion sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,6 @@ endif
ifneq (,$(filter riotboot_usb_dfu, $(USEMODULE)))
USEMODULE += usbus_dfu
USEMODULE += riotboot_flashwrite
USEMODULE += ztimer_sec
FEATURES_REQUIRED += no_idle_thread
FEATURES_REQUIRED += periph_pm
endif
Expand Down
1 change: 1 addition & 0 deletions sys/include/usb/usbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ extern "C" {
*/
#define USBUS_HANDLER_FLAG_TR_FAIL (0x0010)
#define USBUS_HANDLER_FLAG_TR_STALL (0x0020) /**< Report transfer stall complete */
#define USBUS_HANDLER_FLAG_TR_EP0_FWD (0x0100) /**< Forward transfer complete */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So EP0 means transfer complete?

/** @} */

/**
Expand Down
35 changes: 12 additions & 23 deletions sys/usb/usbus/dfu/dfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
#include "usb/usbus/dfu.h"
#include "riotboot/magic.h"
#include "riotboot/usb_dfu.h"
#ifdef MODULE_RIOTBOOT_USB_DFU
#include "ztimer.h"
#endif
#include "periph/pm.h"

#include "riotboot/slot.h"
Expand All @@ -46,12 +43,6 @@ static void _transfer_handler(usbus_t *usbus, usbus_handler_t *handler,
usbdev_ep_t *ep, usbus_event_transfer_t event);
static void _init(usbus_t *usbus, usbus_handler_t *handler);

#ifdef MODULE_RIOTBOOT_USB_DFU
static void _reboot(void *arg);
static ztimer_t scheduled_reboot = { .callback=_reboot };
#define REBOOT_DELAY 2
#endif

#define DEFAULT_XFER_SIZE 64

static size_t _gen_dfu_descriptor(usbus_t *usbus, void *arg)
Expand Down Expand Up @@ -88,14 +79,6 @@ static const usbus_descr_gen_funcs_t _dfu_descriptor = {
.len_type = USBUS_DESCR_LEN_FIXED,
};

#ifdef MODULE_RIOTBOOT_USB_DFU
static void _reboot(void *arg)
{
(void)arg;
pm_reboot();
}
#endif

void usbus_dfu_init(usbus_t *usbus, usbus_dfu_device_t *handler, unsigned mode)
{
DEBUG("DFU: initialization\n");
Expand Down Expand Up @@ -228,13 +211,13 @@ static int _dfu_class_control_req(usbus_t *usbus, usbus_dfu_device_t *dfu, usb_s

if (dfu->dfu_state == USB_DFU_STATE_DFU_DL_SYNC) {
dfu->dfu_state = USB_DFU_STATE_DFU_DL_IDLE;
DEBUG("GET STATUS GO TO IDLE\n");
}
else if (dfu->dfu_state == USB_DFU_STATE_DFU_MANIFEST_SYNC) {
/* Scheduled reboot, so we can answer back dfu-util before rebooting */
dfu->dfu_state = USB_DFU_STATE_DFU_DL_IDLE;
#ifdef MODULE_RIOTBOOT_USB_DFU
ztimer_set(ZTIMER_SEC, &scheduled_reboot, 1);
/* Set specific flag to forward TRANSFER_COMPLETE event to this interface */
usbus_handler_set_flag(&dfu->handler_ctrl, USBUS_HANDLER_FLAG_TR_EP0_FWD);
#endif
}
memset(&buf, 0, sizeof(buf));
Expand All @@ -243,7 +226,6 @@ static int _dfu_class_control_req(usbus_t *usbus, usbus_dfu_device_t *dfu, usb_s
buf.state = dfu->dfu_state;
/* Send answer to host */
usbus_control_slicer_put_bytes(usbus, (uint8_t*)&buf, sizeof(buf));
DEBUG("send answer\n");
break;
}
case DFU_CLR_STATUS:
Expand Down Expand Up @@ -294,10 +276,17 @@ static int _control_handler(usbus_t *usbus, usbus_handler_t *handler,
static void _transfer_handler(usbus_t *usbus, usbus_handler_t *handler,
usbdev_ep_t *ep, usbus_event_transfer_t event)
{
(void)event;
(void)usbus;
(void)handler;
(void)ep;
usbus_control_handler_t *ep0_handler = (usbus_control_handler_t *)usbus->control;

/* Ensure we did transmit the status packet before rebooting to application */
if (ep->dir == USB_EP_DIR_OUT && event == USBUS_EVENT_TRANSFER_COMPLETE) {

/* Wait to receive OUTACK event on EP0 before rebooting */
if (ep0_handler->control_request_state == USBUS_CONTROL_REQUEST_STATE_READY) {
pm_reboot();
}
}
}

static void _event_handler(usbus_t *usbus, usbus_handler_t *handler,
Expand Down
7 changes: 7 additions & 0 deletions sys/usb/usbus/usbus_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,13 @@ static void _handler_ep0_transfer(usbus_t *usbus, usbus_handler_t *handler,
switch (event) {
case USBUS_EVENT_TRANSFER_COMPLETE:
_handle_tr_complete(usbus, ep0_handler, ep);
/* Forward to every handler, EP0 transfer event, except the first
* handler as this is the current handler used for this event */
for (usbus_handler_t *hdl = handler->next; hdl; hdl = hdl->next) {
if(usbus_handler_isset_flag(hdl, USBUS_HANDLER_FLAG_TR_EP0_FWD)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(usbus_handler_isset_flag(hdl, USBUS_HANDLER_FLAG_TR_EP0_FWD)) {
if (usbus_handler_isset_flag(hdl, USBUS_HANDLER_FLAG_TR_EP0_FWD)) {

hdl->driver->transfer_handler(usbus, hdl, ep, USBUS_EVENT_TRANSFER_COMPLETE);
}
}
break;
default:
break;
Expand Down