diff --git a/demos/device/device_os_none/cdcd_app.c b/demos/device/device_os_none/cdcd_app.c index 1500d1497..def783435 100644 --- a/demos/device/device_os_none/cdcd_app.c +++ b/demos/device/device_os_none/cdcd_app.c @@ -46,7 +46,7 @@ // INCLUDE //--------------------------------------------------------------------+ enum { - CDCD_APP_BUFFER_SIZE = 16 + CDCD_APP_BUFFER_SIZE = 64 }; //--------------------------------------------------------------------+ diff --git a/demos/device/device_os_none/tusb_descriptors.h b/demos/device/device_os_none/tusb_descriptors.h index 022ea50bc..b69c8e590 100644 --- a/demos/device/device_os_none/tusb_descriptors.h +++ b/demos/device/device_os_none/tusb_descriptors.h @@ -44,25 +44,28 @@ //--------------------------------------------------------------------+ // Endpoints Address & Max Packet Size //--------------------------------------------------------------------+ -//------------- CDC -------------// -#define CDC_EDPT_NOTIFICATION_ADDR ENDPOINT_IN_LOGICAL_TO_PHYSICAL(2) -#define CDC_EDPT_NOTIFICATION_PACKETSIZE 64 +#define EDPT_IN(x) (0x80 | x) +#define EDPT_OUT(x) (x) -#define CDC_EDPT_DATA_OUT ENDPOINT_OUT_LOGICAL_TO_PHYSICAL(3) -#define CDC_EDPT_DATA_IN ENDPOINT_IN_LOGICAL_TO_PHYSICAL(3) -#define CDC_EDPT_DATA_PACKETSIZE 64 +//------------- CDC -------------// +#define CDC_EDPT_NOTIFICATION_ADDR EDPT_IN(1) +#define CDC_EDPT_NOTIFICATION_PACKETSIZE 64 + +#define CDC_EDPT_DATA_OUT EDPT_OUT(2) +#define CDC_EDPT_DATA_IN EDPT_IN(2) +#define CDC_EDPT_DATA_PACKETSIZE 64 //------------- HID Keyboard -------------// -#define HID_EDPT_KEYBOARD_ADDR ENDPOINT_IN_LOGICAL_TO_PHYSICAL(1) +#define HID_EDPT_KEYBOARD_ADDR EDPT_IN(3) //------------- HID Mouse -------------// -#define HID_MOUSE_EP_IN ENDPOINT_IN_LOGICAL_TO_PHYSICAL(4) +#define HID_MOUSE_EP_IN EDPT_IN(4) //------------- HID Generic -------------// //------------- Mass Storage -------------// -#define MSC_EDPT_IN ENDPOINT_IN_LOGICAL_TO_PHYSICAL(3) -#define MSC_EDPT_OUT ENDPOINT_OUT_LOGICAL_TO_PHYSICAL(3) +#define MSC_EDPT_IN EDPT_IN(3) +#define MSC_EDPT_OUT EDPT_OUT(3) //--------------------------------------------------------------------+ diff --git a/tinyusb/device/dcd_lpc175x_6x.c b/tinyusb/device/dcd_lpc175x_6x.c index a2910fc2f..1be282ae5 100644 --- a/tinyusb/device/dcd_lpc175x_6x.c +++ b/tinyusb/device/dcd_lpc175x_6x.c @@ -52,31 +52,28 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -STATIC_ ATTR_ALIGNED(128) dcd_dma_descriptor_t* dcd_udca[32] TUSB_CFG_ATTR_USBRAM; -STATIC_ dcd_dma_descriptor_t dcd_dd[DCD_MAX_DD]; +#define DCD_QHD_MAX 32 +#define DCD_QTD_MAX 32 // TODO scale with configure + +typedef struct { + volatile ATTR_ALIGNED(128) dcd_dma_descriptor_t* udca[DCD_QHD_MAX]; + dcd_dma_descriptor_t dd[DCD_QTD_MAX]; + + uint8_t ddat[DCD_QHD_MAX]; ///< DMA Descriptor Allocation Table. A fixed DD will be allocated for a UDCA pointer up on endpoint open + uint8_t class_code[DCD_QHD_MAX]; + +}dcd_data_t; + +STATIC_ dcd_data_t dcd_data TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static void bus_reset(void); -static inline void endpoint_set_max_packet_size(uint8_t endpoint_idx, uint16_t max_packet_size) ATTR_ALWAYS_INLINE; -static inline void endpoint_set_max_packet_size(uint8_t endpoint_idx, uint16_t max_packet_size) -{ - LPC_USB->USBReEp |= BIT_(endpoint_idx); - LPC_USB->USBEpInd = endpoint_idx; // select index before setting packet size - LPC_USB->USBMaxPSize = max_packet_size; - -#ifndef _TEST_ - if( endpoint_idx > 2) // endpoint control is always realized - { - while ((LPC_USB->USBDevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {} // TODO can be omitted, or move to set max packet size - LPC_USB->USBDevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK; - } -#endif - -} - +//--------------------------------------------------------------------+ +// SIE Command +//--------------------------------------------------------------------+ static inline void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data) ATTR_ALWAYS_INLINE; static inline void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data) { @@ -110,22 +107,44 @@ static inline uint32_t sie_read (uint8_t cmd_code, uint8_t data_len) return LPC_USB->USBCmdData; } +static inline void edpt_set_max_packet_size(uint8_t ep_id, uint16_t max_packet_size) ATTR_ALWAYS_INLINE; +static inline void edpt_set_max_packet_size(uint8_t ep_id, uint16_t max_packet_size) +{ // follows example in 11.10.4.2 + LPC_USB->USBReEp |= BIT_(ep_id); + LPC_USB->USBEpInd = ep_id; // select index before setting packet size + LPC_USB->USBMaxPSize = max_packet_size; + +#ifndef _TEST_ + if( ep_id > 2) // endpoint control is always realized + { + while ((LPC_USB->USBDevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {} // TODO can be omitted, or move to set max packet size + LPC_USB->USBDevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK; + } +#endif + +} + +static inline dcd_dma_descriptor_t* qhd_get_fixed_dd(uint8_t ep_id) ATTR_PURE ATTR_ALWAYS_INLINE; +static inline dcd_dma_descriptor_t* qhd_get_fixed_dd(uint8_t ep_id) +{ + return &dcd_data.dd[ dcd_data.ddat[ep_id] ]; +} + static tusb_error_t pipe_control_write(void const * buffer, uint16_t length); static tusb_error_t pipe_control_read(void * buffer, uint16_t length); //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ -void endpoint_control_isr(uint8_t coreid) +void endpoint_control_isr(void) { - (void) coreid; // suppress compiler warning uint32_t const endpoint_int_status = LPC_USB->USBEpIntSt & LPC_USB->USBEpIntEn; //------------- control OUT -------------// if (endpoint_int_status & BIT_(0)) { uint32_t const endpoint_status = sie_read(SIE_CMDCODE_ENDPOINT_SELECT+0, 1); - if (endpoint_status & SIE_ENDPOINT_STATUS_SETUP_RECEIVED_MASK) + if (endpoint_status & SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK) { tusb_control_request_t control_request; @@ -137,7 +156,6 @@ void endpoint_control_isr(uint8_t coreid) }else { // Current not support any out control with data yet -// pipe_control_read(0,.. } sie_write(SIE_CMDCODE_ENDPOINT_SELECT+0, 0, 0); sie_write(SIE_CMDCODE_BUFFER_CLEAR , 0, 0); @@ -146,10 +164,16 @@ void endpoint_control_isr(uint8_t coreid) //------------- control IN -------------// if (endpoint_int_status & BIT_(1)) { - (void) endpoint_int_status; + endpoint_handle_t edpt_hdl = + { + .index = 1 //BIT_TEST_(int_status, 1) ? 1 : 0 + }; + + // FIXME xferred_byte for control xfer is not needed now !!! + usbd_xfer_isr(edpt_hdl, TUSB_EVENT_XFER_COMPLETE, 0); } - LPC_USB->USBEpIntClr = endpoint_int_status; // acknowledge interrupt + LPC_USB->USBEpIntClr = endpoint_int_status; // acknowledge interrupt TODO cannot immediately acknowledge setup packet } void dcd_isr(uint8_t coreid) @@ -173,20 +197,59 @@ void dcd_isr(uint8_t coreid) } } - //------------- slave mode, control endpoint -------------// + //------------- Control Endpoint (Slave Mode) -------------// if (device_int_status & DEV_INT_ENDPOINT_SLOW_MASK) { // only occur on control endpoint, all other use DMA - endpoint_control_isr(coreid); + endpoint_control_isr(); } - if (device_int_status & DEV_INT_ERROR_MASK) + //------------- Non-Control Endpoint (DMA Mode) -------------// + uint32_t dma_int_status = LPC_USB->USBDMAIntSt & LPC_USB->USBDMAIntEn; + + if (dma_int_status & DMA_INT_END_OF_XFER_MASK) + { + uint32_t eot_int = LPC_USB->USBEoTIntSt; + LPC_USB->USBEoTIntClr = eot_int; // acknowledge interrupt source + + for(uint8_t ep_id = 2; ep_id < DCD_QHD_MAX; ep_id++ ) + { + if ( BIT_TEST_(eot_int, ep_id) ) + { + dcd_dma_descriptor_t* p_dd; + dcd_dma_descriptor_t* const p_fixed_dd = qhd_get_fixed_dd(ep_id); + + p_fixed_dd->buffer_length = 0; // buffer length is used to determined if fixed dd is queued in pipe xfer function + + // Maximum is 2 QTD are queued in an endpoint + if (p_fixed_dd->is_next_valid) + { + p_dd = (dcd_dma_descriptor_t*) p_fixed_dd->next; + p_dd->used = 0; // free non-fixed dd + }else + { + p_dd = p_fixed_dd; + } + + endpoint_handle_t edpt_hdl = + { + .coreid = 0, + .index = ep_id, + .class_code = dcd_data.class_code[ep_id] + }; + tusb_event_t event = (p_dd->status == DD_STATUS_NORMAL || p_dd->status == DD_STATUS_DATA_UNDERUN) ? TUSB_EVENT_XFER_COMPLETE : TUSB_EVENT_XFER_ERROR; + + usbd_xfer_isr(edpt_hdl, event, p_dd->present_count); // only number of bytes in the IOC qtd + } + } + } + + if (device_int_status & DEV_INT_ERROR_MASK || dma_int_status & DMA_INT_ERROR_MASK) { uint32_t error_status = sie_read(SIE_CMDCODE_READ_ERROR_STATUS, 1); (void) error_status; // ASSERT(false, (void) 0); } - } //--------------------------------------------------------------------+ @@ -200,32 +263,28 @@ static void bus_reset(void) LPC_USB->USBEpIntEn = (uint32_t) BIN8(11); // control endpoint cannot use DMA, non-control all use DMA LPC_USB->USBEpIntPri = 0; // same priority for all endpoint - // step 8 : DMA set up LPC_USB->USBEpDMADis = 0xFFFFFFFF; // firstly disable all dma LPC_USB->USBDMARClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->USBEoTIntClr = 0xFFFFFFFF; LPC_USB->USBNDDRIntClr = 0xFFFFFFFF; LPC_USB->USBSysErrIntClr = 0xFFFFFFFF; + + memclr_(&dcd_data, sizeof(dcd_data_t)); } tusb_error_t dcd_init(void) { //------------- user manual 11.13 usb device controller initialization -------------// LPC_USB->USBEpInd = 0; // step 6 : set up control endpoint - endpoint_set_max_packet_size(0, TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE); - endpoint_set_max_packet_size(1, TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE); + edpt_set_max_packet_size(0, TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE); + edpt_set_max_packet_size(1, TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE); bus_reset(); - LPC_USB->USBDevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK); - - for (uint8_t index = 0; index < DCD_MAX_DD; index++) - { - dcd_udca[index] = dcd_dd + index; - } - LPC_USB->USBUDCAH = (uint32_t) dcd_udca; - LPC_USB->USBDMAIntEn = (DMA_INT_END_OF_XFER_MASK | DMA_INT_NEW_DD_REQUEST_MASK | DMA_INT_ERROR_MASK ); + LPC_USB->USBDevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK); + LPC_USB->USBUDCAH = (uint32_t) dcd_data.udca; + LPC_USB->USBDMAIntEn = (DMA_INT_END_OF_XFER_MASK | DMA_INT_ERROR_MASK ); // clear all stall on control endpoint IN & OUT if any sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS , 1, 0); @@ -252,10 +311,10 @@ void dcd_controller_set_configuration(uint8_t coreid) } //--------------------------------------------------------------------+ -// PIPE API +// PIPE CONTROL HELPER //--------------------------------------------------------------------+ -static inline uint16_t length_unit_byte2dword(uint16_t length_in_bytes) ATTR_ALWAYS_INLINE ATTR_CONST; -static inline uint16_t length_unit_byte2dword(uint16_t length_in_bytes) +static inline uint16_t length_byte2dword(uint16_t length_in_bytes) ATTR_ALWAYS_INLINE ATTR_CONST; +static inline uint16_t length_byte2dword(uint16_t length_in_bytes) { return (length_in_bytes + 3) / 4; // length_in_dword } @@ -267,7 +326,7 @@ static tusb_error_t pipe_control_write(void const * buffer, uint16_t length) LPC_USB->USBCtrl = SLAVE_CONTROL_WRITE_ENABLE_MASK; // logical endpoint = 0 LPC_USB->USBTxPLen = length; - for (uint16_t count = 0; count < length_unit_byte2dword(length); count++) + for (uint16_t count = 0; count < length_byte2dword(length); count++) { LPC_USB->USBTxData = *((uint32_t *)buffer); // NOTE: cortex M3 have no problem with alignment buffer += 4; @@ -288,7 +347,7 @@ static tusb_error_t pipe_control_read(void * buffer, uint16_t length) uint16_t actual_length = min16_of(length, (uint16_t) (LPC_USB->USBRxPLen & SLAVE_RXPLEN_PACKET_LENGTH_MASK) ); uint32_t *p_read_data = (uint32_t*) buffer; - for( uint16_t count=0; count < length_unit_byte2dword(actual_length); count++) + for( uint16_t count=0; count < length_byte2dword(actual_length); count++) { *p_read_data = LPC_USB->USBRxData; p_read_data++; // increase by 4 ( sizeof(uint32_t) ) @@ -298,18 +357,12 @@ static tusb_error_t pipe_control_read(void * buffer, uint16_t length) return TUSB_ERROR_NONE; } -static inline uint8_t endpoint_address_to_physical_index(uint8_t ep_address) ATTR_ALWAYS_INLINE ATTR_CONST; -static inline uint8_t endpoint_address_to_physical_index(uint8_t ep_address) -{ - return (ep_address << 1) + (ep_address & 0x80 ? 1 : 0 ); -} - //--------------------------------------------------------------------+ // CONTROL PIPE API //--------------------------------------------------------------------+ void dcd_pipe_control_stall(uint8_t coreid) { - ASSERT(false, VOID_RETURN); + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK); } tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, void * p_buffer, uint16_t length) @@ -327,6 +380,27 @@ tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, void * return TUSB_ERROR_NONE; } +//--------------------------------------------------------------------+ +// PIPE HELPER +//--------------------------------------------------------------------+ +static inline uint8_t edpt_addr2phy(uint8_t endpoint_addr) ATTR_CONST ATTR_ALWAYS_INLINE; +static inline uint8_t edpt_addr2phy(uint8_t endpoint_addr) +{ + return 2*(endpoint_addr & 0x0F) + ((endpoint_addr & TUSB_DIR_DEV_TO_HOST_MASK) ? 1 : 0); +} + +// retval UINT8_MAX: invalid +static inline uint8_t dd_find_free(void) ATTR_PURE ATTR_ALWAYS_INLINE; +static inline uint8_t dd_find_free(void) +{ + for(uint8_t i=0; ibEndpointAddress ); + // TODO refractor to universal pipe open validation function + if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) return null_handle; // TODO not support ISO yet + ASSERT (p_endpoint_desc->wMaxPacketSize.size <= 64, null_handle); // TODO ISO can be 1023, but ISO not supported now + + uint8_t ep_id = edpt_addr2phy( p_endpoint_desc->bEndpointAddress ); //------------- Realize Endpoint with Max Packet Size -------------// - endpoint_set_max_packet_size(phy_ep, p_endpoint_desc->wMaxPacketSize.size); + edpt_set_max_packet_size(ep_id, p_endpoint_desc->wMaxPacketSize.size); - //------------- DMA set up -------------// - memclr_(dcd_dd + phy_ep, sizeof(dcd_dma_descriptor_t)); - dcd_dd[phy_ep].is_isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; - dcd_dd[phy_ep].max_packet_size = p_endpoint_desc->wMaxPacketSize.size; - dcd_dd[phy_ep].is_retired = 1; // dd is not active at first + //------------- fixed DD prepare -------------// + uint8_t const dd_idx = dd_find_free(); + ASSERT(dd_idx != UINT8_MAX, null_handle); - LPC_USB->USBEpDMAEn = BIT_(phy_ep); + dcd_data.ddat[ep_id] = dd_idx; // fixed this DD to UDCA for this endpoint + dcd_data.class_code[ep_id] = class_code; - sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+phy_ep, 1, 0); // clear all endpoint status + dcd_dma_descriptor_t* const p_dd = &dcd_data.dd[dd_idx]; + memclr_(p_dd, sizeof(dcd_dma_descriptor_t)); + p_dd->used = 1; + p_dd->is_isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; + p_dd->max_packet_size = p_endpoint_desc->wMaxPacketSize.size; + p_dd->is_retired = 1; // inactive at first + + dcd_data.udca[ ep_id ] = p_dd; // hook to UDCA + + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0); // clear all endpoint status + + return (endpoint_handle_t) + { + .coreid = 0, + .index = ep_id, + .class_code = class_code + }; } bool dcd_pipe_is_busy(endpoint_handle_t edpt_hdl) { - ASSERT(false, false); + return (dcd_data.udca[edpt_hdl.index] != NULL && !dcd_data.udca[edpt_hdl.index]->is_retired); +} + +tusb_error_t dcd_pipe_stall(endpoint_handle_t edpt_hdl) +{ + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+edpt_hdl.index, 1, SIE_SET_ENDPOINT_STALLED_MASK); + return TUSB_ERROR_NONE; } tusb_error_t dcd_pipe_clear_stall(uint8_t coreid, uint8_t edpt_addr) { + uint8_t ep_id = edpt_addr2phy(edpt_addr); + + sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0); + return TUSB_ERROR_FAILED; } +void dd_xfer_init(dcd_dma_descriptor_t* p_dd, void* buffer, uint16_t total_bytes) +{ + p_dd->next = 0; + p_dd->is_next_valid = 0; + p_dd->buffer_addr = (uint32_t) buffer; + p_dd->buffer_length = total_bytes; + p_dd->status = DD_STATUS_NOT_SERVICED; +} + +tusb_error_t dcd_pipe_queue_xfer(endpoint_handle_t edpt_hdl, void * buffer, uint16_t total_bytes) +{ // NOTE for sure the qhd has no dds + ASSERT( !dcd_pipe_is_busy(edpt_hdl), TUSB_ERROR_INTERFACE_IS_BUSY); // endpoint must not in transferring + + dcd_dma_descriptor_t* const p_dd = qhd_get_fixed_dd(edpt_hdl.index); // always queue with the fixed DD + + dd_xfer_init(p_dd, buffer, total_bytes); +// p_dd->int_on_complete = 0; + p_dd->is_retired = 1; + + return TUSB_ERROR_NONE; +} + tusb_error_t dcd_pipe_xfer(endpoint_handle_t edpt_hdl, void * buffer, uint16_t total_bytes, bool int_on_complete) { - ASSERT_STATUS(TUSB_ERROR_FAILED); + ASSERT( !dcd_pipe_is_busy(edpt_hdl), TUSB_ERROR_INTERFACE_IS_BUSY); // endpoint must not in transferring + + dcd_dma_descriptor_t* const p_fixed_dd = qhd_get_fixed_dd(edpt_hdl.index); + + if ( p_fixed_dd->buffer_length ) + { // fixed DD is already queued a xfer + //------------- setup new dd -------------// + uint8_t dd_idx = dd_find_free(); + ASSERT( dd_idx != UINT8_MAX, TUSB_ERROR_DCD_NOT_ENOUGH_QTD); + + dcd_dma_descriptor_t* const p_dd = &dcd_data.dd[ dd_idx ]; + memclr_(p_dd, sizeof(dcd_dma_descriptor_t)); + + dd_xfer_init(p_dd, buffer, total_bytes); + + p_dd->used = 1; + p_dd->max_packet_size = p_fixed_dd->max_packet_size; + p_dd->is_isochronous = p_fixed_dd->is_isochronous; +// p_dd->int_on_complete = int_on_complete; + + //------------- hook to fixed dd -------------// + p_fixed_dd->next = (uint32_t) p_dd; + p_fixed_dd->is_next_valid = 1; + } else + { // fixed DD is free + dd_xfer_init(p_fixed_dd, buffer, total_bytes); +// p_fixed_dd->int_on_complete = int_on_complete; + } + + p_fixed_dd->is_retired = 0; + + dcd_data.udca[edpt_hdl.index] = p_fixed_dd; + + LPC_USB->USBEpDMAEn = BIT_(edpt_hdl.index); + + if ( edpt_hdl.index % 2 ) + { // endpoint IN + LPC_USB->USBDMARSet = BIT_(edpt_hdl.index); + } return TUSB_ERROR_NONE; } diff --git a/tinyusb/device/dcd_lpc175x_6x.h b/tinyusb/device/dcd_lpc175x_6x.h index 33ff7b62f..3ee97105d 100644 --- a/tinyusb/device/dcd_lpc175x_6x.h +++ b/tinyusb/device/dcd_lpc175x_6x.h @@ -61,13 +61,13 @@ typedef struct //------------- Word 1 -------------// uint16_t mode : 2; // either 00 normal or 01 ATLE(auto length extraction) uint16_t is_next_valid : 1; - uint16_t : 1; + uint16_t used : 1; ///< make use of reserved bit uint16_t is_isochronous : 1; // is an iso endpoint uint16_t max_packet_size : 11; volatile uint16_t buffer_length; //------------- Word 2 -------------// - volatile uint32_t buffer_start_addr; + volatile uint32_t buffer_addr; //------------- Word 3 -------------// volatile uint16_t is_retired : 1; // initialized to zero @@ -77,18 +77,15 @@ typedef struct volatile uint16_t atle_is_msb_extracted : 1; // used in ATLE mode volatile uint16_t atle_message_length_position : 6; // used in ATLE mode uint16_t : 2; +// uint16_t int_on_complete : 1; ///< make use of reserved bit volatile uint16_t present_count; // The number of bytes transferred by the DMA engine. The DMA engine updates this field after completing each packet transfer. //------------- Word 4 -------------// // uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso } ATTR_ALIGNED(4) dcd_dma_descriptor_t; -#define DCD_MAX_DD 32 // TODO scale with configure +STATIC_ASSERT( sizeof(dcd_dma_descriptor_t) == 16, "size is not correct"); // TODO not support ISO for now -//typedef struct { -// dcd_dma_descriptor_t dd[DCD_MAX_DD]; -// -//}dcd_data_t; //--------------------------------------------------------------------+ // Register Interface @@ -178,17 +175,24 @@ enum { SIE_DEV_STATUS_RESET_MASK = BIT_(4) }; -//------------- SIE Endpoint Status -------------// +//------------- SIE Select Endpoint Command -------------// enum { - SIE_ENDPOINT_STATUS_FULL_EMPTY_MASK = BIT_(0), // 0: empty, 1 full. IN endpoint checks empty, OUT endpoint check full - SIE_ENDPOINT_STATUS_STALL_MASK = BIT_(1), - SIE_ENDPOINT_STATUS_SETUP_RECEIVED_MASK = BIT_(2), // clear by SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT - SIE_ENDPOINT_STATUS_PACKET_OVERWRITTEN_MASK = BIT_(3), // previous packet is overwritten by a SETUP packet - SIE_ENDPOINT_STATUS_NAK_MASK = BIT_(4), // last packet response is NAK (auto clear by an ACK) - SIE_ENDPOINT_STATUS_BUFFER1_FULL_MASK = BIT_(5), - SIE_ENDPOINT_STATUS_BUFFER2_FULL_MASK = BIT_(6) + SIE_SELECT_ENDPOINT_FULL_EMPTY_MASK = BIT_(0), // 0: empty, 1 full. IN endpoint checks empty, OUT endpoint check full + SIE_SELECT_ENDPOINT_STALL_MASK = BIT_(1), + SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK = BIT_(2), // clear by SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT + SIE_SELECT_ENDPOINT_PACKET_OVERWRITTEN_MASK = BIT_(3), // previous packet is overwritten by a SETUP packet + SIE_SELECT_ENDPOINT_NAK_MASK = BIT_(4), // last packet response is NAK (auto clear by an ACK) + SIE_SELECT_ENDPOINT_BUFFER1_FULL_MASK = BIT_(5), + SIE_SELECT_ENDPOINT_BUFFER2_FULL_MASK = BIT_(6) }; +typedef enum { + SIE_SET_ENDPOINT_STALLED_MASK = BIT_(0), + SIE_SET_ENDPOINT_DISABLED_MASK = BIT_(5), + SIE_SET_ENDPOINT_RATE_FEEDBACK_MASK = BIT_(6), + SIE_SET_ENDPOINT_CONDITION_STALLED_MASK = BIT_(7), +}sie_endpoint_set_status_mask_t; + //------------- DMA Descriptor Status -------------// enum { DD_STATUS_NOT_SERVICED = 0,