Skip to content

Commit 9507124

Browse files
authored
Adds USB to Peripheral Manager - Arduino Core 3.0.0 (#8335)
1 parent 31b07e0 commit 9507124

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

cores/esp32/HWCDC.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
1616

1717
#include "esp32-hal.h"
18+
#include "esp32-hal-periman.h"
1819
#include "HWCDC.h"
1920
#include "freertos/FreeRTOS.h"
2021
#include "freertos/semphr.h"
2122
#include "freertos/queue.h"
2223
#include "freertos/ringbuf.h"
2324
#include "esp_intr_alloc.h"
2425
#include "soc/periph_defs.h"
26+
#include "soc/io_mux_reg.h"
2527
#pragma GCC diagnostic ignored "-Wvolatile"
2628
#include "hal/usb_serial_jtag_ll.h"
2729
#pragma GCC diagnostic warning "-Wvolatile"
@@ -171,6 +173,28 @@ void HWCDC::onEvent(arduino_hw_cdc_event_t event, esp_event_handler_t callback){
171173
arduino_hw_cdc_event_handler_register_with(ARDUINO_HW_CDC_EVENTS, event, callback, this);
172174
}
173175

176+
bool HWCDC::deinit(void * busptr)
177+
{
178+
// avoid any recursion issue with Peripheral Manager perimanSetPinBus() call
179+
static bool running = false;
180+
if (running) return true;
181+
running = true;
182+
// Setting USB D+ D- pins
183+
bool retCode = true;
184+
retCode &= perimanSetPinBus(USB_DM_GPIO_NUM, ESP32_BUS_TYPE_INIT, NULL);
185+
retCode &= perimanSetPinBus(USB_DP_GPIO_NUM, ESP32_BUS_TYPE_INIT, NULL);
186+
if (retCode) {
187+
// Force the host to re-enumerate (BUS_RESET)
188+
pinMode(USB_DM_GPIO_NUM, OUTPUT_OPEN_DRAIN);
189+
pinMode(USB_DP_GPIO_NUM, OUTPUT_OPEN_DRAIN);
190+
digitalWrite(USB_DM_GPIO_NUM, LOW);
191+
digitalWrite(USB_DP_GPIO_NUM, LOW);
192+
}
193+
// release the flag
194+
running = false;
195+
return retCode;
196+
}
197+
174198
void HWCDC::begin(unsigned long baud)
175199
{
176200
if(tx_lock == NULL) {
@@ -187,6 +211,14 @@ void HWCDC::begin(unsigned long baud)
187211
end();
188212
return;
189213
}
214+
if (perimanSetBusDeinit(ESP32_BUS_TYPE_USB, HWCDC::deinit)) {
215+
// Setting USB D+ D- pins
216+
perimanSetPinBus(USB_DM_GPIO_NUM, ESP32_BUS_TYPE_USB, (void *) this);
217+
perimanSetPinBus(USB_DP_GPIO_NUM, ESP32_BUS_TYPE_USB, (void *) this);
218+
} else {
219+
log_e("Serial JTAG Pins can't be set into Peripheral Manager.");
220+
}
221+
190222
usb_serial_jtag_ll_txfifo_flush();
191223
}
192224

@@ -206,6 +238,7 @@ void HWCDC::end()
206238
esp_event_loop_delete(arduino_hw_cdc_event_loop_handle);
207239
arduino_hw_cdc_event_loop_handle = NULL;
208240
}
241+
HWCDC::deinit(this);
209242
}
210243

211244
void HWCDC::setTxTimeoutMs(uint32_t timeout){

cores/esp32/HWCDC.h

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ typedef union {
4242

4343
class HWCDC: public Stream
4444
{
45+
private:
46+
static bool deinit(void * busptr);
47+
4548
public:
4649
HWCDC();
4750
~HWCDC();

cores/esp32/esp32-hal-tinyusb.c

+13
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "esp_rom_gpio.h"
3333

3434
#include "esp32-hal.h"
35+
#include "esp32-hal-periman.h"
3536

3637
#include "esp32-hal-tinyusb.h"
3738
#if CONFIG_IDF_TARGET_ESP32S2
@@ -56,6 +57,11 @@ typedef struct {
5657
bool external_phy;
5758
} tinyusb_config_t;
5859

60+
static bool usb_otg_deinit(void * busptr) {
61+
// Once USB OTG is initialized, its GPIOs are assigned and it shall never be deinited
62+
return false;
63+
}
64+
5965
static void configure_pins(usb_hal_context_t *usb)
6066
{
6167
for (const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
@@ -75,6 +81,13 @@ static void configure_pins(usb_hal_context_t *usb)
7581
if (!usb->use_external_phy) {
7682
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
7783
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
84+
if (perimanSetBusDeinit(ESP32_BUS_TYPE_USB, usb_otg_deinit)) {
85+
// Bus Pointer is not used anyway - once the USB GPIOs are assigned, they can't be detached
86+
perimanSetPinBus(USBPHY_DM_NUM, ESP32_BUS_TYPE_USB, (void *) usb);
87+
perimanSetPinBus(USBPHY_DP_NUM, ESP32_BUS_TYPE_USB, (void *) usb);
88+
} else {
89+
log_e("USB OTG Pins can't be set into Peripheral Manager.");
90+
}
7891
}
7992
}
8093

0 commit comments

Comments
 (0)