diff --git a/CMakeLists.txt b/CMakeLists.txt index fae7a5a3..00e9d3e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,12 +8,9 @@ set(CORE_SRCS cores/esp32/esp32-hal-misc.c cores/esp32/esp32-hal-psram.c cores/esp32/esp32-hal-spi.c - cores/esp32/esp32-hal-tinyusb.c cores/esp32/esp32-hal-rmt.c cores/esp32/FunctionalInterrupt.cpp cores/esp32/stdlib_noniso.c - cores/esp32/USB.cpp - cores/esp32/USBCDC.cpp cores/esp32/wiring_pulse.c cores/esp32/wiring_shift.c cores/esp32/WMath.cpp @@ -34,7 +31,7 @@ set(includedirs set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS}) set(requires spi_flash mbedtls wifi_provisioning driver) -set(priv_requires nvs_flash bootloader_support tinyusb espcpputils fmt) +set(priv_requires nvs_flash bootloader_support espcpputils fmt) idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires}) diff --git a/cores/esp32/USB.cpp b/cores/esp32/USB.cpp deleted file mode 100644 index d2b67f6b..00000000 --- a/cores/esp32/USB.cpp +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright 2015-2020 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. -#include "esp32-hal.h" -#include "esp32-hal-tinyusb.h" -#include "USB.h" -#if CONFIG_USB_ENABLED - -#ifndef USB_VID -#define USB_VID USB_ESPRESSIF_VID -#endif -#ifndef USB_PID -#define USB_PID 0x0002 -#endif -#ifndef USB_MANUFACTURER -#define USB_MANUFACTURER "Espressif Systems" -#endif -#ifndef USB_PRODUCT -#define USB_PRODUCT ARDUINO_BOARD -#endif -#ifndef USB_SERIAL -#define USB_SERIAL "0" -#endif - -extern "C" { -#include "tinyusb.h" -} - -#if CFG_TUD_DFU_RT -static uint16_t load_dfu_descriptor(uint8_t * dst, uint8_t * itf) -{ -#define DFU_ATTR_CAN_DOWNLOAD 1 -#define DFU_ATTR_CAN_UPLOAD 2 -#define DFU_ATTR_MANIFESTATION_TOLERANT 4 -#define DFU_ATTR_WILL_DETACH 8 -#define DFU_ATTRS (DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_CAN_UPLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) - - uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB DFU_RT"); - uint8_t descriptor[TUD_DFU_RT_DESC_LEN] = { - // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_RT_DESCRIPTOR(*itf, str_index, DFU_ATTRS, 700, 64) - }; - *itf+=1; - memcpy(dst, descriptor, TUD_DFU_RT_DESC_LEN); - return TUD_DFU_RT_DESC_LEN; -} -// Invoked on DFU_DETACH request to reboot to the bootloader -void tud_dfu_rt_reboot_to_dfu(void) -{ - usb_persist_restart(RESTART_BOOTLOADER_DFU); -} -#endif /* CFG_TUD_DFU_RT */ - -ESP_EVENT_DEFINE_BASE(ARDUINO_USB_EVENTS); - -static esp_event_loop_handle_t arduino_usb_event_loop_handle = NULL; - -esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait){ - if(arduino_usb_event_loop_handle == NULL){ - return ESP_FAIL; - } - return esp_event_post_to(arduino_usb_event_loop_handle, event_base, event_id, event_data, event_data_size, ticks_to_wait); -} -esp_err_t arduino_usb_event_handler_register_with(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler, void *event_handler_arg){ - if(arduino_usb_event_loop_handle == NULL){ - return ESP_FAIL; - } - return esp_event_handler_register_with(arduino_usb_event_loop_handle, event_base, event_id, event_handler, event_handler_arg); -} - -static bool tinyusb_device_mounted = false; -static bool tinyusb_device_suspended = false; - -// Invoked when device is mounted (configured) -void tud_mount_cb(void){ - tinyusb_device_mounted = true; - arduino_usb_event_data_t p = {0}; - arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STARTED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); -} - -// Invoked when device is unmounted -void tud_umount_cb(void){ - tinyusb_device_mounted = false; - arduino_usb_event_data_t p = {0}; - arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); -} - -// Invoked when usb bus is suspended -// Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en){ - tinyusb_device_suspended = true; - arduino_usb_event_data_t p = {0}; - p.suspend.remote_wakeup_en = remote_wakeup_en; - arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_SUSPEND_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); -} - -// Invoked when usb bus is resumed -void tud_resume_cb(void){ - tinyusb_device_suspended = false; - arduino_usb_event_data_t p = {0}; - arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_RESUME_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); -} - -ESPUSB::ESPUSB(size_t task_stack_size, uint8_t event_task_priority) -:vid(USB_VID) -,pid(USB_PID) -,product_name(USB_PRODUCT) -,manufacturer_name(USB_MANUFACTURER) -,serial_number(USB_SERIAL) -,fw_version(0x0100) -,usb_version(0x0200)// at least 2.1 or 3.x for BOS & webUSB -,usb_class(TUSB_CLASS_MISC) -,usb_subclass(MISC_SUBCLASS_COMMON) -,usb_protocol(MISC_PROTOCOL_IAD) -,usb_attributes(TUSB_DESC_CONFIG_ATT_SELF_POWERED) -,usb_power_ma(500) -,webusb_enabled(false) -,webusb_url("espressif.github.io/arduino-esp32/webusb.html") -,_started(false) -,_task_stack_size(task_stack_size) -,_event_task_priority(event_task_priority) -{ - if (!arduino_usb_event_loop_handle) { - esp_event_loop_args_t event_task_args = { - .queue_size = 5, - .task_name = "arduino_usb_events", - .task_priority = _event_task_priority, - .task_stack_size = _task_stack_size, - .task_core_id = tskNO_AFFINITY - }; - if (esp_event_loop_create(&event_task_args, &arduino_usb_event_loop_handle) != ESP_OK) { - log_e("esp_event_loop_create failed"); - } - } -} - -ESPUSB::~ESPUSB(){ - if (arduino_usb_event_loop_handle) { - esp_event_loop_delete(arduino_usb_event_loop_handle); - arduino_usb_event_loop_handle = NULL; - } -} - -bool ESPUSB::begin(){ - if(!_started){ - tinyusb_device_config_t tinyusb_device_config = { - .vid = vid, - .pid = pid, - .product_name = product_name.c_str(), - .manufacturer_name = manufacturer_name.c_str(), - .serial_number = serial_number.c_str(), - .fw_version = fw_version, - .usb_version = usb_version, - .usb_class = usb_class, - .usb_subclass = usb_subclass, - .usb_protocol = usb_protocol, - .usb_attributes = usb_attributes, - .usb_power_ma = usb_power_ma, - .webusb_enabled = webusb_enabled, - .webusb_url = webusb_url.c_str() - }; - _started = tinyusb_init(&tinyusb_device_config) == ESP_OK; - } - return _started; -} - -void ESPUSB::onEvent(esp_event_handler_t callback){ - onEvent(ARDUINO_USB_ANY_EVENT, callback); -} -void ESPUSB::onEvent(arduino_usb_event_t event, esp_event_handler_t callback){ - arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, event, callback, this); -} - -ESPUSB::operator bool() const -{ - return _started && tinyusb_device_mounted; -} - -bool ESPUSB::enableDFU(){ -#if CFG_TUD_DFU_RT - return tinyusb_enable_interface(USB_INTERFACE_DFU, TUD_DFU_RT_DESC_LEN, load_dfu_descriptor) == ESP_OK; -#endif /* CFG_TUD_DFU_RT */ - return false; -} - -bool ESPUSB::VID(uint16_t v){ - if(!_started){ - vid = v; - } - return !_started; -} -uint16_t ESPUSB::VID(void){ - return vid; -} - -bool ESPUSB::PID(uint16_t p){ - if(!_started){ - pid = p; - } - return !_started; -} -uint16_t ESPUSB::PID(void){ - return pid; -} - -bool ESPUSB::firmwareVersion(uint16_t version){ - if(!_started){ - fw_version = version; - } - return !_started; -} -uint16_t ESPUSB::firmwareVersion(void){ - return fw_version; -} - -bool ESPUSB::usbVersion(uint16_t version){ - if(!_started){ - usb_version = version; - } - return !_started; -} -uint16_t ESPUSB::usbVersion(void){ - return usb_version; -} - -bool ESPUSB::usbPower(uint16_t mA){ - if(!_started){ - usb_power_ma = mA; - } - return !_started; -} -uint16_t ESPUSB::usbPower(void){ - return usb_power_ma; -} - -bool ESPUSB::usbClass(uint8_t _class){ - if(!_started){ - usb_class = _class; - } - return !_started; -} -uint8_t ESPUSB::usbClass(void){ - return usb_class; -} - -bool ESPUSB::usbSubClass(uint8_t subClass){ - if(!_started){ - usb_subclass = subClass; - } - return !_started; -} -uint8_t ESPUSB::usbSubClass(void){ - return usb_subclass; -} - -bool ESPUSB::usbProtocol(uint8_t protocol){ - if(!_started){ - usb_protocol = protocol; - } - return !_started; -} -uint8_t ESPUSB::usbProtocol(void){ - return usb_protocol; -} - -bool ESPUSB::usbAttributes(uint8_t attr){ - if(!_started){ - usb_attributes = attr; - } - return !_started; -} -uint8_t ESPUSB::usbAttributes(void){ - return usb_attributes; -} - -bool ESPUSB::webUSB(bool enabled){ - if(!_started){ - webusb_enabled = enabled; - } - return !_started; -} -bool ESPUSB::webUSB(void){ - return webusb_enabled; -} - -bool ESPUSB::productName(const char * name){ - if(!_started){ - product_name = name; - } - return !_started; -} -const char * ESPUSB::productName(void){ - return product_name.c_str(); -} - -bool ESPUSB::manufacturerName(const char * name){ - if(!_started){ - manufacturer_name = name; - } - return !_started; -} -const char * ESPUSB::manufacturerName(void){ - return manufacturer_name.c_str(); -} - -bool ESPUSB::serialNumber(const char * name){ - if(!_started){ - serial_number = name; - } - return !_started; -} -const char * ESPUSB::serialNumber(void){ - return serial_number.c_str(); -} - -bool ESPUSB::webUSBURL(const char * name){ - if(!_started){ - webusb_url = name; - } - return !_started; -} -const char * ESPUSB::webUSBURL(void){ - return webusb_url.c_str(); -} - -ESPUSB USB; - -#endif /* CONFIG_USB_ENABLED */ diff --git a/cores/esp32/USB.h b/cores/esp32/USB.h deleted file mode 100644 index d2fac1b8..00000000 --- a/cores/esp32/USB.h +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2015-2020 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 - -#include "sdkconfig.h" -#if CONFIG_USB_ENABLED - -#include "Arduino.h" -#include "USBCDC.h" - -#include "esp_event.h" - -ESP_EVENT_DECLARE_BASE(ARDUINO_USB_EVENTS); - -typedef enum { - ARDUINO_USB_ANY_EVENT = ESP_EVENT_ANY_ID, - ARDUINO_USB_STARTED_EVENT = 0, - ARDUINO_USB_STOPPED_EVENT, - ARDUINO_USB_SUSPEND_EVENT, - ARDUINO_USB_RESUME_EVENT, - ARDUINO_USB_MAX_EVENT, -} arduino_usb_event_t; - -typedef union { - struct { - bool remote_wakeup_en; - } suspend; -} arduino_usb_event_data_t; - -class ESPUSB { - public: - ESPUSB(size_t event_task_stack_size=2048, uint8_t event_task_priority=5); - ~ESPUSB(); - - void onEvent(esp_event_handler_t callback); - void onEvent(arduino_usb_event_t event, esp_event_handler_t callback); - - bool VID(uint16_t v); - uint16_t VID(void); - - bool PID(uint16_t p); - uint16_t PID(void); - - bool firmwareVersion(uint16_t version); - uint16_t firmwareVersion(void); - - bool usbVersion(uint16_t version); - uint16_t usbVersion(void); - - bool usbPower(uint16_t mA); - uint16_t usbPower(void); - - bool usbClass(uint8_t _class); - uint8_t usbClass(void); - - bool usbSubClass(uint8_t subClass); - uint8_t usbSubClass(void); - - bool usbProtocol(uint8_t protocol); - uint8_t usbProtocol(void); - - bool usbAttributes(uint8_t attr); - uint8_t usbAttributes(void); - - bool webUSB(bool enabled); - bool webUSB(void); - - bool productName(const char * name); - const char * productName(void); - - bool manufacturerName(const char * name); - const char * manufacturerName(void); - - bool serialNumber(const char * name); - const char * serialNumber(void); - - bool webUSBURL(const char * name); - const char * webUSBURL(void); - - bool enableDFU(); - bool begin(); - operator bool() const; - - private: - uint16_t vid; - uint16_t pid; - String product_name; - String manufacturer_name; - String serial_number; - uint16_t fw_version; - uint16_t usb_version; - uint8_t usb_class; - uint8_t usb_subclass; - uint8_t usb_protocol; - uint8_t usb_attributes; - uint16_t usb_power_ma; - bool webusb_enabled; - String webusb_url; - - bool _started; - size_t _task_stack_size; - uint8_t _event_task_priority; -}; - -extern ESPUSB USB; - -#endif /* CONFIG_USB_ENABLED */ diff --git a/cores/esp32/USBCDC.cpp b/cores/esp32/USBCDC.cpp deleted file mode 100644 index ec1e4640..00000000 --- a/cores/esp32/USBCDC.cpp +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright 2015-2020 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. -#include "esp32-hal.h" -#include "esp32-hal-tinyusb.h" -#include "USB.h" -#include "USBCDC.h" -#if CONFIG_USB_ENABLED - -ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS); -esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait); -esp_err_t arduino_usb_event_handler_register_with(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler, void *event_handler_arg); - -extern "C" { -#include "tinyusb.h" -} - -#if CFG_TUD_CDC -#define MAX_USB_CDC_DEVICES 2 -USBCDC * devices[MAX_USB_CDC_DEVICES] = {NULL, NULL}; - -static uint16_t load_cdc_descriptor(uint8_t * dst, uint8_t * itf) -{ - uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC"); - // Interface number, string index, attributes, detach timeout, transfer size */ - uint8_t descriptor[TUD_CDC_DESC_LEN] = { - // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(*itf, str_index, 0x85, 64, 0x03, 0x84, 64) - }; - *itf+=2; - memcpy(dst, descriptor, TUD_CDC_DESC_LEN); - return TUD_CDC_DESC_LEN; -} - -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ - if(itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL){ - devices[itf]->_onLineState(dtr, rts); - } -} - -void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) -{ - if(itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL){ - devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits); - } -} - -void tud_cdc_rx_cb(uint8_t itf) -{ - if(itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL){ - devices[itf]->_onRX(); - } -} - - -static size_t tinyusb_cdc_write(uint8_t itf, const uint8_t *buffer, size_t size){ - if(itf >= MAX_USB_CDC_DEVICES){ - return 0; - } - if(!tud_cdc_n_connected(itf)){ - return 0; - } - size_t tosend = size, sofar = 0; - while(tosend){ - uint32_t space = tud_cdc_n_write_available(itf); - if(!space){ - vTaskDelay(1 / portTICK_PERIOD_MS); - continue; - } - if(tosend < space){ - space = tosend; - } - uint32_t sent = tud_cdc_n_write(itf, buffer + sofar, space); - if(!sent){ - return sofar; - } - sofar += sent; - tosend -= sent; - tud_cdc_n_write_flush(itf); - } - return sofar; -} - -static void ARDUINO_ISR_ATTR cdc0_write_char(char c) -{ - tinyusb_cdc_write(0, (const uint8_t *)&c, 1); -} - -//void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); - -static void usb_unplugged_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){ - ((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) { - tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor); - if(itf < MAX_USB_CDC_DEVICES){ - devices[itf] = this; - arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this); - } -} - -void USBCDC::onEvent(esp_event_handler_t callback){ - onEvent(ARDUINO_USB_CDC_ANY_EVENT, callback); -} -void USBCDC::onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback){ - arduino_usb_event_handler_register_with(ARDUINO_USB_CDC_EVENTS, event, callback, this); -} - -size_t USBCDC::setRxBufferSize(size_t rx_queue_len){ - if(rx_queue){ - return 0; - } - rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t)); - if(!rx_queue){ - return 0; - } - return rx_queue_len; -} - -void USBCDC::begin(unsigned long baud) -{ - setRxBufferSize(256);//default if not preset -} - -void USBCDC::end() -{ -} - -void USBCDC::_onUnplugged(void){ - if(connected){ - connected = false; - dtr = false; - rts = false; - arduino_usb_cdc_event_data_t p = {0}; - arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_DISCONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY); - } -} - -enum { CDC_LINE_IDLE, CDC_LINE_1, CDC_LINE_2, CDC_LINE_3 }; -void USBCDC::_onLineState(bool _dtr, bool _rts){ - static uint8_t lineState = CDC_LINE_IDLE; - dtr = _dtr; - rts = _rts; - - if(reboot_enable){ - if(!dtr && rts){ - if(lineState == CDC_LINE_IDLE){ - lineState++; - } else { - lineState = CDC_LINE_IDLE; - } - } else if(dtr && rts){ - if(lineState == CDC_LINE_1){ - lineState++; - } else { - lineState = CDC_LINE_IDLE; - } - } else if(dtr && !rts){ - if(lineState == CDC_LINE_2){ - lineState++; - } else { - lineState = CDC_LINE_IDLE; - } - } else if(!dtr && !rts){ - if(lineState == CDC_LINE_3){ - usb_persist_restart(RESTART_BOOTLOADER); - } else { - lineState = CDC_LINE_IDLE; - } - } - } - - if(lineState == CDC_LINE_IDLE){ - if(dtr && rts && !connected){ - connected = true; - 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); - } else if(!dtr && !rts && connected){ - connected = false; - arduino_usb_cdc_event_data_t p = {0}; - arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_DISCONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY); - } - arduino_usb_cdc_event_data_t l = {0}; - l.line_state.dtr = dtr; - l.line_state.rts = rts; - 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::_onLineCoding(uint32_t _bit_rate, uint8_t _stop_bits, uint8_t _parity, uint8_t _data_bits){ - if(bit_rate != _bit_rate || data_bits != _data_bits || stop_bits != _stop_bits || parity != _parity){ - bit_rate = _bit_rate; - data_bits = _data_bits; - stop_bits = _stop_bits; - parity = _parity; - arduino_usb_cdc_event_data_t p = {0}; - p.line_coding.bit_rate = bit_rate; - p.line_coding.data_bits = data_bits; - p.line_coding.stop_bits = stop_bits; - p.line_coding.parity = parity; - arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_LINE_CODING_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY); - } -} - -void USBCDC::_onRX(){ - uint8_t buf[CONFIG_USB_CDC_RX_BUFSIZE+1]; - uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_USB_CDC_RX_BUFSIZE); - for(uint32_t i=0; i= MAX_USB_CDC_DEVICES || rx_queue == NULL){ - return -1; - } - return uxQueueMessagesWaiting(rx_queue); -} - -int USBCDC::peek(void) -{ - if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){ - return -1; - } - uint8_t c; - if(xQueuePeek(rx_queue, &c, 0)) { - return c; - } - return -1; -} - -int USBCDC::read(void) -{ - if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){ - return -1; - } - uint8_t c = 0; - if(xQueueReceive(rx_queue, &c, 0)) { - return c; - } - return -1; -} - -size_t USBCDC::read(uint8_t *buffer, size_t size) -{ - if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){ - return -1; - } - uint8_t c = 0; - size_t count = 0; - while(count < size && xQueueReceive(rx_queue, &c, 0)){ - buffer[count++] = c; - } - return count; -} - -void USBCDC::flush(void) -{ - if(itf >= MAX_USB_CDC_DEVICES){ - return; - } - tud_cdc_n_write_flush(itf); -} - -int USBCDC::availableForWrite(void) -{ - if(itf >= MAX_USB_CDC_DEVICES){ - return -1; - } - return tud_cdc_n_write_available(itf); -} - -size_t USBCDC::write(const uint8_t *buffer, size_t size) -{ - return tinyusb_cdc_write(itf, buffer, size); -} - -size_t USBCDC::write(uint8_t c) -{ - return write(&c, 1); -} - -uint32_t USBCDC::baudRate() -{ - return bit_rate; -} - -void USBCDC::setDebugOutput(bool en) -{ - if(en) { - uartSetDebug(NULL); - ets_install_putc1((void (*)(char)) &cdc0_write_char); - } else { - ets_install_putc1(NULL); - } -} - -USBCDC::operator bool() const -{ - if(itf >= MAX_USB_CDC_DEVICES){ - return false; - } - return connected; -} - -#if ARDUINO_SERIAL_PORT //Serial used for USB CDC -USBCDC Serial(0); -#endif - -#endif /* CONFIG_USB_CDC_ENABLED */ - -#endif /* CONFIG_USB_ENABLED */ diff --git a/cores/esp32/USBCDC.h b/cores/esp32/USBCDC.h deleted file mode 100644 index f23469a6..00000000 --- a/cores/esp32/USBCDC.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2015-2020 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 - -#include - -#include "esp32-hal.h" -#if CONFIG_USB_CDC_ENABLED - -#include "esp_event.h" - -ESP_EVENT_DECLARE_BASE(ARDUINO_USB_CDC_EVENTS); - -typedef enum { - ARDUINO_USB_CDC_ANY_EVENT = ESP_EVENT_ANY_ID, - ARDUINO_USB_CDC_CONNECTED_EVENT = 0, - ARDUINO_USB_CDC_DISCONNECTED_EVENT, - ARDUINO_USB_CDC_LINE_STATE_EVENT, - ARDUINO_USB_CDC_LINE_CODING_EVENT, - ARDUINO_USB_CDC_RX_EVENT, - ARDUINO_USB_CDC_MAX_EVENT, -} arduino_usb_cdc_event_t; - -typedef union { - struct { - bool dtr; - bool rts; - } line_state; - struct { - uint32_t bit_rate; - uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits - uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space - uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 - } line_coding; - struct { - size_t len; - } rx; -} arduino_usb_cdc_event_data_t; - -class USBCDC -{ -public: - USBCDC(uint8_t itf=0); - - void onEvent(esp_event_handler_t callback); - void onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback); - - size_t setRxBufferSize(size_t); - void begin(unsigned long baud=0); - void end(); - - int available(void); - int availableForWrite(void); - int peek(void); - int read(void); - size_t read(uint8_t *buffer, size_t size); - size_t write(uint8_t); - size_t write(const uint8_t *buffer, size_t size); - void flush(void); - - inline size_t read(char * buffer, size_t size) - { - return read((uint8_t*) buffer, size); - } - inline size_t write(const char * buffer, size_t size) - { - return write((uint8_t*) buffer, size); - } - inline size_t write(const char * s) - { - return write((uint8_t*) s, strlen(s)); - } - inline size_t write(unsigned long n) - { - return write((uint8_t) n); - } - inline size_t write(long n) - { - return write((uint8_t) n); - } - inline size_t write(unsigned int n) - { - return write((uint8_t) n); - } - inline size_t write(int n) - { - return write((uint8_t) n); - } - uint32_t baudRate(); - void setDebugOutput(bool); - operator bool() const; - - void enableReboot(bool enable); - bool rebootEnabled(void); - - //internal methods - void _onDFU(void); - void _onLineState(bool _dtr, bool _rts); - void _onLineCoding(uint32_t _bit_rate, uint8_t _stop_bits, uint8_t _parity, uint8_t _data_bits); - void _onRX(void); - void _onUnplugged(void); - -protected: - uint8_t itf; - uint32_t bit_rate; - uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits - uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space - uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 - bool dtr; - bool rts; - bool connected; - bool reboot_enable; - xQueueHandle rx_queue; - -}; - -#if ARDUINO_SERIAL_PORT //Serial used for USB CDC -extern USBCDC Serial; -#endif - -#endif /* CONFIG_USB_CDC_ENABLED */ diff --git a/cores/esp32/esp32-hal-tinyusb.c b/cores/esp32/esp32-hal-tinyusb.c deleted file mode 100644 index 3d04fdbe..00000000 --- a/cores/esp32/esp32-hal-tinyusb.c +++ /dev/null @@ -1,697 +0,0 @@ - -#include "sdkconfig.h" -#if CONFIG_USB_ENABLED -#include - -#include "esp_log.h" - -#include "soc/soc.h" -#include "soc/efuse_reg.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/usb_struct.h" -#include "soc/usb_reg.h" -#include "soc/usb_wrap_reg.h" -#include "soc/usb_wrap_struct.h" -#include "soc/periph_defs.h" -#include "soc/timer_group_struct.h" -#include "soc/system_reg.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "driver/gpio.h" -#include "driver/periph_ctrl.h" - -#include "esp_efuse.h" -#include "esp_efuse_table.h" - -#include "tinyusb.h" -#include "esp32-hal.h" - -#include "esp32-hal-tinyusb.h" -#include "esp32s2/rom/usb/usb_persist.h" -#include "esp32s2/rom/usb/usb_dc.h" -#include "esp32s2/rom/usb/chip_usb_dw_wrapper.h" - -typedef char tusb_str_t[127]; - -static bool WEBUSB_ENABLED = false; - -static tusb_str_t WEBUSB_URL = ""; -static tusb_str_t USB_DEVICE_PRODUCT = ""; -static tusb_str_t USB_DEVICE_MANUFACTURER = ""; -static tusb_str_t USB_DEVICE_SERIAL = ""; - -static uint8_t USB_DEVICE_ATTRIBUTES = 0; -static uint16_t USB_DEVICE_POWER = 0; - -/* - * Device Descriptor - * */ -static tusb_desc_device_t tinyusb_device_descriptor = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0, - .bDeviceClass = 0, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, - - .idVendor = 0, - .idProduct = 0, - .bcdDevice = 0, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 -}; - -/* - * String Descriptors - * */ -#define MAX_STRING_DESCRIPTORS 20 -static uint32_t tinyusb_string_descriptor_len = 4; -static char * tinyusb_string_descriptor[MAX_STRING_DESCRIPTORS] = { - // array of pointer to string descriptors - "\x09\x04", // 0: is supported language is English (0x0409) - USB_DEVICE_MANUFACTURER,// 1: Manufacturer - USB_DEVICE_PRODUCT, // 2: Product - USB_DEVICE_SERIAL, // 3: Serials, should use chip ID -}; - - -/* Microsoft OS 2.0 registry property descriptor -Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx -device should create DeviceInterfaceGUIDs. It can be done by driver and -in case of real PnP solution device should expose MS "Microsoft OS 2.0 -registry property descriptor". Such descriptor can insert any record -into Windows registry per device/configuration/interface. In our case it -will insert "DeviceInterfaceGUIDs" multistring property. - -GUID is freshly generated and should be OK to use. - -https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ -(Section Microsoft OS compatibility descriptors) - */ - -#define MS_OS_20_DESC_LEN 0xB2 - -static uint8_t const tinyusb_ms_os_20_descriptor[] = -{ - // Set header: length, type, windows version, total length - U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), - - // Configuration subset header: length, type, configuration index, reserved, configuration total length - U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A), - - // Function Subset header: length, type, first interface, reserved, subset length - U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08), - - // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID - U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible - - // MS OS 2.0 Registry property descriptor: length, type - U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), - U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, - 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, - U16_TO_U8S_LE(0x0050), // wPropertyDataLength - //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”. - '{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00, - '0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, - '8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00, - '8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -TU_VERIFY_STATIC(sizeof(tinyusb_ms_os_20_descriptor) == MS_OS_20_DESC_LEN, "Incorrect size"); - - -/* - * BOS Descriptor (required for webUSB) - * */ -#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) - -enum { - VENDOR_REQUEST_WEBUSB = 1, - VENDOR_REQUEST_MICROSOFT = 2 -}; - -static uint8_t const tinyusb_bos_descriptor[] = { - // total length, number of device caps - TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2), - - // Vendor Code, iLandingPage - TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1), - - // Microsoft OS 2.0 descriptor - TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT) -}; - -/* - * URL Descriptor (required for webUSB) - * */ -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bScheme; - char url[127]; -} tinyusb_desc_webusb_url_t; - -static tinyusb_desc_webusb_url_t tinyusb_url_descriptor = { - .bLength = 3, - .bDescriptorType = 3, // WEBUSB URL type - .bScheme = 1, // URL Scheme Prefix: 0: "http://", 1: "https://", 255: "" - .url = "" -}; - -/* - * Configuration Descriptor - * */ - -static tinyusb_descriptor_cb_t tinyusb_loaded_interfaces_callbacks[USB_INTERFACE_MAX]; -static uint32_t tinyusb_loaded_interfaces_mask = 0; -static uint8_t tinyusb_loaded_interfaces_num = 0; -static uint16_t tinyusb_config_descriptor_len = 0; -static uint8_t * tinyusb_config_descriptor = NULL; - -/* - * Endpoint Usage Tracking - * */ -typedef union { - struct { - uint32_t in:16; - uint32_t out:16; - }; - uint32_t val; -} tinyusb_endpoints_usage_t; - -static tinyusb_endpoints_usage_t tinyusb_endpoints; - - -/* - * TinyUSB Callbacks - * */ - -/** - * @brief Invoked when received GET CONFIGURATION DESCRIPTOR. - */ -uint8_t const *tud_descriptor_configuration_cb(uint8_t index) -{ - //log_d("%u", index); - return tinyusb_config_descriptor; -} - -/** - * @brief Invoked when received GET DEVICE DESCRIPTOR. - */ -uint8_t const *tud_descriptor_device_cb(void) -{ - //log_d(""); - return (uint8_t const *)&tinyusb_device_descriptor; -} - -/** - * @brief Invoked when received GET STRING DESCRIPTOR request. - */ -uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) -{ - //log_d("%u (0x%x)", index, langid); - static uint16_t _desc_str[127]; - uint8_t chr_count; - - if (index == 0) { - memcpy(&_desc_str[1], tinyusb_string_descriptor[0], 2); - chr_count = 1; - } else { - // Convert ASCII string into UTF-16 - if (index >= tinyusb_string_descriptor_len) { - return NULL; - } - const char *str = tinyusb_string_descriptor[index]; - // Cap at max char - chr_count = strlen(str); - if (chr_count > 126) { - chr_count = 126; - } - for (uint8_t i = 0; i < chr_count; i++) { - _desc_str[1 + i] = str[i]; - } - } - - // first byte is len, second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); - - return _desc_str; -} - -/** - * @brief Invoked when received GET BOS DESCRIPTOR request. - */ -uint8_t const * tud_descriptor_bos_cb(void) -{ - //log_d(""); - return tinyusb_bos_descriptor; -} - -__attribute__ ((weak)) bool tinyusb_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request){ return false; } -__attribute__ ((weak)) bool tinyusb_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request){ return true; } - -/** - * @brief Handle WebUSB and Vendor requests. - */ -bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request) -{ - if(WEBUSB_ENABLED && (request->bRequest == VENDOR_REQUEST_WEBUSB - || (request->bRequest == VENDOR_REQUEST_MICROSOFT && request->wIndex == 7))){ - if(request->bRequest == VENDOR_REQUEST_WEBUSB){ - // match vendor request in BOS descriptor - // Get landing page url - tinyusb_url_descriptor.bLength = 3 + strlen(WEBUSB_URL); - snprintf(tinyusb_url_descriptor.url, 127, "%s", WEBUSB_URL); - return tud_control_xfer(rhport, request, (void*) &tinyusb_url_descriptor, tinyusb_url_descriptor.bLength); - } - // Get Microsoft OS 2.0 compatible descriptor - uint16_t total_len; - memcpy(&total_len, tinyusb_ms_os_20_descriptor + 8, 2); - return tud_control_xfer(rhport, request, (void*) tinyusb_ms_os_20_descriptor, total_len); - } - return tinyusb_vendor_control_request_cb(rhport, request); -} - -bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request) -{ - if(!WEBUSB_ENABLED || !(request->bRequest == VENDOR_REQUEST_WEBUSB - || (request->bRequest == VENDOR_REQUEST_MICROSOFT && request->wIndex == 7))){ - return tinyusb_vendor_control_complete_cb(rhport, request); - } - return true; -} - -/* - * Required Callbacks - * */ -#if CFG_TUD_HID -__attribute__ ((weak)) const uint8_t * tud_hid_descriptor_report_cb(void){return NULL;} -__attribute__ ((weak)) uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen){return 0;} -__attribute__ ((weak)) void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, const uint8_t * buffer, uint16_t bufsize){} -#endif -#if CFG_TUD_MSC -__attribute__ ((weak)) bool tud_msc_test_unit_ready_cb(uint8_t lun){return false;} -__attribute__ ((weak)) void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]){} -__attribute__ ((weak)) void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size){} -__attribute__ ((weak)) int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize){return -1;} -__attribute__ ((weak)) int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){return -1;} -__attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize){return -1;} -#endif - - -/* - * Private API - * */ -static bool usb_persist_enabled = false; -static restart_type_t usb_persist_mode = RESTART_NO_PERSIST; - -static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){ - if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){ - return false; - } - tinyusb_endpoints.in |= BIT(endpoint); - return true; -} - -static bool tinyusb_reserve_out_endpoint(uint8_t endpoint){ - if(endpoint > 6 || (tinyusb_endpoints.out & BIT(endpoint)) != 0){ - return false; - } - tinyusb_endpoints.out |= BIT(endpoint); - return true; -} - -static bool tinyusb_has_available_fifos(void){ - uint8_t max_endpoints = 4, active_endpoints = 0; - if (tinyusb_loaded_interfaces_mask & BIT(USB_INTERFACE_CDC)) { - max_endpoints = 5; //CDC endpoint 0x85 is actually not linked to FIFO and not used - } - for(uint8_t i=1; i<7; i++){ - if((tinyusb_endpoints.in & BIT(i)) != 0){ - active_endpoints++; - } - } - - return active_endpoints < max_endpoints; -} - -static uint16_t tinyusb_load_descriptor(tinyusb_interface_t interface, uint8_t * dst, uint8_t * itf) -{ - if(tinyusb_loaded_interfaces_callbacks[interface]){ - return tinyusb_loaded_interfaces_callbacks[interface](dst, itf); - } - return 0; -} - -static bool tinyusb_load_enabled_interfaces(){ - tinyusb_config_descriptor_len += TUD_CONFIG_DESC_LEN; - tinyusb_config_descriptor = (uint8_t *)malloc(tinyusb_config_descriptor_len); - if (tinyusb_config_descriptor == NULL) { - log_e("Descriptor Malloc Failed"); - return false; - } - uint8_t * dst = tinyusb_config_descriptor + TUD_CONFIG_DESC_LEN; - - for(int i=0; i> 4); - *srl++ = nibble_to_hex_char(b & 0xf); - } - *srl++ = '\0'; -} - -static void tinyusb_apply_device_config(tinyusb_device_config_t *config){ - if(config->product_name){ - snprintf(USB_DEVICE_PRODUCT, 126, "%s", config->product_name); - } - - if(config->manufacturer_name){ - snprintf(USB_DEVICE_MANUFACTURER, 126, "%s", config->manufacturer_name); - } - - if(config->serial_number && config->serial_number[0]){ - snprintf(USB_DEVICE_SERIAL, 126, "%s", config->serial_number); - } else { - set_usb_serial_num(); - } - - if(config->webusb_url){ - snprintf(WEBUSB_URL, 126, "%s", config->webusb_url); - } - - WEBUSB_ENABLED = config->webusb_enabled; - USB_DEVICE_ATTRIBUTES = config->usb_attributes; - USB_DEVICE_POWER = config->usb_power_ma; - - tinyusb_device_descriptor.bcdUSB = config->usb_version; - tinyusb_device_descriptor.idVendor = config->vid; - tinyusb_device_descriptor.idProduct = config->pid; - tinyusb_device_descriptor.bcdDevice = config->fw_version; - tinyusb_device_descriptor.bDeviceClass = config->usb_class; - tinyusb_device_descriptor.bDeviceSubClass = config->usb_subclass; - tinyusb_device_descriptor.bDeviceProtocol = config->usb_protocol; -} - -static void IRAM_ATTR usb_persist_shutdown_handler(void) -{ - if(usb_persist_mode != RESTART_NO_PERSIST){ - if (usb_persist_enabled) { - usb_dc_prepare_persist(); - } - if (usb_persist_mode == RESTART_BOOTLOADER) { - //USB CDC Download - if (usb_persist_enabled) { - chip_usb_set_persist_flags(USBDC_PERSIST_ENA); - } - REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); - } else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) { - //DFU Download - chip_usb_set_persist_flags(USBDC_BOOT_DFU); - REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); - } else if (usb_persist_enabled) { - //USB Persist reboot - chip_usb_set_persist_flags(USBDC_PERSIST_ENA); - } - } -} - -// USB Device Driver task -// This top level thread processes all usb events and invokes callbacks -static void usb_device_task(void *param) { - (void)param; - while(1) tud_task(); // RTOS forever loop -} - -/* - * PUBLIC API - * */ - -esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb) -{ - if((interface >= USB_INTERFACE_MAX) || (tinyusb_loaded_interfaces_mask & (1U << interface))){ - log_e("Interface %u not enabled", interface); - return ESP_FAIL; - } - tinyusb_loaded_interfaces_mask |= (1U << interface); - tinyusb_config_descriptor_len += descriptor_len; - tinyusb_loaded_interfaces_callbacks[interface] = cb; - log_d("Interface %u enabled", interface); - return ESP_OK; -} - -esp_err_t tinyusb_init(tinyusb_device_config_t *config) { - static bool initialized = false; - if(initialized){ - return ESP_OK; - } - initialized = true; - - tinyusb_endpoints.val = 0; - tinyusb_apply_device_config(config); - if (!tinyusb_load_enabled_interfaces()) { - initialized = false; - return ESP_FAIL; - } - - bool usb_did_persist = (USB_WRAP.date.val == USBDC_PERSIST_ENA); - - if(usb_did_persist && usb_persist_enabled){ - // Enable USB/IO_MUX peripheral reset, if coming from persistent reboot - REG_CLR_BIT(RTC_CNTL_USB_CONF_REG, RTC_CNTL_IO_MUX_RESET_DISABLE); - REG_CLR_BIT(RTC_CNTL_USB_CONF_REG, RTC_CNTL_USB_RESET_DISABLE); - } else { - // Reset USB module - periph_module_reset(PERIPH_USB_MODULE); - periph_module_enable(PERIPH_USB_MODULE); - } - - if (esp_register_shutdown_handler(usb_persist_shutdown_handler) != ESP_OK) { - initialized = false; - return ESP_FAIL; - } - - tinyusb_config_t tusb_cfg = { - .external_phy = false // In the most cases you need to use a `false` value - }; - esp_err_t err = tinyusb_driver_install(&tusb_cfg); - if (err != ESP_OK) { - initialized = false; - return err; - } - xTaskCreate(usb_device_task, "usbd", 4096, NULL, configMAX_PRIORITIES - 1, NULL); - return err; -} - -void usb_persist_restart(restart_type_t mode) -{ - if (mode < RESTART_TYPE_MAX) { - usb_persist_mode = mode; - esp_restart(); - } -} - -uint8_t tinyusb_add_string_descriptor(const char * str){ - if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){ - return 0; - } - uint8_t index = tinyusb_string_descriptor_len; - tinyusb_string_descriptor[tinyusb_string_descriptor_len++] = (char*)str; - return index; -} - -uint8_t tinyusb_get_free_duplex_endpoint(void){ - if(!tinyusb_has_available_fifos()){ - log_e("No available IN endpoints"); - return 0; - } - for(uint8_t i=1; i<7; i++){ - if((tinyusb_endpoints.in & BIT(i)) == 0 && (tinyusb_endpoints.out & BIT(i)) == 0){ - tinyusb_endpoints.in |= BIT(i); - tinyusb_endpoints.out |= BIT(i); - return i; - } - } - log_e("No available duplex endpoints"); - return 0; -} - -uint8_t tinyusb_get_free_in_endpoint(void){ - if(!tinyusb_has_available_fifos()){ - log_e("No available IN endpoints"); - return 0; - } - for(uint8_t i=1; i<7; i++){ - if((tinyusb_endpoints.in & BIT(i)) == 0 && (tinyusb_endpoints.out & BIT(i)) != 0){ - tinyusb_endpoints.in |= BIT(i); - return i; - } - } - for(uint8_t i=1; i<7; i++){ - if((tinyusb_endpoints.in & BIT(i)) == 0){ - tinyusb_endpoints.in |= BIT(i); - return i; - } - } - return 0; -} - -uint8_t tinyusb_get_free_out_endpoint(void){ - for(uint8_t i=1; i<7; i++){ - if((tinyusb_endpoints.out & BIT(i)) == 0 && (tinyusb_endpoints.in & BIT(i)) != 0){ - tinyusb_endpoints.out |= BIT(i); - return i; - } - } - for(uint8_t i=1; i<7; i++){ - if((tinyusb_endpoints.out & BIT(i)) == 0){ - tinyusb_endpoints.out |= BIT(i); - return i; - } - } - return 0; -} - -/* -void usb_dw_reg_dump(void) -{ -#define USB_PRINT_REG(r) printf("USB0." #r " = 0x%x;\n", USB0.r) -#define USB_PRINT_IREG(i, r) printf("USB0.in_ep_reg[%u]." #r " = 0x%x;\n", i, USB0.in_ep_reg[i].r) -#define USB_PRINT_OREG(i, r) printf("USB0.out_ep_reg[%u]." #r " = 0x%x;\n", i, USB0.out_ep_reg[i].r) - uint8_t i; - USB_PRINT_REG(gotgctl); - USB_PRINT_REG(gotgint); - USB_PRINT_REG(gahbcfg); - USB_PRINT_REG(gusbcfg); - USB_PRINT_REG(grstctl); - USB_PRINT_REG(gintsts); - USB_PRINT_REG(gintmsk); - USB_PRINT_REG(grxstsr); - USB_PRINT_REG(grxstsp); - USB_PRINT_REG(grxfsiz); - USB_PRINT_REG(gnptxsts); - USB_PRINT_REG(gpvndctl); - USB_PRINT_REG(ggpio); - USB_PRINT_REG(guid); - USB_PRINT_REG(gsnpsid); - USB_PRINT_REG(ghwcfg1); - USB_PRINT_REG(ghwcfg2); - USB_PRINT_REG(ghwcfg3); - USB_PRINT_REG(ghwcfg4); - USB_PRINT_REG(glpmcfg); - USB_PRINT_REG(gpwrdn); - USB_PRINT_REG(gdfifocfg); - USB_PRINT_REG(gadpctl); - USB_PRINT_REG(hptxfsiz); - USB_PRINT_REG(hcfg); - USB_PRINT_REG(hfir); - USB_PRINT_REG(hfnum); - USB_PRINT_REG(hptxsts); - USB_PRINT_REG(haint); - USB_PRINT_REG(haintmsk); - USB_PRINT_REG(hflbaddr); - USB_PRINT_REG(hprt); - USB_PRINT_REG(dcfg); - USB_PRINT_REG(dctl); - USB_PRINT_REG(dsts); - USB_PRINT_REG(diepmsk); - USB_PRINT_REG(doepmsk); - USB_PRINT_REG(daint); - USB_PRINT_REG(daintmsk); - USB_PRINT_REG(dtknqr1); - USB_PRINT_REG(dtknqr2); - USB_PRINT_REG(dvbusdis); - USB_PRINT_REG(dvbuspulse); - USB_PRINT_REG(dtknqr3_dthrctl); - USB_PRINT_REG(dtknqr4_fifoemptymsk); - USB_PRINT_REG(deachint); - USB_PRINT_REG(deachintmsk); - USB_PRINT_REG(pcgctrl); - USB_PRINT_REG(pcgctrl1); - USB_PRINT_REG(gnptxfsiz); - for (i = 0; i < 4; i++) { - printf("USB0.dieptxf[%u] = 0x%x;\n", i, USB0.dieptxf[i]); - } -// for (i = 0; i < 16; i++) { -// printf("USB0.diepeachintmsk[%u] = 0x%x;\n", i, USB0.diepeachintmsk[i]); -// } -// for (i = 0; i < 16; i++) { -// printf("USB0.doepeachintmsk[%u] = 0x%x;\n", i, USB0.doepeachintmsk[i]); -// } - for (i = 0; i < 7; i++) { - printf("// EP %u:\n", i); - USB_PRINT_IREG(i, diepctl); - USB_PRINT_IREG(i, diepint); - USB_PRINT_IREG(i, dieptsiz); - USB_PRINT_IREG(i, diepdma); - USB_PRINT_IREG(i, dtxfsts); - USB_PRINT_OREG(i, doepctl); - USB_PRINT_OREG(i, doepint); - USB_PRINT_OREG(i, doeptsiz); - USB_PRINT_OREG(i, doepdma); - } -} - */ -#endif /* CONFIG_USB_ENABLED */ diff --git a/cores/esp32/esp32-hal-tinyusb.h b/cores/esp32/esp32-hal-tinyusb.h deleted file mode 100644 index adf6780b..00000000 --- a/cores/esp32/esp32-hal-tinyusb.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2015-2020 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 - -#include "esp32-hal.h" - -#if CONFIG_IDF_TARGET_ESP32S2 -#if CONFIG_USB_ENABLED - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tinyusb.h" - -typedef struct { - uint16_t vid; - uint16_t pid; - const char * product_name; - const char * manufacturer_name; - const char * serial_number; - uint16_t fw_version; - - uint16_t usb_version; - uint8_t usb_class; - uint8_t usb_subclass; - uint8_t usb_protocol; - uint8_t usb_attributes; - uint16_t usb_power_ma; - - bool webusb_enabled; - const char * webusb_url; -} tinyusb_device_config_t; - -#define TINYUSB_CONFIG_DEFAULT() { \ - .vid = USB_ESPRESSIF_VID, \ - .pid = 0x0002, \ - .product_name = CONFIG_USB_DESC_PRODUCT_STRING, \ - .manufacturer_name = CONFIG_USB_DESC_MANUFACTURER_STRING, \ - .serial_number = CONFIG_USB_DESC_SERIAL_STRING, \ - .fw_version = CONFIG_USB_DESC_BCDDEVICE, \ - .usb_version = 0x0200, \ - .usb_class = TUSB_CLASS_MISC, \ - .usb_subclass = MISC_SUBCLASS_COMMON, \ - .usb_protocol = MISC_PROTOCOL_IAD, \ - .usb_attributes = TUSB_DESC_CONFIG_ATT_SELF_POWERED, \ - .usb_power_ma = 500, \ - .webusb_enabled = false, \ - .webusb_url = "espressif.github.io/arduino-esp32/webusb.html" \ -} - -esp_err_t tinyusb_init(tinyusb_device_config_t *config); - -/* - * USB Persistence API - * */ -typedef enum { - RESTART_NO_PERSIST, - RESTART_PERSIST, - RESTART_BOOTLOADER, - RESTART_BOOTLOADER_DFU, - RESTART_TYPE_MAX -} restart_type_t; - -void usb_persist_restart(restart_type_t mode); - -// The following definitions and functions are to be used only by the drivers -typedef enum { - USB_INTERFACE_CDC, - USB_INTERFACE_DFU, - USB_INTERFACE_HID, - USB_INTERFACE_VENDOR, - USB_INTERFACE_MSC, - USB_INTERFACE_MIDI, - USB_INTERFACE_CUSTOM, - USB_INTERFACE_MAX -} tinyusb_interface_t; - -typedef uint16_t (*tinyusb_descriptor_cb_t)(uint8_t * dst, uint8_t * itf); - -esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb); -uint8_t tinyusb_add_string_descriptor(const char * str); -uint8_t tinyusb_get_free_duplex_endpoint(void); -uint8_t tinyusb_get_free_in_endpoint(void); -uint8_t tinyusb_get_free_out_endpoint(void); - -#ifdef __cplusplus -} -#endif - -#endif /* CONFIG_USB_ENABLED */ -#endif /* CONFIG_IDF_TARGET_ESP32S2 */