Skip to content

Commit

Permalink
RP2040 ISO API
Browse files Browse the repository at this point in the history
  • Loading branch information
pschatzmann committed Oct 14, 2024
1 parent 933ac29 commit 43e4f14
Show file tree
Hide file tree
Showing 62 changed files with 148 additions and 27 deletions.
1 change: 1 addition & 0 deletions hw/mcu/allwinner
Submodule allwinner added at 8e5e89
1 change: 1 addition & 0 deletions hw/mcu/analog/max32
Submodule max32 added at b20b39
1 change: 1 addition & 0 deletions hw/mcu/bridgetek/ft9xx/ft90x-sdk
Submodule ft90x-sdk added at 910601
1 change: 1 addition & 0 deletions hw/mcu/broadcom
Submodule broadcom added at 083700
1 change: 1 addition & 0 deletions hw/mcu/gd/nuclei-sdk
Submodule nuclei-sdk added at 7eb7bf
1 change: 1 addition & 0 deletions hw/mcu/infineon/mtb-xmclib-cat3
Submodule mtb-xmclib-cat3 added at daf550
1 change: 1 addition & 0 deletions hw/mcu/microchip
Submodule microchip added at 9e8b37
1 change: 1 addition & 0 deletions hw/mcu/mindmotion/mm32sdk
Submodule mm32sdk added at b93e85
1 change: 1 addition & 0 deletions hw/mcu/nordic/nrfx
Submodule nrfx added at 7c47cc
1 change: 1 addition & 0 deletions hw/mcu/nuvoton
Submodule nuvoton added at 220419
1 change: 1 addition & 0 deletions hw/mcu/nxp/lpcopen
Submodule lpcopen added at b41cf9
1 change: 1 addition & 0 deletions hw/mcu/nxp/mcux-sdk
Submodule mcux-sdk added at 144f1e
1 change: 1 addition & 0 deletions hw/mcu/raspberry_pi/Pico-PIO-USB
Submodule Pico-PIO-USB added at fe9133
1 change: 1 addition & 0 deletions hw/mcu/renesas/fsp
Submodule fsp added at d52e5a
1 change: 1 addition & 0 deletions hw/mcu/renesas/rx
Submodule rx added at 706b4e
1 change: 1 addition & 0 deletions hw/mcu/silabs/cmsis-dfp-efm32gg12b
Submodule cmsis-dfp-efm32gg12b added at f1c31b
1 change: 1 addition & 0 deletions hw/mcu/sony/cxd56/spresense-exported-sdk
Submodule spresense-exported-sdk added at 2ec2a1
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_f0
Submodule cmsis_device_f0 added at 2fc25e
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_f1
Submodule cmsis_device_f1 added at 660110
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_f2
Submodule cmsis_device_f2 added at 182fcb
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_f3
Submodule cmsis_device_f3 added at 5e4ee5
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_f4
Submodule cmsis_device_f4 added at 2615e8
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_f7
Submodule cmsis_device_f7 added at 25b046
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_g0
Submodule cmsis_device_g0 added at 3a23e1
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_g4
Submodule cmsis_device_g4 added at ce822a
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_h5
Submodule cmsis_device_h5 added at cd2d1d
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_h7
Submodule cmsis_device_h7 added at 60dc2c
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_l0
Submodule cmsis_device_l0 added at 69cd59
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_l1
Submodule cmsis_device_l1 added at 7f16ec
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_l4
Submodule cmsis_device_l4 added at 6ca731
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_l5
Submodule cmsis_device_l5 added at d92286
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_u5
Submodule cmsis_device_u5 added at 5ad979
1 change: 1 addition & 0 deletions hw/mcu/st/cmsis_device_wb
Submodule cmsis_device_wb added at 9c5d19
1 change: 1 addition & 0 deletions hw/mcu/st/stm32f0xx_hal_driver
Submodule stm32f0xx_hal_driver added at 0e95cd
1 change: 1 addition & 0 deletions hw/mcu/st/stm32f1xx_hal_driver
Submodule stm32f1xx_hal_driver added at 1dd9d3
1 change: 1 addition & 0 deletions hw/mcu/st/stm32f2xx_hal_driver
Submodule stm32f2xx_hal_driver added at c75ace
1 change: 1 addition & 0 deletions hw/mcu/st/stm32f3xx_hal_driver
Submodule stm32f3xx_hal_driver added at 1761b6
1 change: 1 addition & 0 deletions hw/mcu/st/stm32f4xx_hal_driver
Submodule stm32f4xx_hal_driver added at 04e99f
1 change: 1 addition & 0 deletions hw/mcu/st/stm32f7xx_hal_driver
Submodule stm32f7xx_hal_driver added at f7ffdf
1 change: 1 addition & 0 deletions hw/mcu/st/stm32g0xx_hal_driver
Submodule stm32g0xx_hal_driver added at e911b1
1 change: 1 addition & 0 deletions hw/mcu/st/stm32g4xx_hal_driver
Submodule stm32g4xx_hal_driver added at 8b4518
1 change: 1 addition & 0 deletions hw/mcu/st/stm32h5xx_hal_driver
Submodule stm32h5xx_hal_driver added at 2cf77d
1 change: 1 addition & 0 deletions hw/mcu/st/stm32h7xx_hal_driver
Submodule stm32h7xx_hal_driver added at d8461b
1 change: 1 addition & 0 deletions hw/mcu/st/stm32l0xx_hal_driver
Submodule stm32l0xx_hal_driver added at fbdaca
1 change: 1 addition & 0 deletions hw/mcu/st/stm32l1xx_hal_driver
Submodule stm32l1xx_hal_driver added at 44efc4
1 change: 1 addition & 0 deletions hw/mcu/st/stm32l4xx_hal_driver
Submodule stm32l4xx_hal_driver added at aee3d5
1 change: 1 addition & 0 deletions hw/mcu/st/stm32l5xx_hal_driver
Submodule stm32l5xx_hal_driver added at 675c32
1 change: 1 addition & 0 deletions hw/mcu/st/stm32u5xx_hal_driver
Submodule stm32u5xx_hal_driver added at 4d9309
1 change: 1 addition & 0 deletions hw/mcu/st/stm32wbxx_hal_driver
Submodule stm32wbxx_hal_driver added at 2c5f06
1 change: 1 addition & 0 deletions hw/mcu/ti
Submodule ti added at 143ed6
1 change: 1 addition & 0 deletions hw/mcu/wch/ch32f20x
Submodule ch32f20x added at 77c409
1 change: 1 addition & 0 deletions hw/mcu/wch/ch32v103
Submodule ch32v103 added at 7578ca
1 change: 1 addition & 0 deletions hw/mcu/wch/ch32v20x
Submodule ch32v20x added at c4c38f
1 change: 1 addition & 0 deletions hw/mcu/wch/ch32v307
Submodule ch32v307 added at 184f21
1 change: 1 addition & 0 deletions lib/CMSIS_5
Submodule CMSIS_5 added at 202852
1 change: 1 addition & 0 deletions lib/FreeRTOS-Kernel
Submodule FreeRTOS-Kernel added at cc0e07
1 change: 1 addition & 0 deletions lib/lwip
Submodule lwip added at 159e31
1 change: 1 addition & 0 deletions lib/sct_neopixel
Submodule sct_neopixel added at e73e04
2 changes: 1 addition & 1 deletion src/class/video/video_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
#ifdef TUP_DCD_EDPT_ISO_ALLOC
/* Allocate ISO endpoints */
uint16_t ep_size = 0;
uint16_t ep_addr = 0;
uint8_t ep_addr = 0;
uint8_t const *p_desc = (uint8_t const*)itf_desc + stm->desc.beg;
uint8_t const *p_desc_end = (uint8_t const*)itf_desc + stm->desc.end;
while (p_desc < p_desc_end) {
Expand Down
1 change: 1 addition & 0 deletions src/common/tusb_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@
// Raspberry Pi
//--------------------------------------------------------------------+
#elif TU_CHECK_MCU(OPT_MCU_RP2040)
#define TUP_DCD_EDPT_ISO_ALLOC
#define TUP_DCD_ENDPOINT_MAX 16

#define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb")))
Expand Down
113 changes: 87 additions & 26 deletions src/portable/raspberrypi/rp2040/dcd_rp2040.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,15 @@
// Note: won't work if change to 0 (for now)
#define FORCE_VBUS_DETECT 1


/*------------------------------------------------------------------*/
/* Low level controller
*------------------------------------------------------------------*/
static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type);
static void hw_set_endpoint_control_reg(struct hw_endpoint* ep, uint dpram_offset);

// Init these in dcd_init
static uint8_t* next_buffer_ptr;
static uint8_t* next_buffer_ptr = NULL;

// USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in.
static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2];
Expand All @@ -66,31 +69,83 @@ TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_addr(
return hw_endpoint_get_by_num(num, dir);
}

static void _hw_endpoint_alloc(struct hw_endpoint* ep, uint8_t transfer_type) {
// Allocate from the USB buffer space (max 3840 bytes)
static void hw_endpoint_alloc(struct hw_endpoint* ep, size_t size) {
static uint8_t *end;
// determine buffer end
if (end == NULL){
end = &usb_dpram->epx_data[0] + 0xF00;
}
// determine first next_buffer_ptr if necessary
if (next_buffer_ptr == NULL){
next_buffer_ptr = &usb_dpram->epx_data[0];
}
// assign buffer
ep->hw_data_buf = next_buffer_ptr;
next_buffer_ptr += size;

hard_assert(next_buffer_ptr < end);

pico_info(" Allocated %d bytes (0x%p)\r\n", size, ep->hw_data_buf);
}

// allocate endpoint and fill endpoint control registers
static void hw_endpoint_alloc_and_control(struct hw_endpoint* ep, uint8_t transfer_type) {
// size must be multiple of 64
uint size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u;

// double buffered Bulk endpoint
if (transfer_type == TUSB_XFER_BULK) {
size *= 2u;
}

ep->hw_data_buf = next_buffer_ptr;
next_buffer_ptr += size;

assert(((uintptr_t) next_buffer_ptr & 0b111111u) == 0);
ep->transfer_type = transfer_type;
hw_endpoint_alloc(ep, size);

uint dpram_offset = hw_data_offset(ep->hw_data_buf);
hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX);

pico_info(" Allocated %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf);

// Fill in endpoint control register with buffer offset
uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset;
hw_set_endpoint_control_reg(ep, dpram_offset);
}

static void hw_set_endpoint_control_reg(struct hw_endpoint* ep, uint dpram_offset) {
// Fill in endpoint control register with buffer offset
uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset;
*ep->endpoint_control = reg;
}

static void _hw_endpoint_close(struct hw_endpoint* ep) {

// New API: Allocate packet buffer used by ISO endpoints
// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
(void) rhport;
assert(rhport == 0);
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
// size must be multiple of 64
uint16_t size = (uint16_t)tu_div_ceil(largest_packet_size, 64) * 64u;
ep->wMaxPacketSize = size;
hw_endpoint_alloc(ep, size);
return true;
}

// New API: Configure and enable an ISO endpoint according to descriptor
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
(void) rhport;
assert(rhport == 0);
const uint8_t ep_addr = ep_desc->bEndpointAddress;
const uint16_t mps = ep_desc->wMaxPacketSize;
uint16_t size = (uint16_t)tu_div_ceil(mps, 64) * 64u;

// init w/o allocate
hw_endpoint_init(ep_addr, size, TUSB_XFER_ISOCHRONOUS);

// Fill in endpoint control register with buffer offset
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
uint dpram_offset = hw_data_offset(ep->hw_data_buf);
hw_set_endpoint_control_reg(ep, dpram_offset);
return true;
}

static void hw_endpoint_close(uint8_t ep_addr) {
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
// Clear hardware registers and then zero the struct
// Clears endpoint enable
*ep->endpoint_control = 0;
Expand All @@ -113,14 +168,22 @@ static void _hw_endpoint_close(struct hw_endpoint* ep) {
}
}

static void hw_endpoint_close(uint8_t ep_addr) {
// Legacy init called by dcd_init (which does allocation)
static void hw_endpoint_init_and_alloc(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
_hw_endpoint_close(ep);
uint16_t size = (uint16_t) tu_div_ceil(wMaxPacketSize, 64) * 64u;
// size must be multiple of 64
hw_endpoint_init(ep_addr, size, transfer_type);
const uint8_t num = tu_edpt_number(ep_addr);
if (num != 0) {
// alloc a buffer and fill in endpoint control register
hw_endpoint_alloc_and_control(ep, transfer_type);
}
}

// main processing for dcd_edpt_iso_activate
static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);

const uint8_t num = tu_edpt_number(ep_addr);
const tusb_dir_t dir = tu_edpt_dir(ep_addr);

Expand Down Expand Up @@ -156,9 +219,6 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t
} else {
ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out;
}

// alloc a buffer and fill in endpoint control register
_hw_endpoint_alloc(ep, transfer_type);
}
}

Expand Down Expand Up @@ -369,8 +429,8 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) {
#define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
#endif

bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
(void) rh_init;

void dcd_init(uint8_t rhport) {
assert(rhport == 0);

TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version());
Expand All @@ -387,8 +447,8 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {

// Init control endpoints
tu_memclr(hw_endpoints[0], 2 * sizeof(hw_endpoint_t));
hw_endpoint_init(0x0, 64, TUSB_XFER_CONTROL);
hw_endpoint_init(0x80, 64, TUSB_XFER_CONTROL);
hw_endpoint_init_and_alloc(0x0, 64, TUSB_XFER_CONTROL);
hw_endpoint_init_and_alloc(0x80, 64, TUSB_XFER_CONTROL);

// Init non-control endpoints
reset_non_control_endpoints();
Expand All @@ -406,7 +466,6 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
(FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS);

dcd_connect(rhport);
return true;
}

bool dcd_deinit(uint8_t rhport) {
Expand Down Expand Up @@ -483,6 +542,8 @@ void dcd_sof_enable(uint8_t rhport, bool en) {
/* DCD Endpoint port
*------------------------------------------------------------------*/



void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) {
(void) rhport;

Expand All @@ -495,7 +556,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* req

bool dcd_edpt_open(__unused uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) {
assert(rhport == 0);
hw_endpoint_init(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer);
hw_endpoint_init_and_alloc(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer);
return true;
}

Expand Down Expand Up @@ -551,4 +612,4 @@ void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) {
dcd_rp2040_irq();
}

#endif
#endif
1 change: 1 addition & 0 deletions tools/uf2
Submodule uf2 added at c59454

0 comments on commit 43e4f14

Please sign in to comment.