diff --git a/sys/include/usb_board_reset.h b/sys/include/usb_board_reset.h new file mode 100644 index 0000000000..8aa6c655de --- /dev/null +++ b/sys/include/usb_board_reset.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup sys_usb_board_reset Board reset via USB CDC ACM + * @ingroup sys + * @brief Trigger a board reset via USB CDC ACM + * + * @{ + * + * @file + * @author Alexandre Abadie + */ + +#ifndef USB_BOARD_RESET_H +#define USB_BOARD_RESET_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "usb/usbus/cdc/acm.h" + +/** + * @brief USB coding callback used to trigger the board reset + * + * @param[in] cdcacm Pointer to the cdcacm device + * @param[in] baud Baudrate used by the client. Only 1200 baud is taken into account + * @param[in] bits Number of bit mode used by the client + * @param[in] parity Parity mode used by the client + * @param[in] stop Stop bit mode used by the client + * + * @return Always return 0 + */ +int usb_board_reset_coding_cb(usbus_cdcacm_device_t *cdcacm, + uint32_t baud, uint8_t bits, + uint8_t parity, uint8_t stop); + +/** + * @brief Trigger a simple reset, back to the application + */ +void usb_board_reset_in_application(void); + +#ifdef __cplusplus +} +#endif + +#endif /* USB_BOARD_RESET_H */ +/** @} */ diff --git a/sys/usb_board_reset/Makefile b/sys/usb_board_reset/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/sys/usb_board_reset/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/usb_board_reset/usb_board_reset.c b/sys/usb_board_reset/usb_board_reset.c new file mode 100644 index 0000000000..04aa426d3d --- /dev/null +++ b/sys/usb_board_reset/usb_board_reset.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys + * @{ + * @file + * + * @author Alexandre Abadie + * @} + */ + +#define USB_H_USER_IS_RIOT_INTERNAL + +#include "log.h" + +#include "usb/usbus/cdc/acm.h" +#include "usb_board_reset.h" + +#include "periph/pm.h" + +#ifndef RESET_IN_BOOTLOADER_TRIGGER_BAUDRATE +#define RESET_IN_BOOTLOADER_TRIGGER_BAUDRATE (1200U) +#endif + +#ifndef RESET_IN_APPLICATION_TRIGGER_BAUDRATE +#define RESET_IN_APPLICATION_TRIGGER_BAUDRATE (600U) +#endif + +void usb_board_reset_in_bootloader(void); + +int usb_board_reset_coding_cb(usbus_cdcacm_device_t *cdcacm, + uint32_t baud, uint8_t bits, + uint8_t parity, uint8_t stop) +{ + (void)cdcacm; + (void)bits; + (void)parity; + (void)stop; + switch (baud) { + case RESET_IN_BOOTLOADER_TRIGGER_BAUDRATE: + LOG_DEBUG("[cdc-acm-stdio] reset in bootloader"); + usb_board_reset_in_bootloader(); + break; + case RESET_IN_APPLICATION_TRIGGER_BAUDRATE: + LOG_DEBUG("[cdc-acm-stdio] reset in application"); + usb_board_reset_in_application(); + break; + default: + (void)baud; + break; + } + + return 0; +} + +void usb_board_reset_in_application(void) +{ + pm_reboot(); + while (1) {} +}