Handle persistent reboot better in CDC

This commit is contained in:
me-no-dev
2020-07-02 13:07:34 +03:00
parent 7f54a357a4
commit 29e3d0e75f
10 changed files with 228 additions and 22 deletions

View File

@ -381,7 +381,7 @@ static bool tinyusb_load_enabled_interfaces(){
}; };
memcpy(tinyusb_config_descriptor, descriptor, TUD_CONFIG_DESC_LEN); memcpy(tinyusb_config_descriptor, descriptor, TUD_CONFIG_DESC_LEN);
if ((tinyusb_loaded_interfaces_mask == (BIT(USB_INTERFACE_CDC) | BIT(USB_INTERFACE_DFU))) || (tinyusb_loaded_interfaces_mask == BIT(USB_INTERFACE_CDC))) { if ((tinyusb_loaded_interfaces_mask == (BIT(USB_INTERFACE_CDC) | BIT(USB_INTERFACE_DFU))) || (tinyusb_loaded_interfaces_mask == BIT(USB_INTERFACE_CDC))) {
tinyusb_persist_set_enable(true); usb_persist_set_enable(true);
log_d("USB Persist enabled"); log_d("USB Persist enabled");
} }
log_d("Load Done: if_num: %u, descr_len: %u, if_mask: 0x%x", tinyusb_loaded_interfaces_num, tinyusb_config_descriptor_len, tinyusb_loaded_interfaces_mask); log_d("Load Done: if_num: %u, descr_len: %u, if_mask: 0x%x", tinyusb_loaded_interfaces_num, tinyusb_config_descriptor_len, tinyusb_loaded_interfaces_mask);

View File

@ -42,8 +42,7 @@ static uint16_t load_dfu_descriptor(uint8_t * dst, uint8_t * itf)
// Invoked on DFU_DETACH request to reboot to the bootloader // Invoked on DFU_DETACH request to reboot to the bootloader
void tud_dfu_rt_reboot_to_dfu(void) void tud_dfu_rt_reboot_to_dfu(void)
{ {
tinyusb_persist_set_mode(REBOOT_BOOTLOADER_DFU); usb_persist_restart(RESTART_BOOTLOADER_DFU);
esp_restart();
} }
#endif /* CFG_TUD_DFU_RT */ #endif /* CFG_TUD_DFU_RT */

View File

@ -70,7 +70,7 @@ static void usb_unplugged_cb(void* arg, esp_event_base_t event_base, int32_t eve
((USBCDC*)arg)->_onUnplugged(); ((USBCDC*)arg)->_onUnplugged();
} }
USBCDC::USBCDC(uint8_t itfn) : itf(itfn), bit_rate(0), stop_bits(0), parity(0), data_bits(0), dtr(false), rts(false), connected(false), reboot_enable(true), rx_queue(NULL) { USBCDC::USBCDC(uint8_t itfn) : itf(itfn), bit_rate(0), stop_bits(0), parity(0), data_bits(0), dtr(false), rts(false), connected(usb_persist_this_boot()), reboot_enable(true), rx_queue(NULL) {
tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor); tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
if(itf < MAX_USB_CDC_DEVICES){ if(itf < MAX_USB_CDC_DEVICES){
devices[itf] = this; devices[itf] = this;
@ -94,6 +94,15 @@ void USBCDC::begin(size_t rx_queue_len)
if(!rx_queue){ if(!rx_queue){
return; return;
} }
if(connected){
arduino_usb_cdc_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_CONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
arduino_usb_cdc_event_data_t l = {0};
l.line_state.dtr = true;
l.line_state.rts = true;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_LINE_STATE_EVENT, &l, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
} }
void USBCDC::end() void USBCDC::end()
@ -137,8 +146,7 @@ void USBCDC::_onLineState(bool _dtr, bool _rts){
} }
} else if(!dtr && !rts){ } else if(!dtr && !rts){
if(lineState == CDC_LINE_3){ if(lineState == CDC_LINE_3){
tinyusb_persist_set_mode(REBOOT_BOOTLOADER); usb_persist_restart(RESTART_BOOTLOADER);
esp_restart();
} else { } else {
lineState = CDC_LINE_IDLE; lineState = CDC_LINE_IDLE;
} }
@ -195,13 +203,6 @@ void USBCDC::_onRX(){
} }
void USBCDC::enableReboot(bool enable){ void USBCDC::enableReboot(bool enable){
if(enable != reboot_enable){
if(enable){
tinyusb_persist_set_mode(REBOOT_PERSIST);
} else {
tinyusb_persist_set_mode(REBOOT_NO_PERSIST);
}
}
reboot_enable = enable; reboot_enable = enable;
} }
bool USBCDC::rebootEnabled(void){ bool USBCDC::rebootEnabled(void){

View File

@ -24,29 +24,34 @@ extern "C" {
* USB Persistence API * USB Persistence API
* */ * */
typedef enum { typedef enum {
REBOOT_NO_PERSIST, RESTART_NO_PERSIST,
REBOOT_PERSIST, RESTART_PERSIST,
REBOOT_BOOTLOADER, RESTART_BOOTLOADER,
REBOOT_BOOTLOADER_DFU, RESTART_BOOTLOADER_DFU,
REBOOT_TYPE_MAX RESTART_TYPE_MAX
} reboot_type_t; } restart_type_t;
/* /*
* Init Persistence reboot system * Init Persistence reboot system
* */ * */
void tinyusb_persist_init(void); void usb_persist_init(void);
/* /*
* Enable Persistence reboot * Enable Persistence reboot
* *
* Note: Persistence should be enabled when ONLY CDC and DFU are being used * Note: Persistence should be enabled when ONLY CDC and DFU are being used
* */ * */
void tinyusb_persist_set_enable(bool enable); void usb_persist_set_enable(bool enable);
/* /*
* Set Reboot mode. Call before esp_reboot(); * Set Reboot mode. Call before esp_reboot();
* */ * */
void tinyusb_persist_set_mode(reboot_type_t mode); void usb_persist_restart(restart_type_t mode);
/*
* Check if last boot was persistent
* */
bool usb_persist_this_boot(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -113,6 +113,9 @@
#elif CFG_TUSB_MCU == OPT_MCU_ESP32S2 #elif CFG_TUSB_MCU == OPT_MCU_ESP32S2
// no header needed // no header needed
#elif CFG_TUSB_MCU == OPT_MCU_DA1469X
#include "DA1469xAB.h"
#else #else
#error "Missing MCU header" #error "Missing MCU header"
#endif #endif

View File

@ -0,0 +1,34 @@
/**
* This file was generated by Apache newt version: 1.9.0-dev
*/
#ifndef H_MYNEWT_SYSCFG_
#define H_MYNEWT_SYSCFG_
/**
* This macro exists to ensure code includes this header when needed. If code
* checks the existence of a setting directly via ifdef without including this
* header, the setting macro will silently evaluate to 0. In contrast, an
* attempt to use these macros without including this header will result in a
* compiler error.
*/
#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name
#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val
#ifndef MYNEWT_VAL_RAM_RESIDENT
#define MYNEWT_VAL_RAM_RESIDENT (0)
#endif
#ifndef MYNEWT_VAL_MCU_GPIO_MAX_IRQ
#define MYNEWT_VAL_MCU_GPIO_MAX_IRQ (4)
#endif
#ifndef MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM
#define MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM (-1)
#endif
#ifndef MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US
#define MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US (2000)
#endif
#endif

View File

@ -0,0 +1,34 @@
/**
* This file was generated by Apache newt version: 1.9.0-dev
*/
#ifndef H_MYNEWT_SYSCFG_
#define H_MYNEWT_SYSCFG_
/**
* This macro exists to ensure code includes this header when needed. If code
* checks the existence of a setting directly via ifdef without including this
* header, the setting macro will silently evaluate to 0. In contrast, an
* attempt to use these macros without including this header will result in a
* compiler error.
*/
#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name
#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val
#ifndef MYNEWT_VAL_RAM_RESIDENT
#define MYNEWT_VAL_RAM_RESIDENT (0)
#endif
#ifndef MYNEWT_VAL_MCU_GPIO_MAX_IRQ
#define MYNEWT_VAL_MCU_GPIO_MAX_IRQ (4)
#endif
#ifndef MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM
#define MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM (-1)
#endif
#ifndef MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US
#define MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US (2000)
#endif
#endif

View File

@ -0,0 +1,126 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
/**
* @brief LED Strip Type
*
*/
typedef struct led_strip_s led_strip_t;
/**
* @brief LED Strip Device Type
*
*/
typedef void *led_strip_dev_t;
/**
* @brief Declare of LED Strip Type
*
*/
struct led_strip_s {
/**
* @brief Set RGB for a specific pixel
*
* @param strip: LED strip
* @param index: index of pixel to set
* @param red: red part of color
* @param green: green part of color
* @param blue: blue part of color
*
* @return
* - ESP_OK: Set RGB for a specific pixel successfully
* - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters
* - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred
*/
esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue);
/**
* @brief Refresh memory colors to LEDs
*
* @param strip: LED strip
* @param timeout_ms: timeout value for refreshing task
*
* @return
* - ESP_OK: Refresh successfully
* - ESP_ERR_TIMEOUT: Refresh failed because of timeout
* - ESP_FAIL: Refresh failed because some other error occurred
*
* @note:
* After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip.
*/
esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms);
/**
* @brief Clear LED strip (turn off all LEDs)
*
* @param strip: LED strip
* @param timeout_ms: timeout value for clearing task
*
* @return
* - ESP_OK: Clear LEDs successfully
* - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout
* - ESP_FAIL: Clear LEDs failed because some other error occurred
*/
esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms);
/**
* @brief Free LED strip resources
*
* @param strip: LED strip
*
* @return
* - ESP_OK: Free resources successfully
* - ESP_FAIL: Free resources failed because error occurred
*/
esp_err_t (*del)(led_strip_t *strip);
};
/**
* @brief LED Strip Configuration Type
*
*/
typedef struct {
uint32_t max_leds; /*!< Maximum LEDs in a single strip */
led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */
} led_strip_config_t;
/**
* @brief Default configuration for LED strip
*
*/
#define LED_STRIP_DEFAULT_CONFIG(number, dev_hdl) \
{ \
.max_leds = number, \
.dev = dev_hdl, \
}
/**
* @brief Install a new ws2812 driver (based on RMT peripheral)
*
* @param config: LED strip configuration
* @return
* LED strip instance or NULL
*/
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config);
#ifdef __cplusplus
}
#endif

View File

@ -58,6 +58,7 @@
#define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21 #define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21
#define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51 #define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51
#define OPT_MCU_SAMG 202 ///< MicroChip SAMDG series #define OPT_MCU_SAMG 202 ///< MicroChip SAMDG series
#define OPT_MCU_SAME5X 203 ///< MicroChip SAM E5x
// STM32 // STM32
#define OPT_MCU_STM32F0 300 ///< ST STM32F0 #define OPT_MCU_STM32F0 300 ///< ST STM32F0
@ -92,6 +93,9 @@
// Espressif // Espressif
#define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2
// Dialog
#define OPT_MCU_DA1469X 1000 ///< Dialog Semiconductor DA1469x
/** @} */ /** @} */
/** \defgroup group_supported_os Supported RTOS /** \defgroup group_supported_os Supported RTOS

Binary file not shown.