Skip to content

Commit 7f61a5a

Browse files
committed
made change per reviews, remove dcd_edpt_close(), rename and move thing around
1 parent c514a8c commit 7f61a5a

File tree

2 files changed

+55
-113
lines changed

2 files changed

+55
-113
lines changed

src/common/tusb_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { retur
177177

178178
//------------- Mathematics -------------//
179179
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return TU_DIV_CEIL(v, d); }
180+
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_round_up(uint32_t v, uint32_t f) { return tu_div_ceil(v, f) * f; }
180181

181182
// log2 of a value is its MSB's position
182183
// TODO use clz TODO remove

src/portable/raspberrypi/rp2040/dcd_rp2040.c

Lines changed: 54 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,8 @@
4646
/*------------------------------------------------------------------*/
4747
/* Low level controller
4848
*------------------------------------------------------------------*/
49-
static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type);
50-
static void hw_set_endpoint_control_reg(struct hw_endpoint* ep, uint dpram_offset);
51-
5249
// Init these in dcd_init
53-
static uint8_t* next_buffer_ptr = NULL;
50+
static uint8_t* next_buffer_ptr;
5451

5552
// USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in.
5653
static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2];
@@ -70,115 +67,28 @@ TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_addr(
7067

7168
// Allocate from the USB buffer space (max 3840 bytes)
7269
static void hw_endpoint_alloc(struct hw_endpoint* ep, size_t size) {
73-
static uint8_t *end;
74-
// determine buffer end
75-
if (end == NULL){
76-
end = &usb_dpram->epx_data[0] + 0xF00;
77-
}
78-
// determine first next_buffer_ptr if necessary
79-
if (next_buffer_ptr == NULL){
80-
next_buffer_ptr = &usb_dpram->epx_data[0];
81-
}
82-
// assign buffer
83-
ep->hw_data_buf = next_buffer_ptr;
84-
next_buffer_ptr += size;
85-
86-
hard_assert(next_buffer_ptr < end);
87-
88-
pico_info(" Allocated %d bytes (0x%p)\r\n", size, ep->hw_data_buf);
89-
}
70+
// round up size to multiple of 64
71+
size = tu_round_up(ep->wMaxPacketSize, 64);
9072

91-
// allocate endpoint and fill endpoint control registers
92-
static void hw_endpoint_alloc_and_control(struct hw_endpoint* ep, uint8_t transfer_type) {
93-
// size must be multiple of 64
94-
uint size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u;
9573
// double buffered Bulk endpoint
96-
if (transfer_type == TUSB_XFER_BULK) {
74+
if (ep->transfer_type == TUSB_XFER_BULK) {
9775
size *= 2u;
9876
}
99-
ep->transfer_type = transfer_type;
100-
hw_endpoint_alloc(ep, size);
10177

102-
uint dpram_offset = hw_data_offset(ep->hw_data_buf);
103-
pico_info(" Allocated %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf);
78+
// assign buffer
79+
ep->hw_data_buf = next_buffer_ptr;
80+
next_buffer_ptr += size;
10481

105-
hw_set_endpoint_control_reg(ep, dpram_offset);
82+
hard_assert(next_buffer_ptr < usb_dpram->epx_data + sizeof(usb_dpram->epx_data));
83+
pico_info(" Allocated %d bytes (0x%p)\r\n", size, ep->hw_data_buf);
10684
}
10785

108-
static void hw_set_endpoint_control_reg(struct hw_endpoint* ep, uint dpram_offset) {
109-
// Fill in endpoint control register with buffer offset
110-
uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset;
86+
// Enable endpoint
87+
TU_ATTR_ALWAYS_INLINE static inline void hw_endpoint_enable(struct hw_endpoint* ep) {
88+
uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) ep->transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf);
11189
*ep->endpoint_control = reg;
11290
}
11391

114-
// New API: Allocate packet buffer used by ISO endpoints
115-
// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering
116-
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
117-
(void) rhport;
118-
assert(rhport == 0);
119-
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
120-
// size must be multiple of 64
121-
uint16_t size = (uint16_t)tu_div_ceil(largest_packet_size, 64) * 64u;
122-
ep->wMaxPacketSize = size;
123-
hw_endpoint_alloc(ep, size);
124-
return true;
125-
}
126-
127-
// New API: Configure and enable an ISO endpoint according to descriptor
128-
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
129-
(void) rhport;
130-
assert(rhport == 0);
131-
const uint8_t ep_addr = ep_desc->bEndpointAddress;
132-
const uint16_t mps = ep_desc->wMaxPacketSize;
133-
uint16_t size = (uint16_t)tu_div_ceil(mps, 64) * 64u;
134-
135-
// init w/o allocate
136-
hw_endpoint_init(ep_addr, size, TUSB_XFER_ISOCHRONOUS);
137-
138-
// Fill in endpoint control register with buffer offset
139-
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
140-
uint dpram_offset = hw_data_offset(ep->hw_data_buf);
141-
hw_set_endpoint_control_reg(ep, dpram_offset);
142-
return true;
143-
}
144-
145-
static void hw_endpoint_close(uint8_t ep_addr) {
146-
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
147-
// Clear hardware registers and then zero the struct
148-
// Clears endpoint enable
149-
*ep->endpoint_control = 0;
150-
// Clears buffer available, etc
151-
*ep->buffer_control = 0;
152-
// Clear any endpoint state
153-
memset(ep, 0, sizeof(struct hw_endpoint));
154-
155-
// Reclaim buffer space if all endpoints are closed
156-
bool reclaim_buffers = true;
157-
for (uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++) {
158-
if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL ||
159-
hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) {
160-
reclaim_buffers = false;
161-
break;
162-
}
163-
}
164-
if (reclaim_buffers) {
165-
next_buffer_ptr = &usb_dpram->epx_data[0];
166-
}
167-
}
168-
169-
// Legacy init called by dcd_init (which does allocation)
170-
static void hw_endpoint_init_and_alloc(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
171-
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
172-
uint16_t size = (uint16_t) tu_div_ceil(wMaxPacketSize, 64) * 64u;
173-
// size must be multiple of 64
174-
hw_endpoint_init(ep_addr, size, transfer_type);
175-
const uint8_t num = tu_edpt_number(ep_addr);
176-
if (num != 0) {
177-
// alloc a buffer and fill in endpoint control register
178-
hw_endpoint_alloc_and_control(ep, transfer_type);
179-
}
180-
}
181-
18292
// main processing for dcd_edpt_iso_activate
18393
static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
18494
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
@@ -221,6 +131,18 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t
221131
}
222132
}
223133

134+
// Init, allocate buffer and enable endpoint
135+
static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) {
136+
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
137+
hw_endpoint_init(ep_addr, wMaxPacketSize, transfer_type);
138+
const uint8_t num = tu_edpt_number(ep_addr);
139+
if (num != 0) {
140+
// EP0 is already enabled
141+
hw_endpoint_alloc(ep, ep->wMaxPacketSize);
142+
hw_endpoint_enable(ep);
143+
}
144+
}
145+
224146
static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) {
225147
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
226148
hw_endpoint_xfer_start(ep, buffer, total_bytes);
@@ -446,8 +368,8 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
446368

447369
// Init control endpoints
448370
tu_memclr(hw_endpoints[0], 2 * sizeof(hw_endpoint_t));
449-
hw_endpoint_init_and_alloc(0x0, 64, TUSB_XFER_CONTROL);
450-
hw_endpoint_init_and_alloc(0x80, 64, TUSB_XFER_CONTROL);
371+
hw_endpoint_open(0x0, 64, TUSB_XFER_CONTROL);
372+
hw_endpoint_open(0x80, 64, TUSB_XFER_CONTROL);
451373

452374
// Init non-control endpoints
453375
reset_non_control_endpoints();
@@ -552,9 +474,34 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* req
552474
}
553475
}
554476

555-
bool dcd_edpt_open(__unused uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) {
556-
assert(rhport == 0);
557-
hw_endpoint_init_and_alloc(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer);
477+
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) {
478+
(void) rhport;
479+
const uint8_t xfer_type = desc_edpt->bmAttributes.xfer;
480+
TU_VERIFY(xfer_type != TUSB_XFER_ISOCHRONOUS);
481+
hw_endpoint_open(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), xfer_type);
482+
return true;
483+
}
484+
485+
// New API: Allocate packet buffer used by ISO endpoints
486+
// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering
487+
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
488+
(void) rhport;
489+
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
490+
hw_endpoint_init(ep_addr, largest_packet_size, TUSB_XFER_ISOCHRONOUS);
491+
hw_endpoint_alloc(ep, largest_packet_size);
492+
return true;
493+
}
494+
495+
// New API: Configure and enable an ISO endpoint according to descriptor
496+
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
497+
(void) rhport;
498+
const uint8_t ep_addr = ep_desc->bEndpointAddress;
499+
// Fill in endpoint control register with buffer offset
500+
struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr);
501+
TU_ASSERT(ep->hw_data_buf != NULL); // must be inited and buffer allocated
502+
ep->wMaxPacketSize = ep_desc->wMaxPacketSize;
503+
504+
hw_endpoint_enable(ep);
558505
return true;
559506
}
560507

@@ -599,12 +546,6 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
599546
}
600547
}
601548

602-
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
603-
(void) rhport;
604-
pico_trace("dcd_edpt_close %02x\r\n", ep_addr);
605-
hw_endpoint_close(ep_addr);
606-
}
607-
608549
void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) {
609550
(void) rhport;
610551
dcd_rp2040_irq();

0 commit comments

Comments
 (0)