41 #if MODE_DEVICE_SUPPORTED && TUSB_CFG_MCU == MCU_LPC43XX
43 #define _TINY_USB_SOURCE_FILE_
59 #define DCD_QHD_MAX 12
60 #define DCD_QTD_MAX 12
61 #define DCD_QTD_PER_QHD_MAX 2 // maximum number of qtd that are linked into one queue head at a time
63 #define QTD_NEXT_INVALID 0x01
67 ENDPTCTRL_MASK_STALL =
BIT_(0),
68 ENDPTCTRL_MASK_TOGGLE_INHIBIT =
BIT_(5),
69 ENDPTCTRL_MASK_TOGGLE_RESET =
BIT_(6),
70 ENDPTCTRL_MASK_ENABLE =
BIT_(7)
75 USBCMD_MASK_RUN_STOP =
BIT_(0),
76 USBCMD_MASK_RESET =
BIT_(1),
77 USBCMD_MASK_SETUP_TRIPWIRE =
BIT_(13),
78 USBCMD_MASK_ADD_QTD_TRIPWIRE =
BIT_(14)
84 INT_MASK_USB =
BIT_(0),
85 INT_MASK_ERROR =
BIT_(1),
86 INT_MASK_PORT_CHANGE =
BIT_(2),
87 INT_MASK_RESET =
BIT_(6),
88 INT_MASK_SOF =
BIT_(7),
89 INT_MASK_SUSPEND =
BIT_(8),
90 INT_MASK_NAK =
BIT_(16)
95 PORTSC_CURRENT_CONNECT_STATUS_MASK =
BIT_(0),
96 PORTSC_FORCE_PORT_RESUME_MASK =
BIT_(6),
97 PORTSC_SUSPEND_MASK =
BIT_(7)
107 volatile uint32_t xact_err : 1 ;
109 volatile uint32_t buffer_err : 1 ;
110 volatile uint32_t halted : 1 ;
111 volatile uint32_t active : 1 ;
113 uint32_t iso_mult_override : 2 ;
115 uint32_t int_on_complete : 1 ;
116 volatile uint32_t total_bytes : 15 ;
123 uint16_t expected_bytes;
128 STATIC_ASSERT(
sizeof(dcd_qtd_t) == 32,
"size is not correct");
133 uint32_t int_on_setup : 1 ;
134 uint32_t max_package_size : 11 ;
136 uint32_t zero_length_termination : 1 ;
137 uint32_t iso_mult : 2 ;
141 volatile uint32_t qtd_addr;
144 volatile dcd_qtd_t qtd_overlay;
154 uint8_t list_qtd_idx[DCD_QTD_PER_QHD_MAX];
156 uint8_t reserved[15-DCD_QTD_PER_QHD_MAX];
159 STATIC_ASSERT(
sizeof(dcd_qhd_t) == 64,
"size is not correct");
165 dcd_qhd_t qhd[DCD_QHD_MAX];
170 #if (TUSB_CFG_CONTROLLER_0_MODE & TUSB_MODE_DEVICE)
174 #if (TUSB_CFG_CONTROLLER_1_MODE & TUSB_MODE_DEVICE)
178 static LPC_USB0_Type *
const LPC_USB[2] = { LPC_USB0, ((LPC_USB0_Type*) LPC_USB1_BASE) };
179 static dcd_data_t*
const dcd_data_ptr[2] =
181 #if (TUSB_CFG_CONTROLLER_0_MODE & TUSB_MODE_DEVICE)
187 #if (TUSB_CFG_CONTROLLER_1_MODE & TUSB_MODE_DEVICE)
197 void dcd_controller_connect(uint8_t coreid)
199 LPC_USB[coreid]->USBCMD_D |=
BIT_(0);
202 void dcd_controller_set_address(uint8_t coreid, uint8_t dev_addr)
204 LPC_USB[coreid]->DEVICEADDR = (dev_addr << 25) |
BIT_(24);
207 void dcd_controller_set_configuration(uint8_t coreid)
213 static void bus_reset(uint8_t coreid)
215 LPC_USB0_Type*
const lpc_usb = LPC_USB[coreid];
222 lpc_usb->ENDPTCTRL1 = lpc_usb->ENDPTCTRL2 = lpc_usb->ENDPTCTRL3 =
223 (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18);
228 lpc_usb->ENDPTCTRL4 = lpc_usb->ENDPTCTRL5 = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18);
232 lpc_usb->ENDPTNAK = lpc_usb->ENDPTNAK;
233 lpc_usb->ENDPTNAKEN = 0;
234 lpc_usb->USBSTS_D = lpc_usb->USBSTS_D;
235 lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;
236 lpc_usb->ENDPTCOMPLETE = lpc_usb->ENDPTCOMPLETE;
238 while (lpc_usb->ENDPTPRIME);
239 lpc_usb->ENDPTFLUSH = 0xFFFFFFFF;
240 while (lpc_usb->ENDPTFLUSH);
245 dcd_data_t* p_dcd = dcd_data_ptr[coreid];
247 memclr_(p_dcd,
sizeof(dcd_data_t));
250 p_dcd->qhd[0].zero_length_termination = p_dcd->qhd[1].zero_length_termination = 1;
252 p_dcd->qhd[0].qtd_overlay.next = p_dcd->qhd[1].qtd_overlay.next = QTD_NEXT_INVALID;
254 p_dcd->qhd[0].int_on_setup = 1;
258 static void lpc43xx_controller_init(uint8_t coreid)
260 LPC_USB0_Type*
const lpc_usb = LPC_USB[coreid];
261 dcd_data_t* p_dcd = dcd_data_ptr[coreid];
263 memclr_(p_dcd,
sizeof(dcd_data_t));
265 lpc_usb->ENDPOINTLISTADDR = (uint32_t) p_dcd->qhd;
266 lpc_usb->USBSTS_D = lpc_usb->USBSTS_D;
267 lpc_usb->USBINTR_D = INT_MASK_USB | INT_MASK_ERROR | INT_MASK_PORT_CHANGE | INT_MASK_RESET | INT_MASK_SUSPEND;
269 lpc_usb->USBCMD_D &= ~0x00FF0000;
270 lpc_usb->USBCMD_D |=
BIT_(0);
275 #if (TUSB_CFG_CONTROLLER_0_MODE & TUSB_MODE_DEVICE)
276 lpc43xx_controller_init(0);
279 #if (TUSB_CFG_CONTROLLER_1_MODE & TUSB_MODE_DEVICE)
280 lpc43xx_controller_init(1);
283 return TUSB_ERROR_NONE;
291 static inline uint8_t edpt_pos2phy(uint8_t pos)
293 return (pos < DCD_QHD_MAX/2) ? (2*pos) : (2*(pos-16)+1);
298 static inline uint8_t edpt_phy2pos(uint8_t physical_endpoint)
300 return physical_endpoint/2 + ( (physical_endpoint%2) ? 16 : 0);
304 static inline uint8_t edpt_addr2phy(uint8_t endpoint_addr)
306 return 2*(endpoint_addr & 0x0F) + ((endpoint_addr & TUSB_DIR_DEV_TO_HOST_MASK) ? 1 : 0);
310 static inline uint8_t edpt_phy2log(uint8_t physical_endpoint)
312 return physical_endpoint/2;
315 static void qtd_init(dcd_qtd_t* p_qtd,
void * data_ptr, uint16_t total_bytes)
317 memclr_(p_qtd,
sizeof(dcd_qtd_t));
321 p_qtd->next = QTD_NEXT_INVALID;
323 p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes;
325 if (data_ptr != NULL)
327 p_qtd->buffer[0] = (uint32_t) data_ptr;
328 for(uint8_t i=1; i<5; i++)
330 p_qtd->buffer[i] |= align4k( p_qtd->buffer[i-1] ) + 4096;
337 static inline uint8_t qtd_find_free(uint8_t coreid)
339 for(uint8_t i=2; i<DCD_QTD_MAX; i++)
341 if ( dcd_data_ptr[coreid]->qtd[i].used == 0)
return i;
350 void dcd_pipe_control_stall(uint8_t coreid)
352 LPC_USB[coreid]->ENDPTCTRL0 |= (ENDPTCTRL_MASK_STALL << 16);
356 tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length,
bool int_on_complete)
358 LPC_USB0_Type*
const lpc_usb = LPC_USB[coreid];
359 dcd_data_t*
const p_dcd = dcd_data_ptr[coreid];
362 uint8_t
const ep_data = (dir == TUSB_DIR_DEV_TO_HOST) ? 1 : 0;
363 uint8_t
const ep_status = 1 - ep_data;
365 ASSERT_FALSE(p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active, TUSB_ERROR_FAILED);
370 dcd_qtd_t* p_qtd_data = &p_dcd->qtd[0];
371 qtd_init(p_qtd_data, p_buffer, length);
372 p_dcd->qhd[ep_data].qtd_overlay.next = (uint32_t) p_qtd_data;
374 lpc_usb->ENDPTPRIME =
BIT_(edpt_phy2pos(ep_data));
378 dcd_qtd_t* p_qtd_status = &p_dcd->qtd[1];
379 qtd_init(p_qtd_status, NULL, 0);
380 p_qtd_status->int_on_complete = int_on_complete ? 1 : 0;
382 p_dcd->qhd[ep_status].qtd_overlay.next = (uint32_t) p_qtd_status;
384 LPC_USB0->ENDPTPRIME =
BIT_(edpt_phy2pos(ep_status));
386 return TUSB_ERROR_NONE;
393 static inline volatile uint32_t * get_reg_control_addr(uint8_t coreid, uint8_t physical_endpoint)
395 return &(LPC_USB[coreid]->ENDPTCTRL0) + edpt_phy2log(physical_endpoint);
400 volatile uint32_t * reg_control = get_reg_control_addr(edpt_hdl.coreid, edpt_hdl.index);
402 (*reg_control) |= ENDPTCTRL_MASK_STALL << (edpt_hdl.index & 0x01 ? 16 : 0);
404 return TUSB_ERROR_NONE;
407 tusb_error_t dcd_pipe_clear_stall(uint8_t coreid, uint8_t edpt_addr)
409 volatile uint32_t * reg_control = get_reg_control_addr(coreid, edpt_addr2phy(edpt_addr));
412 (*reg_control) |= ENDPTCTRL_MASK_TOGGLE_RESET << ((edpt_addr & TUSB_DIR_DEV_TO_HOST_MASK) ? 16 : 0);
413 (*reg_control) &= ~(ENDPTCTRL_MASK_STALL << ((edpt_addr & TUSB_DIR_DEV_TO_HOST_MASK) ? 16 : 0));
415 return TUSB_ERROR_NONE;
423 if (p_endpoint_desc->
bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
426 tusb_direction_t dir = (p_endpoint_desc->
bEndpointAddress & TUSB_DIR_DEV_TO_HOST_MASK) ? TUSB_DIR_DEV_TO_HOST : TUSB_DIR_HOST_TO_DEV;
430 dcd_qhd_t * p_qhd = &dcd_data_ptr[coreid]->qhd[ep_idx];
432 memclr_(p_qhd,
sizeof(dcd_qhd_t));
434 p_qhd->class_code = class_code;
435 p_qhd->zero_length_termination = 1;
436 p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.
size;
437 p_qhd->qtd_overlay.next = QTD_NEXT_INVALID;
440 volatile uint32_t * reg_control = get_reg_control_addr(coreid, ep_idx);
442 ASSERT_FALSE( (*reg_control) & (ENDPTCTRL_MASK_ENABLE << (dir ? 16 : 0)), null_handle );
443 (*reg_control) |= ((p_endpoint_desc->
bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0);
449 .class_code = class_code
455 dcd_qhd_t* p_qhd = &dcd_data_ptr[edpt_hdl.coreid]->qhd[edpt_hdl.index];
458 return !p_qhd->qtd_overlay.halted && p_qhd->qtd_overlay.active;
464 uint8_t qtd_idx = qtd_find_free(edpt_hdl.coreid);
465 ASSERT(qtd_idx != 0, TUSB_ERROR_DCD_NOT_ENOUGH_QTD);
467 dcd_data_t* p_dcd = dcd_data_ptr[edpt_hdl.coreid];
468 dcd_qhd_t * p_qhd = &p_dcd->qhd[edpt_hdl.index];
469 dcd_qtd_t * p_qtd = &p_dcd->qtd[qtd_idx];
473 for(free_slot=0; free_slot < DCD_QTD_PER_QHD_MAX; free_slot++)
475 if ( p_qhd->list_qtd_idx[free_slot] == 0 )
break;
477 ASSERT(free_slot < DCD_QTD_PER_QHD_MAX, TUSB_ERROR_DCD_NOT_ENOUGH_QTD);
479 p_qhd->list_qtd_idx[free_slot] = qtd_idx;
482 qtd_init(p_qtd, buffer, total_bytes);
483 p_qtd->int_on_complete = int_on_complete;
485 if ( free_slot > 0 ) p_dcd->qtd[ p_qhd->list_qtd_idx[free_slot-1] ].next = (uint32_t) p_qtd;
487 return TUSB_ERROR_NONE;
492 return pipe_add_xfer( edpt_hdl, buffer, total_bytes,
false);
497 ASSERT_STATUS ( pipe_add_xfer(edpt_hdl, buffer, total_bytes, int_on_complete) );
499 dcd_qhd_t* p_qhd = &dcd_data_ptr[edpt_hdl.coreid]->qhd[ edpt_hdl.index ];
500 dcd_qtd_t* p_qtd = &dcd_data_ptr[edpt_hdl.coreid]->qtd[ p_qhd->list_qtd_idx[0] ];
502 p_qhd->qtd_overlay.next = (uint32_t) p_qtd;
504 LPC_USB[edpt_hdl.coreid]->ENDPTPRIME =
BIT_( edpt_phy2pos(edpt_hdl.index) ) ;
506 return TUSB_ERROR_NONE;
510 void xfer_complete_isr(uint8_t coreid, uint32_t reg_complete)
512 for(uint8_t ep_idx = 2; ep_idx < DCD_QHD_MAX; ep_idx++)
514 if (
BIT_TEST_(reg_complete, edpt_phy2pos(ep_idx)) )
516 dcd_qhd_t * p_qhd = &dcd_data_ptr[coreid]->qhd[ep_idx];
522 .class_code = p_qhd->class_code
526 while( p_qhd->list_qtd_idx[0] != 0 )
528 dcd_qtd_t * p_qtd = &dcd_data_ptr[coreid]->qtd[ p_qhd->list_qtd_idx[0] ];
530 if (p_qtd->active)
break;
534 memmove(p_qhd->list_qtd_idx, p_qhd->list_qtd_idx+1, DCD_QTD_PER_QHD_MAX-1);
535 p_qhd->list_qtd_idx[DCD_QTD_PER_QHD_MAX-1]=0;
537 if (p_qtd->int_on_complete)
539 tusb_event_t
event = ( p_qtd->xact_err || p_qtd->halted || p_qtd->buffer_err ) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_COMPLETE;
540 usbd_xfer_isr(edpt_hdl, event, p_qtd->expected_bytes - p_qtd->total_bytes);
547 void dcd_isr(uint8_t coreid)
549 LPC_USB0_Type*
const lpc_usb = LPC_USB[coreid];
551 uint32_t
const int_enable = lpc_usb->USBINTR_D;
552 uint32_t
const int_status = lpc_usb->USBSTS_D & int_enable;
553 lpc_usb->USBSTS_D = int_status;
555 if (int_status == 0)
return;
557 if (int_status & INT_MASK_RESET)
560 usbd_dcd_bus_event_isr(0, USBD_BUS_EVENT_RESET);
563 if (int_status & INT_MASK_SUSPEND)
565 if (lpc_usb->PORTSC1_D & PORTSC_SUSPEND_MASK)
567 if ((lpc_usb->DEVICEADDR >> 25) & 0x0f)
569 usbd_dcd_bus_event_isr(0, USBD_BUS_EVENT_SUSPENDED);
583 if (int_status & INT_MASK_USB)
585 uint32_t
const edpt_complete = lpc_usb->ENDPTCOMPLETE;
586 lpc_usb->ENDPTCOMPLETE = edpt_complete;
588 dcd_data_t*
const p_dcd = dcd_data_ptr[coreid];
591 if (lpc_usb->ENDPTSETUPSTAT)
594 lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;
596 usbd_setup_received_isr(coreid, &control_request);
599 else if ( edpt_complete & 0x03 )
601 for(uint8_t ep_idx = 0; ep_idx < 2; ep_idx++)
603 if (
BIT_TEST_(edpt_complete, edpt_phy2pos(ep_idx)) )
606 dcd_qtd_t
volatile *
const p_qtd = &p_dcd->qhd[ep_idx].qtd_overlay;
608 if ( p_qtd->int_on_complete )
616 tusb_event_t
event = ( p_qtd->xact_err || p_qtd->halted || p_qtd->buffer_err ) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_COMPLETE;
618 usbd_xfer_isr(edpt_hdl, event, 0);
625 if ( edpt_complete & ~(0x03UL) )
627 xfer_complete_isr(coreid, edpt_complete);
631 if (int_status & INT_MASK_SOF) {}
632 if (int_status & INT_MASK_NAK) {}
633 if (int_status & INT_MASK_ERROR) ASSERT(
false, VOID_RETURN);
#define BIT_TEST_(x, n)
check if n-th bit of x is 1
#define ATTR_PURE
Many functions have no effects except the return value and their return value depends only on the par...
struct tusb_descriptor_endpoint_t::@8 bmAttributes
This field describes the endpoint's attributes when it is configured using the bConfigurationValue. Bits 1..0: Transfer Type - 00 = Control - 01 = Isochronous - 10 = Bulk - 11 = Interrupt If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: Bits 3..2: Synchronization Type - 00 = No Synchronization - 01 = Asynchronous - 10 = Adaptive - 11 = Synchronous Bits 5..4: Usage Type - 00 = Data endpoint - 01 = Feedback endpoint - 10 = Implicit feedback Data endpoint - 11 = Reserved Refer to Chapter 5 of USB 2.0 specification for more information. All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host.
#define TUSB_CFG_ATTR_USBRAM
USB Standard Endpoint Descriptor (section 9.6.1 table 9-13)
tusb_error_t
Error Code returned.
#define ATTR_ALIGNED(Bytes)
This attribute specifies a minimum alignment for the variable or structure field, measured in bytes...
#define ATTR_ALWAYS_INLINE
Generally, functions are not inlined unless optimization is specified. For functions declared inline...
#define ATTR_CONST
Many functions do not examine any values except their arguments, and have no effects except the retur...
#define TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE
Max packet size of Cotnrol Endpoint, default is 64.
uint16_t size
Maximum packet size this endpoint is capable of sending or receiving when this configuration is selec...
uint8_t bEndpointAddress
The address of the endpoint on the USB device described by this descriptor. The address is encoded as...