blackmagic glue works
This commit is contained in:
parent
59d0ea87a5
commit
a51f611066
|
@ -56,7 +56,8 @@ target_sources(${COMPONENT_TARGET} INTERFACE
|
|||
"${COMPONENT_DIR}/tinyusb/src/host/usbh_control.c"
|
||||
|
||||
"${COMPONENT_DIR}/drivers/usb-glue.c"
|
||||
"${COMPONENT_DIR}/drivers/dual-cdc/dual-cdc-driver.c"
|
||||
|
||||
# "${COMPONENT_DIR}/drivers/dual-cdc/dual-cdc-driver.c"
|
||||
"${COMPONENT_DIR}/drivers/dual-cdc/dual-cdc-descriptors.c"
|
||||
|
||||
# "${COMPONENT_DIR}/drivers/dap-link/vendor_device.c"
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
#include <tusb.h>
|
||||
#include <class/cdc/cdc_device.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/periph_ctrl.h>
|
||||
#include <hal/usb_hal.h>
|
||||
#include <soc/gpio_periph.h>
|
||||
#include <soc/usb_periph.h>
|
||||
#include <esp_rom_gpio.h>
|
||||
#include <hal/gpio_ll.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_check.h>
|
||||
|
||||
#include "dual-cdc-driver.h"
|
||||
|
||||
#define TAG "usb-dual-cdc"
|
||||
|
||||
#define CONFIG_TINYUSB_TASK_STACK_SIZE 4096
|
||||
#define CONFIG_TINYUSB_TASK_PRIORITY 17
|
||||
|
||||
static void configure_pins(usb_hal_context_t* usb) {
|
||||
/* usb_periph_iopins currently configures USB_OTG as USB Device.
|
||||
* Introduce additional parameters in usb_hal_context_t when adding support
|
||||
* for USB Host.
|
||||
*/
|
||||
for(const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
|
||||
if((usb->use_external_phy) || (iopin->ext_phy_only == 0)) {
|
||||
esp_rom_gpio_pad_select_gpio(iopin->pin);
|
||||
if(iopin->is_output) {
|
||||
esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false);
|
||||
} else {
|
||||
esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false);
|
||||
if((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) {
|
||||
gpio_ll_input_enable(&GPIO, iopin->pin);
|
||||
}
|
||||
}
|
||||
esp_rom_gpio_pad_unhold(iopin->pin);
|
||||
}
|
||||
}
|
||||
if(!usb->use_external_phy) {
|
||||
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
|
||||
}
|
||||
}
|
||||
|
||||
static void tusb_device_task(void* arg) {
|
||||
ESP_LOGD(TAG, "tinyusb task started");
|
||||
while(1) { // RTOS forever loop
|
||||
tud_task();
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t dual_cdc_driver_install(void) {
|
||||
// Enable APB CLK to USB peripheral
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
periph_module_reset(PERIPH_USB_MODULE);
|
||||
|
||||
// Initialize HAL layer
|
||||
usb_hal_context_t hal = {.use_external_phy = false};
|
||||
usb_hal_init(&hal);
|
||||
configure_pins(&hal);
|
||||
|
||||
ESP_RETURN_ON_FALSE(tusb_init(), ESP_FAIL, TAG, "init TinyUSB failed");
|
||||
|
||||
TaskHandle_t s_tusb_tskh;
|
||||
xTaskCreate(
|
||||
tusb_device_task,
|
||||
"TinyUSB",
|
||||
CONFIG_TINYUSB_TASK_STACK_SIZE,
|
||||
NULL,
|
||||
CONFIG_TINYUSB_TASK_PRIORITY,
|
||||
&s_tusb_tskh);
|
||||
ESP_RETURN_ON_FALSE(s_tusb_tskh, ESP_FAIL, TAG, "create TinyUSB main task failed");
|
||||
|
||||
ESP_LOGI(TAG, "TinyUSB Driver installed");
|
||||
return ESP_OK;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* @file dual-cdc-driver.h
|
||||
* @author Sergey Gavrilov (who.just.the.doctor@gmail.com)
|
||||
* @version 1.0
|
||||
* @date 2021-12-16
|
||||
*
|
||||
* Dual CDC driver
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <esp_err.h>
|
||||
#include <tusb_config.h>
|
||||
|
||||
#define CDC_IF_COUNT CFG_TUD_CDC
|
||||
|
||||
/**
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t dual_cdc_driver_install(void);
|
|
@ -3,6 +3,10 @@
|
|||
#include "dual-cdc/dual-cdc-descriptors.h"
|
||||
#include "usb-glue.h"
|
||||
|
||||
#define TAG "usb-glue"
|
||||
#define CONFIG_TINYUSB_TASK_STACK_SIZE 4096
|
||||
#define CONFIG_TINYUSB_TASK_PRIORITY 17
|
||||
|
||||
typedef struct {
|
||||
uint8_t const* desc_device;
|
||||
uint8_t const* desc_config;
|
||||
|
@ -165,6 +169,11 @@ bool tud_vendor_control_xfer_cb(
|
|||
return true;
|
||||
}
|
||||
|
||||
void tud_vendor_rx_cb(uint8_t itf) {
|
||||
(void)itf;
|
||||
callback_dap_receive();
|
||||
}
|
||||
|
||||
void tud_mount_cb(void) {
|
||||
callback_connected();
|
||||
}
|
||||
|
@ -226,10 +235,101 @@ void tud_cdc_line_coding_cb(uint8_t interface, cdc_line_coding_t const* p_line_c
|
|||
}
|
||||
}
|
||||
|
||||
/***** HAL *****/
|
||||
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/periph_ctrl.h>
|
||||
#include <hal/usb_hal.h>
|
||||
#include <soc/usb_periph.h>
|
||||
#include <esp_rom_gpio.h>
|
||||
#include <hal/gpio_ll.h>
|
||||
#include <delay.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_check.h>
|
||||
|
||||
static void usb_hal_init_pins(usb_hal_context_t* usb) {
|
||||
/* usb_periph_iopins currently configures USB_OTG as USB Device.
|
||||
* Introduce additional parameters in usb_hal_context_t when adding support
|
||||
* for USB Host.
|
||||
*/
|
||||
for(const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
|
||||
if((usb->use_external_phy) || (iopin->ext_phy_only == 0)) {
|
||||
esp_rom_gpio_pad_select_gpio(iopin->pin);
|
||||
if(iopin->is_output) {
|
||||
esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false);
|
||||
} else {
|
||||
esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false);
|
||||
if((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) {
|
||||
gpio_ll_input_enable(&GPIO, iopin->pin);
|
||||
}
|
||||
}
|
||||
esp_rom_gpio_pad_unhold(iopin->pin);
|
||||
}
|
||||
}
|
||||
if(!usb->use_external_phy) {
|
||||
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_hal_bus_reset() {
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT_OD;
|
||||
io_conf.pin_bit_mask = ((1 << USBPHY_DM_NUM) | (1 << USBPHY_DP_NUM));
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
gpio_set_level(USBPHY_DM_NUM, 0);
|
||||
gpio_set_level(USBPHY_DP_NUM, 0);
|
||||
delay(100);
|
||||
gpio_set_level(USBPHY_DM_NUM, 1);
|
||||
gpio_set_level(USBPHY_DP_NUM, 1);
|
||||
}
|
||||
|
||||
static void usb_hal_tusb_device_task(void* arg) {
|
||||
ESP_LOGD(TAG, "tinyusb task started");
|
||||
while(1) { // RTOS forever loop
|
||||
tud_task();
|
||||
}
|
||||
}
|
||||
|
||||
/***** Glue *****/
|
||||
|
||||
void usb_glue_init(USBDeviceType device_type) {
|
||||
esp_err_t usb_glue_init(USBDeviceType device_type) {
|
||||
usb_device_type = device_type;
|
||||
|
||||
usb_hal_bus_reset();
|
||||
|
||||
// Enable APB CLK to USB peripheral
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
periph_module_reset(PERIPH_USB_MODULE);
|
||||
|
||||
// Initialize HAL layer
|
||||
usb_hal_context_t hal = {.use_external_phy = false};
|
||||
usb_hal_init(&hal);
|
||||
usb_hal_init_pins(&hal);
|
||||
|
||||
ESP_RETURN_ON_FALSE(tusb_init(), ESP_FAIL, TAG, "init TinyUSB failed");
|
||||
|
||||
TaskHandle_t s_tusb_tskh;
|
||||
xTaskCreate(
|
||||
usb_hal_tusb_device_task,
|
||||
"TinyUSB",
|
||||
CONFIG_TINYUSB_TASK_STACK_SIZE,
|
||||
NULL,
|
||||
CONFIG_TINYUSB_TASK_PRIORITY,
|
||||
&s_tusb_tskh);
|
||||
ESP_RETURN_ON_FALSE(s_tusb_tskh, ESP_FAIL, TAG, "create TinyUSB main task failed");
|
||||
|
||||
ESP_LOGI(TAG, "TinyUSB Driver installed");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void usb_glue_reset_bus() {
|
||||
usb_hal_bus_reset();
|
||||
}
|
||||
|
||||
void usb_glue_set_connected_callback(void (*callback)(void* context), void* context) {
|
||||
|
@ -310,4 +410,5 @@ void usb_glue_dap_send(const uint8_t* buf, size_t len, bool flush) {
|
|||
|
||||
size_t usb_glue_dap_receive(uint8_t* buf, size_t len) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <esp_err.h>
|
||||
#include <tusb.h>
|
||||
|
||||
typedef enum {
|
||||
USBDeviceTypeDapLink,
|
||||
|
@ -9,7 +11,9 @@ typedef enum {
|
|||
|
||||
/***** Common *****/
|
||||
|
||||
void usb_glue_init(USBDeviceType device_type);
|
||||
esp_err_t usb_glue_init(USBDeviceType device_type);
|
||||
|
||||
void usb_glue_reset_bus();
|
||||
|
||||
void usb_glue_set_connected_callback(void (*callback)(void* context), void* context);
|
||||
|
||||
|
|
100
main/usb-cdc.c
100
main/usb-cdc.c
|
@ -18,7 +18,7 @@
|
|||
#include "led.h"
|
||||
#include "delay.h"
|
||||
#include <gdb-glue.h>
|
||||
#include <dual-cdc-driver.h>
|
||||
#include <usb-glue.h>
|
||||
#include <class/cdc/cdc_device.h>
|
||||
|
||||
#define USB_DN_PIN (19)
|
||||
|
@ -37,32 +37,19 @@ typedef struct {
|
|||
|
||||
static USBCDC usb_cdc;
|
||||
|
||||
typedef enum {
|
||||
CDCTypeGDB = 0,
|
||||
CDCTypeUART = 1,
|
||||
} CDCType;
|
||||
|
||||
static void usb_cdc_tx_char(CDCType type, uint8_t c, bool flush) {
|
||||
tud_cdc_n_write(type, &c, 1);
|
||||
|
||||
if(flush) {
|
||||
tud_cdc_n_write_flush(type);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_cdc_gdb_tx_char(uint8_t c, bool flush) {
|
||||
usb_cdc_tx_char(CDCTypeGDB, c, flush);
|
||||
usb_glue_gdb_send(&c, 1, flush);
|
||||
}
|
||||
|
||||
void usb_cdc_uart_tx_char(uint8_t c, bool flush) {
|
||||
usb_cdc_tx_char(CDCTypeUART, c, flush);
|
||||
usb_glue_cdc_send(&c, 1, flush);
|
||||
}
|
||||
|
||||
void usb_cdc_gdb_rx_callback(void) {
|
||||
static void usb_cdc_gdb_rx_callback(void* context) {
|
||||
if(gdb_glue_can_receive()) {
|
||||
size_t max_len = gdb_glue_get_free_size();
|
||||
if(max_len > GDB_BUF_RX_SIZE) max_len = GDB_BUF_RX_SIZE;
|
||||
uint32_t rx_size = tud_cdc_n_read(CDCTypeGDB, gdb_buffer_rx, max_len);
|
||||
uint32_t rx_size = usb_glue_gdb_receive(gdb_buffer_rx, max_len);
|
||||
|
||||
if(rx_size > 0) {
|
||||
gdb_glue_receive(gdb_buffer_rx, rx_size);
|
||||
|
@ -72,43 +59,28 @@ void usb_cdc_gdb_rx_callback(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void usb_cdc_uart_rx_callback(void) {
|
||||
static void usb_cdc_uart_rx_callback(void* context) {
|
||||
size_t max_len = gdb_glue_get_free_size();
|
||||
if(max_len > UART_BUF_RX_SIZE) max_len = UART_BUF_RX_SIZE;
|
||||
uint32_t rx_size = tud_cdc_n_read(CDCTypeUART, uart_buffer_rx, max_len);
|
||||
uint32_t rx_size = usb_glue_cdc_receive(uart_buffer_rx, max_len);
|
||||
|
||||
if(rx_size > 0) {
|
||||
usb_uart_write(uart_buffer_rx, rx_size);
|
||||
}
|
||||
}
|
||||
|
||||
void tud_cdc_rx_cb(uint8_t interface) {
|
||||
do {
|
||||
if(interface == CDCTypeGDB) {
|
||||
usb_cdc_gdb_rx_callback();
|
||||
} else if(interface == CDCTypeUART) {
|
||||
usb_cdc_uart_rx_callback();
|
||||
} else {
|
||||
tud_cdc_n_read_flush(interface);
|
||||
}
|
||||
} while(false);
|
||||
static void usb_cdc_line_state_cb(bool dtr, bool rts, void* context) {
|
||||
usb_uart_set_line_state(dtr, rts);
|
||||
}
|
||||
|
||||
void tud_cdc_line_state_cb(uint8_t interface, bool dtr, bool rts) {
|
||||
if(interface == CDCTypeUART) {
|
||||
usb_uart_set_line_state(dtr, rts);
|
||||
}
|
||||
}
|
||||
|
||||
void tud_cdc_line_coding_cb(uint8_t interface, cdc_line_coding_t const* p_line_coding) {
|
||||
static void
|
||||
usb_cdc_set_line_coding_callback(cdc_line_coding_t const* p_line_coding, void* context) {
|
||||
uint32_t bit_rate = p_line_coding->bit_rate;
|
||||
uint8_t stop_bits = p_line_coding->stop_bits;
|
||||
uint8_t parity = p_line_coding->parity;
|
||||
uint8_t data_bits = p_line_coding->data_bits;
|
||||
|
||||
if(interface == CDCTypeUART) {
|
||||
usb_uart_set_line_coding(bit_rate, stop_bits, parity, data_bits);
|
||||
}
|
||||
usb_uart_set_line_coding(bit_rate, stop_bits, parity, data_bits);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -121,7 +93,7 @@ static void usb_cdc_event_blink(void) {
|
|||
led_set_blue(0);
|
||||
}
|
||||
|
||||
static void usb_cdc_to_connected(void) {
|
||||
static void usb_cdc_to_connected(void* context) {
|
||||
if(!usb_cdc.connected) {
|
||||
usb_cdc_event_blink();
|
||||
}
|
||||
|
@ -129,7 +101,7 @@ static void usb_cdc_to_connected(void) {
|
|||
ESP_LOGI(TAG, "connect");
|
||||
}
|
||||
|
||||
static void usb_cdc_from_connected(void) {
|
||||
static void usb_cdc_from_connected(void* context) {
|
||||
if(usb_cdc.connected) {
|
||||
usb_cdc_event_blink();
|
||||
}
|
||||
|
@ -138,45 +110,19 @@ static void usb_cdc_from_connected(void) {
|
|||
ESP_LOGI(TAG, "disconnect");
|
||||
}
|
||||
|
||||
void tud_mount_cb(void) {
|
||||
usb_cdc_to_connected();
|
||||
}
|
||||
|
||||
void tud_umount_cb(void) {
|
||||
usb_cdc_from_connected();
|
||||
}
|
||||
|
||||
void tud_resume_cb(void) {
|
||||
usb_cdc_to_connected();
|
||||
}
|
||||
|
||||
void tud_suspend_cb(bool remote_wakeup_en) {
|
||||
usb_cdc_from_connected();
|
||||
}
|
||||
|
||||
static void usb_cdc_bus_reset() {
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT_OD;
|
||||
io_conf.pin_bit_mask = ((1 << USB_DN_PIN) | (1 << USB_DP_PIN));
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
gpio_set_level(USB_DN_PIN, 0);
|
||||
gpio_set_level(USB_DP_PIN, 0);
|
||||
delay(100);
|
||||
gpio_set_level(USB_DN_PIN, 1);
|
||||
gpio_set_level(USB_DP_PIN, 1);
|
||||
}
|
||||
|
||||
void usb_cdc_init(void) {
|
||||
ESP_LOGI(TAG, "init");
|
||||
|
||||
usb_glue_set_connected_callback(usb_cdc_to_connected, NULL);
|
||||
usb_glue_set_disconnected_callback(usb_cdc_from_connected, NULL);
|
||||
usb_glue_cdc_set_line_coding_callback(usb_cdc_set_line_coding_callback, NULL);
|
||||
usb_glue_cdc_set_line_state_callback(usb_cdc_line_state_cb, NULL);
|
||||
usb_glue_cdc_set_receive_callback(usb_cdc_uart_rx_callback, NULL);
|
||||
usb_glue_gdb_set_receive_callback(usb_cdc_gdb_rx_callback, NULL);
|
||||
|
||||
usb_cdc.connected = false;
|
||||
usb_uart_init();
|
||||
usb_cdc_bus_reset();
|
||||
dual_cdc_driver_install();
|
||||
|
||||
usb_glue_init(USBDeviceTypeDualCDC);
|
||||
|
||||
ESP_LOGI(TAG, "init done");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue