commit
908931320e
103
README.md
103
README.md
|
@ -1,95 +1,72 @@
|
||||||
# tinyusb #
|
# tinyusb
|
||||||
|
|
||||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
tinyusb is an cross-platform open-source USB Host/Device stack for embedded system.
|
||||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
||||||
**Table of Contents**
|
|
||||||
|
|
||||||
- [Features](#features)
|
![tinyusb](https://user-images.githubusercontent.com/249515/49858616-f60c9700-fe27-11e8-8627-e76936352ff7.png)
|
||||||
- [Host](#host)
|
|
||||||
- [Device](#device)
|
|
||||||
- [RTOS](#rtos)
|
|
||||||
- [Supported MCUs](#supported-mcus)
|
|
||||||
- [Toolchains](#toolchains)
|
|
||||||
- [Getting Started](#getting-started)
|
|
||||||
- [Uses](#uses)
|
|
||||||
- [Porting](#porting)
|
|
||||||
- [License](#license)
|
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
Folder | Description
|
||||||
|
----- | -------------
|
||||||
|
docs | Documentation
|
||||||
|
examples| Sample applications are kept with Makefile and Segger Embedded build support
|
||||||
|
hw/bsp | Source files of supported boards
|
||||||
|
hw/mcu | Low level mcu core & peripheral drivers (e.g CMSIS )
|
||||||
|
lib | Source files from 3rd party such as freeRTOS, fatfs etc ...
|
||||||
|
src | All sources files for tinyusb stack itself.
|
||||||
|
tests | Unit tests for the stack
|
||||||
|
tools | Files used internally
|
||||||
|
|
||||||
tinyusb is an open-source (BSD-licensed) USB Host/Device/OTG stack for embedded micro-controllers, especially ARM MCUs. It is designed to be user-friendly in term of configuration and out-of-the-box running experience.
|
## Device Stack
|
||||||
|
|
||||||
In addition to running without an RTOS, tinyusb can run across multiple RTOS vendors. More documents and API reference can be found at http://docs.tinyusb.org
|
- Human Interface Device (HID): Keyboard, Mouse, Generic
|
||||||
|
|
||||||
![tinyusb diagram](http://docs.tinyusb.org/images/tinyusb_overview.png)
|
|
||||||
|
|
||||||
## Features ##
|
|
||||||
|
|
||||||
### Device ###
|
|
||||||
|
|
||||||
- HID Mouse
|
|
||||||
- HID Keyboard
|
|
||||||
- HID Generic
|
|
||||||
- Communication Class (CDC)
|
- Communication Class (CDC)
|
||||||
- Mass Storage Class (MSC)
|
- Mass Storage Class (MSC)
|
||||||
|
|
||||||
### Host ###
|
## Host Stack
|
||||||
|
|
||||||
** Most active development is on the Device stack. The Host stack is largely untested.**
|
** Most active development is on the Device stack. The Host stack is under rework and largely untested.**
|
||||||
|
|
||||||
- HID Mouse
|
- Human Interface Device (HID): Keyboard, Mouse, Generic
|
||||||
- HID Keyboard
|
|
||||||
- HID Generic (coming soon)
|
|
||||||
- Communication Device Class (CDC)
|
|
||||||
- Mass Storage Class (MSC)
|
- Mass Storage Class (MSC)
|
||||||
- Hub currently only support 1 level of hub (due to my laziness)
|
- Hub currently only support 1 level of hub (due to my laziness)
|
||||||
|
|
||||||
### RTOS ###
|
## OS Abtraction layer
|
||||||
|
|
||||||
Currently the following OS are supported with tinyusb out of the box with a simple change of CFG_TUSB_OS macro.
|
Currently the following OS are supported with tinyusb out of the box with a simple change of **CFG_TUSB_OS** macro.
|
||||||
|
|
||||||
- **None OS**
|
- **No OS**
|
||||||
- **FreeRTOS**
|
- **FreeRTOS**
|
||||||
- **MyNewt**
|
- **MyNewt** (work in progress)
|
||||||
|
|
||||||
### Toolchains ###
|
## Supported MCUs
|
||||||
|
|
||||||
You can compile with any of following toolchains, however, the stack requires C99 to build with
|
|
||||||
|
|
||||||
- GCC
|
|
||||||
- lpcxpresso
|
|
||||||
- Keil MDK
|
|
||||||
- IAR Workbench
|
|
||||||
|
|
||||||
### Supported MCUs ###
|
|
||||||
|
|
||||||
The stack supports the following MCUs
|
The stack supports the following MCUs
|
||||||
|
|
||||||
- LPC11uxx
|
- **NXP:** LPC11Uxx, LPC13xx, LPC175x_6x, LPC177x_8x, LPC40xx, LPC43xx
|
||||||
- LPC13uxx (12 bit ADC)
|
- **MicroChip:** SAMD21, SAMD51 (device only)
|
||||||
- LPC175x_6x
|
- **Nordic:** nRF52840
|
||||||
- LPC43xx
|
|
||||||
- MicroChip SAMD21
|
|
||||||
- MicroChip SAMD51
|
|
||||||
- Nordic nRF52840
|
|
||||||
|
|
||||||
[Here is the list of supported Boards](boards/readme.md) in the code base
|
[Here is the list of supported Boards](hw/bsp/readme.md)
|
||||||
|
|
||||||
## Getting Started ##
|
## Compiler & IDE
|
||||||
|
|
||||||
[Here is the details for getting started](doxygen/getting_started.md) with the stack.
|
The stack is developed with GCC compiler, and should be compilable with others. However, it requires C99 to build with. Folder `examples` provide Makefile and Segger Embedded Studio build support.
|
||||||
|
|
||||||
## Uses ##
|
## Getting Started
|
||||||
|
|
||||||
|
[Here is the details for getting started](docs/getting_started.md) with the stack.
|
||||||
|
|
||||||
|
## Uses
|
||||||
|
|
||||||
TinyUSB is currently used by these other projects:
|
TinyUSB is currently used by these other projects:
|
||||||
|
|
||||||
* [nRF52840 UF2 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
|
* [Adafruit nRF52 Arduino](https://github.com/adafruit/Adafruit_nRF52_Arduino)
|
||||||
* [CircuitPython](https://github.com/adafruit/circuitpython)
|
* [CircuitPython](https://github.com/adafruit/circuitpython)
|
||||||
|
* [nRF52840 UF2 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
|
||||||
|
|
||||||
## Porting ##
|
## Porting
|
||||||
|
|
||||||
Want to help add TinyUSB support for a new MCU? Read [here](doxygen/porting.md) for an explanation on the low-level API needed by TinyUSB.
|
Want to help add TinyUSB support for a new MCU? Read [here](docs/porting.md) for an explanation on the low-level API needed by TinyUSB.
|
||||||
|
|
||||||
## License ##
|
## License
|
||||||
|
|
||||||
BSD license for most of the code base, but each file is individually licensed especially those in *vendor* folder. Please make sure you understand all the license term for files you use in your project. [Full license is here](tinyusb/license.md)
|
BSD license for all tinyusb sources [Full license is here](tinyusb/license.md) and most of the code base. However each file/folder is individually licensed especially those in `lib` and `hw/mcu` folder. Please make sure you understand all the license term for files you use in your project.
|
||||||
|
|
|
@ -113,10 +113,10 @@ As before with `dcd_event_bus_signal` the first argument is the USB peripheral n
|
||||||
|
|
||||||
Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below.
|
Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below.
|
||||||
|
|
||||||
Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides `edpt_number` and `edpt_dir` to unpack this data from the address. Here is a snippet that does it.
|
Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides `tu_edpt_number` and `tu_edpt_dir` to unpack this data from the address. Here is a snippet that does it.
|
||||||
|
|
||||||
uint8_t epnum = edpt_number(ep_addr);
|
uint8_t epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t dir = edpt_dir(ep_addr);
|
uint8_t dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
##### dcd_edpt_open
|
##### dcd_edpt_open
|
||||||
|
|
||||||
|
|
|
@ -94,11 +94,20 @@ void virtual_com_task(void)
|
||||||
// read and echo back
|
// read and echo back
|
||||||
uint32_t count = tud_cdc_read(buf, sizeof(buf));
|
uint32_t count = tud_cdc_read(buf, sizeof(buf));
|
||||||
|
|
||||||
tud_cdc_write(buf, count);
|
for(uint32_t i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
tud_cdc_write_char(buf[i]);
|
||||||
|
|
||||||
|
if ( buf[i] == '\r' )
|
||||||
|
{
|
||||||
|
tud_cdc_write_char('\n');
|
||||||
|
tud_cdc_write_str("tinyusb cdc: ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tud_cdc_write_flush();
|
tud_cdc_write_flush();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||||
|
@ -109,7 +118,7 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||||
if ( dtr && rts )
|
if ( dtr && rts )
|
||||||
{
|
{
|
||||||
// print greeting
|
// print greeting
|
||||||
tud_cdc_write_str("tinyusb usb cdc\n");
|
tud_cdc_write_str("tinyusb cdc: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Supported MCUs #
|
|
||||||
|
|
||||||
Currently
|
|
|
@ -229,16 +229,14 @@ void cdcd_reset(uint8_t rhport)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
|
bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS;
|
// Only support ACM subclass
|
||||||
|
TU_ASSERT ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
|
||||||
|
|
||||||
// Only support AT commands, no protocol and vendor specific commands.
|
// Only support AT commands, no protocol and vendor specific commands.
|
||||||
if ( !(tu_within(CDC_COMM_PROTOCOL_NONE, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
|
TU_ASSERT(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
|
||||||
p_interface_desc->bInterfaceProtocol == 0xff ) )
|
itf_desc->bInterfaceProtocol == 0xff);
|
||||||
{
|
|
||||||
return TUSB_ERROR_CDC_UNSUPPORTED_PROTOCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find available interface
|
// Find available interface
|
||||||
cdcd_interface_t * p_cdc = NULL;
|
cdcd_interface_t * p_cdc = NULL;
|
||||||
|
@ -250,49 +248,51 @@ tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TU_ASSERT(p_cdc);
|
||||||
|
|
||||||
//------------- Control Interface -------------//
|
//------------- Control Interface -------------//
|
||||||
p_cdc->itf_num = p_interface_desc->bInterfaceNumber;
|
p_cdc->itf_num = itf_desc->bInterfaceNumber;
|
||||||
|
|
||||||
uint8_t const * p_desc = descriptor_next ( (uint8_t const *) p_interface_desc );
|
uint8_t const * p_desc = tu_desc_next( itf_desc );
|
||||||
(*p_length) = sizeof(tusb_desc_interface_t);
|
(*p_length) = sizeof(tusb_desc_interface_t);
|
||||||
|
|
||||||
// Communication Functional Descriptors
|
// Communication Functional Descriptors
|
||||||
while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] )
|
while ( TUSB_DESC_CLASS_SPECIFIC == tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += tu_desc_len(p_desc);
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
|
||||||
{ // notification endpoint if any
|
{
|
||||||
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED);
|
// notification endpoint if any
|
||||||
|
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc) );
|
||||||
|
|
||||||
p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Data Interface (if any) -------------//
|
//------------- Data Interface (if any) -------------//
|
||||||
if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
|
if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
|
||||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||||
{
|
{
|
||||||
// next to endpoint descritpor
|
// next to endpoint descriptor
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += tu_desc_len(p_desc);
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
|
|
||||||
// Open endpoint pair with usbd helper
|
// Open endpoint pair with usbd helper
|
||||||
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||||
TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
|
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
|
||||||
|
|
||||||
(*p_length) += 2*sizeof(tusb_desc_endpoint_t);
|
(*p_length) += 2*sizeof(tusb_desc_endpoint_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for incoming data
|
// Prepare for incoming data
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE), TUSB_ERROR_DCD_EDPT_XFER);
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE) );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when class request DATA stage is finished.
|
// Invoked when class request DATA stage is finished.
|
||||||
|
@ -346,9 +346,10 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request
|
||||||
// This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
|
// This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
|
||||||
p_cdc->line_state = (uint8_t) request->wValue;
|
p_cdc->line_state = (uint8_t) request->wValue;
|
||||||
|
|
||||||
|
usbd_control_status(rhport, request);
|
||||||
|
|
||||||
// Invoke callback
|
// Invoke callback
|
||||||
if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, BIT_TEST_(request->wValue, 0), BIT_TEST_(request->wValue, 1));
|
if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, BIT_TEST_(request->wValue, 0), BIT_TEST_(request->wValue, 1));
|
||||||
usbd_control_status(rhport, request);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: return false; // stall unsupported request
|
default: return false; // stall unsupported request
|
||||||
|
@ -357,7 +358,7 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
(void) result;
|
(void) result;
|
||||||
|
|
||||||
|
@ -382,13 +383,13 @@ tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
|
||||||
// invoke receive callback (if there is still data)
|
// invoke receive callback (if there is still data)
|
||||||
if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
|
if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
|
||||||
|
|
||||||
// prepare for next
|
// prepare for incoming data
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE), TUSB_ERROR_DCD_EDPT_XFER );
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing to do with in and notif endpoint
|
// nothing to do with in and notif endpoint
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -113,10 +113,10 @@ ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_li
|
||||||
#ifdef _TINY_USB_SOURCE_FILE_
|
#ifdef _TINY_USB_SOURCE_FILE_
|
||||||
|
|
||||||
void cdcd_init (void);
|
void cdcd_init (void);
|
||||||
tusb_error_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
|
bool cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
|
||||||
bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * p_request);
|
bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
bool cdcd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
bool cdcd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
tusb_error_t cdcd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
|
bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||||
void cdcd_reset (uint8_t rhport);
|
void cdcd_reset (uint8_t rhport);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -146,7 +146,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
uint8_t const * p_desc;
|
uint8_t const * p_desc;
|
||||||
cdch_data_t * p_cdc;
|
cdch_data_t * p_cdc;
|
||||||
|
|
||||||
p_desc = descriptor_next ( (uint8_t const *) itf_desc );
|
p_desc = tu_desc_next(itf_desc);
|
||||||
p_cdc = &cdch_data[dev_addr-1];
|
p_cdc = &cdch_data[dev_addr-1];
|
||||||
|
|
||||||
p_cdc->itf_num = itf_desc->bInterfaceNumber;
|
p_cdc->itf_num = itf_desc->bInterfaceNumber;
|
||||||
|
@ -165,7 +165,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
||||||
|
@ -177,7 +177,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
p_cdc->ep_notif = ep_desc->bEndpointAddress;
|
p_cdc->ep_notif = ep_desc->bEndpointAddress;
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Data Interface (if any) -------------//
|
//------------- Data Interface (if any) -------------//
|
||||||
|
@ -185,7 +185,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||||
{
|
{
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
|
|
||||||
// data endpoints expected to be in pairs
|
// data endpoints expected to be in pairs
|
||||||
for(uint32_t i=0; i<2; i++)
|
for(uint32_t i=0; i<2; i++)
|
||||||
|
@ -196,7 +196,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
|
|
||||||
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
||||||
|
|
||||||
if ( edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
||||||
{
|
{
|
||||||
p_cdc->ep_in = ep_desc->bEndpointAddress;
|
p_cdc->ep_in = ep_desc->bEndpointAddress;
|
||||||
}else
|
}else
|
||||||
|
@ -205,7 +205,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = descriptor_next( p_desc );
|
p_desc = tu_desc_next( p_desc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,22 +71,22 @@ void cusd_init(void)
|
||||||
tu_varclr(&_cusd_itf);
|
tu_varclr(&_cusd_itf);
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
|
bool cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
|
||||||
{
|
{
|
||||||
cusd_interface_t* p_itf = &_cusd_itf;
|
cusd_interface_t* p_itf = &_cusd_itf;
|
||||||
|
|
||||||
// Open endpoint pair with usbd helper
|
// Open endpoint pair with usbd helper
|
||||||
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_itf );
|
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(p_desc_itf);
|
||||||
TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_itf->ep_out, &p_itf->ep_in) );
|
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_itf->ep_out, &p_itf->ep_in) );
|
||||||
|
|
||||||
p_itf->itf_num = p_desc_itf->bInterfaceNumber;
|
p_itf->itf_num = p_desc_itf->bInterfaceNumber;
|
||||||
|
|
||||||
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||||
|
|
||||||
// TODO Prepare for incoming data
|
// TODO Prepare for incoming data
|
||||||
// TU_ASSERT( dcd_edpt_xfer(rhport, p_itf->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_DCD_EDPT_XFER );
|
// TU_ASSERT( dcd_edpt_xfer(rhport, p_itf->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cusd_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
|
bool cusd_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
@ -94,9 +94,9 @@ bool cusd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t cusd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes)
|
bool cusd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cusd_reset(uint8_t rhport)
|
void cusd_reset(uint8_t rhport)
|
||||||
|
|
|
@ -63,10 +63,10 @@
|
||||||
#ifdef _TINY_USB_SOURCE_FILE_
|
#ifdef _TINY_USB_SOURCE_FILE_
|
||||||
|
|
||||||
void cusd_init(void);
|
void cusd_init(void);
|
||||||
tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
|
bool cusd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||||
bool cusd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request);
|
bool cusd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
bool cusd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
bool cusd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
tusb_error_t cusd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
|
bool cusd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void cusd_reset(uint8_t rhport);
|
void cusd_reset(uint8_t rhport);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
|
||||||
{
|
{
|
||||||
// FIXME quick hack to test lpc1k custom class with 2 bulk endpoints
|
// FIXME quick hack to test lpc1k custom class with 2 bulk endpoints
|
||||||
uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
|
uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
|
|
||||||
//------------- Bulk Endpoints Descriptor -------------//
|
//------------- Bulk Endpoints Descriptor -------------//
|
||||||
for(uint32_t i=0; i<2; i++)
|
for(uint32_t i=0; i<2; i++)
|
||||||
|
@ -124,7 +124,7 @@ tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
|
||||||
*p_pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
|
*p_pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
|
||||||
TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
|
TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
|
||||||
|
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p_length) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
(*p_length) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||||
|
|
|
@ -318,22 +318,22 @@ void hidd_reset(uint8_t rhport)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len)
|
bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len)
|
||||||
{
|
{
|
||||||
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
||||||
|
|
||||||
// TODO not support HID OUT Endpoint
|
// TODO support HID OUT Endpoint
|
||||||
TU_ASSERT(desc_itf->bNumEndpoints == 1, ERR_TUD_INVALID_DESCRIPTOR);
|
TU_ASSERT(desc_itf->bNumEndpoints == 1);
|
||||||
|
|
||||||
//------------- HID descriptor -------------//
|
//------------- HID descriptor -------------//
|
||||||
p_desc += p_desc[DESC_OFFSET_LEN];
|
p_desc = tu_desc_next(p_desc);
|
||||||
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
|
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
|
||||||
TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType, ERR_TUD_INVALID_DESCRIPTOR);
|
TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType);
|
||||||
|
|
||||||
//------------- Endpoint Descriptor -------------//
|
//------------- Endpoint Descriptor -------------//
|
||||||
p_desc += p_desc[DESC_OFFSET_LEN];
|
p_desc = tu_desc_next(p_desc);
|
||||||
tusb_desc_endpoint_t const *desc_edpt = (tusb_desc_endpoint_t const *) p_desc;
|
tusb_desc_endpoint_t const *desc_edpt = (tusb_desc_endpoint_t const *) p_desc;
|
||||||
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_edpt->bDescriptorType, ERR_TUD_INVALID_DESCRIPTOR);
|
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_edpt->bDescriptorType);
|
||||||
|
|
||||||
hidd_interface_t * p_hid = NULL;
|
hidd_interface_t * p_hid = NULL;
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR);
|
TU_ASSERT(p_hid);
|
||||||
p_hid->boot_protocol = true; // default mode is BOOT
|
p_hid->boot_protocol = true; // default mode is BOOT
|
||||||
}
|
}
|
||||||
/*------------- Generic (multiple report) -------------*/
|
/*------------- Generic (multiple report) -------------*/
|
||||||
|
@ -386,12 +386,10 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
|
||||||
p_hid->desc_report = usbd_desc_set->hid_report.generic;
|
p_hid->desc_report = usbd_desc_set->hid_report.generic;
|
||||||
p_hid->get_report_cb = tud_hid_generic_get_report_cb;
|
p_hid->get_report_cb = tud_hid_generic_get_report_cb;
|
||||||
p_hid->set_report_cb = tud_hid_generic_set_report_cb;
|
p_hid->set_report_cb = tud_hid_generic_set_report_cb;
|
||||||
|
|
||||||
TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_VERIFY(p_hid->desc_report, ERR_TUD_INVALID_DESCRIPTOR);
|
TU_ASSERT(p_hid->desc_report);
|
||||||
TU_ASSERT( dcd_edpt_open(rhport, desc_edpt), ERR_TUD_EDPT_OPEN_FAILED );
|
TU_ASSERT(dcd_edpt_open(rhport, desc_edpt));
|
||||||
|
|
||||||
p_hid->itf_num = desc_itf->bInterfaceNumber;
|
p_hid->itf_num = desc_itf->bInterfaceNumber;
|
||||||
p_hid->ep_in = desc_edpt->bEndpointAddress;
|
p_hid->ep_in = desc_edpt->bEndpointAddress;
|
||||||
|
@ -399,7 +397,7 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
|
||||||
|
|
||||||
*p_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
|
*p_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle class control request
|
// Handle class control request
|
||||||
|
@ -510,10 +508,10 @@ bool hidd_control_request_complete(uint8_t rhport, tusb_control_request_t const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes)
|
bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -377,10 +377,10 @@ ATTR_WEAK void tud_hid_mouse_set_report_cb(uint8_t report_id, hid_report_type_t
|
||||||
#ifdef _TINY_USB_SOURCE_FILE_
|
#ifdef _TINY_USB_SOURCE_FILE_
|
||||||
|
|
||||||
void hidd_init(void);
|
void hidd_init(void);
|
||||||
tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
|
bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||||
bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
|
bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
bool hidd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
bool hidd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
|
bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void hidd_reset(uint8_t rhport);
|
void hidd_reset(uint8_t rhport);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -150,25 +150,25 @@ void mscd_reset(uint8_t rhport)
|
||||||
tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
|
tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
|
bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len)
|
||||||
{
|
{
|
||||||
// only support SCSI's BOT protocol
|
// only support SCSI's BOT protocol
|
||||||
TU_VERIFY( ( MSC_SUBCLASS_SCSI == p_desc_itf->bInterfaceSubClass &&
|
TU_ASSERT(MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
|
||||||
MSC_PROTOCOL_BOT == p_desc_itf->bInterfaceProtocol ), TUSB_ERROR_MSC_UNSUPPORTED_PROTOCOL );
|
MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol);
|
||||||
|
|
||||||
mscd_interface_t * p_msc = &_mscd_itf;
|
mscd_interface_t * p_msc = &_mscd_itf;
|
||||||
|
|
||||||
// Open endpoint pair with usbd helper
|
// Open endpoint pair with usbd helper
|
||||||
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_itf );
|
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next( itf_desc );
|
||||||
TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
|
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
|
||||||
|
|
||||||
p_msc->itf_num = p_desc_itf->bInterfaceNumber;
|
p_msc->itf_num = itf_desc->bInterfaceNumber;
|
||||||
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||||
|
|
||||||
//------------- Queue Endpoint OUT for Command Block Wrapper -------------//
|
// Prepare for Command Block Wrapper
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_DCD_EDPT_XFER );
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle class control request
|
// Handle class control request
|
||||||
|
@ -329,7 +329,7 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
mscd_interface_t* p_msc = &_mscd_itf;
|
mscd_interface_t* p_msc = &_mscd_itf;
|
||||||
msc_cbw_t const * p_cbw = &p_msc->cbw;
|
msc_cbw_t const * p_cbw = &p_msc->cbw;
|
||||||
|
@ -340,10 +340,10 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
||||||
case MSC_STAGE_CMD:
|
case MSC_STAGE_CMD:
|
||||||
//------------- new CBW received -------------//
|
//------------- new CBW received -------------//
|
||||||
// Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it
|
// Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it
|
||||||
if(ep_addr != p_msc->ep_out) return TUSB_ERROR_NONE;
|
if(ep_addr != p_msc->ep_out) return true;
|
||||||
|
|
||||||
TU_ASSERT( event == XFER_RESULT_SUCCESS &&
|
TU_ASSERT( event == XFER_RESULT_SUCCESS &&
|
||||||
xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA );
|
xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE );
|
||||||
|
|
||||||
p_csw->signature = MSC_CSW_SIGNATURE;
|
p_csw->signature = MSC_CSW_SIGNATURE;
|
||||||
p_csw->tag = p_cbw->tag;
|
p_csw->tag = p_cbw->tag;
|
||||||
|
@ -388,7 +388,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
||||||
else if ( !BIT_TEST_(p_cbw->dir, 7) )
|
else if ( !BIT_TEST_(p_cbw->dir, 7) )
|
||||||
{
|
{
|
||||||
// OUT transfer
|
// OUT transfer
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len), TUSB_ERROR_DCD_EDPT_XFER );
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -409,8 +409,8 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
||||||
p_msc->total_len = (uint32_t) cb_result;
|
p_msc->total_len = (uint32_t) cb_result;
|
||||||
p_csw->status = MSC_CSW_STATUS_PASSED;
|
p_csw->status = MSC_CSW_STATUS_PASSED;
|
||||||
|
|
||||||
TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len, TUSB_ERROR_INVALID_PARA ); // cannot return more than host expect
|
TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len), TUSB_ERROR_DCD_EDPT_XFER );
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
p_msc->total_len = 0;
|
p_msc->total_len = 0;
|
||||||
|
@ -474,7 +474,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
||||||
// simulate an transfer complete with adjusted parameters --> this driver callback will fired again
|
// simulate an transfer complete with adjusted parameters --> this driver callback will fired again
|
||||||
dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false);
|
dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false);
|
||||||
|
|
||||||
return TUSB_ERROR_NONE; // skip the rest
|
return true; // skip the rest
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -549,7 +549,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
|
@ -171,10 +171,10 @@ ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
|
||||||
#ifdef _TINY_USB_SOURCE_FILE_
|
#ifdef _TINY_USB_SOURCE_FILE_
|
||||||
|
|
||||||
void mscd_init(void);
|
void mscd_init(void);
|
||||||
tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
|
bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||||
bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
|
bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
bool mscd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
bool mscd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
|
bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void mscd_reset(uint8_t rhport);
|
void mscd_reset(uint8_t rhport);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -300,7 +300,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
msch_interface_t* p_msc = &msch_data[dev_addr-1];
|
msch_interface_t* p_msc = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Open Data Pipe -------------//
|
//------------- Open Data Pipe -------------//
|
||||||
tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) itf_desc );
|
tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
|
||||||
|
|
||||||
for(uint32_t i=0; i<2; i++)
|
for(uint32_t i=0; i<2; i++)
|
||||||
{
|
{
|
||||||
|
@ -309,7 +309,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
|
|
||||||
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
||||||
|
|
||||||
if ( edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
||||||
{
|
{
|
||||||
p_msc->ep_in = ep_desc->bEndpointAddress;
|
p_msc->ep_in = ep_desc->bEndpointAddress;
|
||||||
}else
|
}else
|
||||||
|
@ -317,7 +317,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
|
||||||
p_msc->ep_out = ep_desc->bEndpointAddress;
|
p_msc->ep_out = ep_desc->bEndpointAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep_desc = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) ep_desc );
|
ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_msc->itf_numr = itf_desc->bInterfaceNumber;
|
p_msc->itf_numr = itf_desc->bInterfaceNumber;
|
||||||
|
|
|
@ -181,7 +181,6 @@ enum {
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_DEVICE_STATE_UNPLUG = 0 ,
|
TUSB_DEVICE_STATE_UNPLUG = 0 ,
|
||||||
TUSB_DEVICE_STATE_ADDRESSED ,
|
|
||||||
TUSB_DEVICE_STATE_CONFIGURED ,
|
TUSB_DEVICE_STATE_CONFIGURED ,
|
||||||
TUSB_DEVICE_STATE_SUSPENDED ,
|
TUSB_DEVICE_STATE_SUSPENDED ,
|
||||||
}tusb_device_state_t;
|
}tusb_device_state_t;
|
||||||
|
@ -376,18 +375,18 @@ static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t r
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Get direction from Endpoint address
|
// Get direction from Endpoint address
|
||||||
static inline tusb_dir_t edpt_dir(uint8_t addr)
|
static inline tusb_dir_t tu_edpt_dir(uint8_t addr)
|
||||||
{
|
{
|
||||||
return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
|
return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Endpoint number from address
|
// Get Endpoint number from address
|
||||||
static inline uint8_t edpt_number(uint8_t addr)
|
static inline uint8_t tu_edpt_number(uint8_t addr)
|
||||||
{
|
{
|
||||||
return addr & (~TUSB_DIR_IN_MASK);
|
return addr & (~TUSB_DIR_IN_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t edpt_addr(uint8_t num, uint8_t dir)
|
static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
|
||||||
{
|
{
|
||||||
return num | (dir ? TUSB_DIR_IN_MASK : 0);
|
return num | (dir ? TUSB_DIR_IN_MASK : 0);
|
||||||
}
|
}
|
||||||
|
@ -395,19 +394,20 @@ static inline uint8_t edpt_addr(uint8_t num, uint8_t dir)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Descriptor helper
|
// Descriptor helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline uint8_t const * descriptor_next(uint8_t const p_desc[])
|
static inline uint8_t const * tu_desc_next(void const* desc)
|
||||||
{
|
{
|
||||||
return p_desc + p_desc[DESC_OFFSET_LEN];
|
uint8_t const* desc8 = (uint8_t const*) desc;
|
||||||
|
return desc8 + desc8[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t descriptor_type(uint8_t const p_desc[])
|
static inline uint8_t tu_desc_type(void const* desc)
|
||||||
{
|
{
|
||||||
return p_desc[DESC_OFFSET_TYPE];
|
return ((uint8_t const*) desc)[DESC_OFFSET_TYPE];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t descriptor_len(uint8_t const p_desc[])
|
static inline uint8_t tu_desc_len(void const* desc)
|
||||||
{
|
{
|
||||||
return p_desc[DESC_OFFSET_LEN];
|
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length of the string descriptors in bytes with slen characters
|
// Length of the string descriptors in bytes with slen characters
|
||||||
|
|
|
@ -89,10 +89,10 @@ typedef struct {
|
||||||
uint8_t class_code;
|
uint8_t class_code;
|
||||||
|
|
||||||
void (* init ) (void);
|
void (* init ) (void);
|
||||||
tusb_error_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length);
|
bool (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length);
|
||||||
bool (* control_request ) (uint8_t rhport, tusb_control_request_t const * request);
|
bool (* control_request ) (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool (* control_request_complete ) (uint8_t rhport, tusb_control_request_t const * request);
|
bool (* control_request_complete ) (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
tusb_error_t (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t, uint32_t);
|
bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t, uint32_t);
|
||||||
void (* sof ) (uint8_t rhport);
|
void (* sof ) (uint8_t rhport);
|
||||||
void (* reset ) (uint8_t);
|
void (* reset ) (uint8_t);
|
||||||
} usbd_class_driver_t;
|
} usbd_class_driver_t;
|
||||||
|
@ -246,14 +246,14 @@ static void usbd_task_body(void)
|
||||||
// Invoke the class callback associated with the endpoint address
|
// Invoke the class callback associated with the endpoint address
|
||||||
uint8_t const ep_addr = event.xfer_complete.ep_addr;
|
uint8_t const ep_addr = event.xfer_complete.ep_addr;
|
||||||
|
|
||||||
if ( 0 == edpt_number(ep_addr) )
|
if ( 0 == tu_edpt_number(ep_addr) )
|
||||||
{
|
{
|
||||||
// control transfer DATA stage callback
|
// control transfer DATA stage callback
|
||||||
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
|
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t const drv_id = _usbd_dev.ep2drv[edpt_number(ep_addr)][edpt_dir(ep_addr)];
|
uint8_t const drv_id = _usbd_dev.ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)];
|
||||||
TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
|
TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
|
||||||
|
|
||||||
usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
|
usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
|
||||||
|
@ -436,12 +436,12 @@ static bool process_set_config(uint8_t rhport)
|
||||||
while( p_desc < desc_cfg + cfg_len )
|
while( p_desc < desc_cfg + cfg_len )
|
||||||
{
|
{
|
||||||
// Each interface always starts with Interface or Association descriptor
|
// Each interface always starts with Interface or Association descriptor
|
||||||
if ( TUSB_DESC_INTERFACE_ASSOCIATION == descriptor_type(p_desc) )
|
if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
p_desc = descriptor_next(p_desc); // ignore Interface Association
|
p_desc = tu_desc_next(p_desc); // ignore Interface Association
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
TU_ASSERT( TUSB_DESC_INTERFACE == descriptor_type(p_desc) );
|
TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
|
||||||
|
|
||||||
tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;
|
tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ static bool process_set_config(uint8_t rhport)
|
||||||
_usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
|
_usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
|
||||||
|
|
||||||
uint16_t itf_len=0;
|
uint16_t itf_len=0;
|
||||||
TU_ASSERT_ERR( usbd_class_drivers[drv_id].open( rhport, desc_itf, &itf_len ), false );
|
TU_ASSERT( usbd_class_drivers[drv_id].open( rhport, desc_itf, &itf_len ) );
|
||||||
TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) );
|
TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) );
|
||||||
|
|
||||||
mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id);
|
mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id);
|
||||||
|
@ -480,15 +480,15 @@ static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc,
|
||||||
|
|
||||||
while( len < desc_len )
|
while( len < desc_len )
|
||||||
{
|
{
|
||||||
if ( TUSB_DESC_ENDPOINT == descriptor_type(p_desc) )
|
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
|
uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
|
||||||
|
|
||||||
ep2drv[edpt_number(ep_addr)][edpt_dir(ep_addr)] = driver_id;
|
ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
len += descriptor_len(p_desc);
|
len += tu_desc_len(p_desc);
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,7 +576,7 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
|
||||||
|
|
||||||
case DCD_EVENT_XFER_COMPLETE:
|
case DCD_EVENT_XFER_COMPLETE:
|
||||||
// skip zero-length control status complete event, should dcd notifies us.
|
// skip zero-length control status complete event, should dcd notifies us.
|
||||||
if ( 0 == edpt_number(event->xfer_complete.ep_addr) && event->xfer_complete.len == 0) break;
|
if ( 0 == tu_edpt_number(event->xfer_complete.ep_addr) && event->xfer_complete.len == 0) break;
|
||||||
|
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
TU_ASSERT(event->xfer_complete.result == XFER_RESULT_SUCCESS,);
|
TU_ASSERT(event->xfer_complete.result == XFER_RESULT_SUCCESS,);
|
||||||
|
@ -624,16 +624,16 @@ void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Helper to parse an pair of endpoint descriptors (IN & OUT)
|
// Helper to parse an pair of endpoint descriptors (IN & OUT)
|
||||||
tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* ep_desc, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
|
bool usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* ep_desc, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
|
||||||
{
|
{
|
||||||
for(int i=0; i<2; i++)
|
for(int i=0; i<2; i++)
|
||||||
{
|
{
|
||||||
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType &&
|
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType &&
|
||||||
xfer_type == ep_desc->bmAttributes.xfer, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
|
xfer_type == ep_desc->bmAttributes.xfer );
|
||||||
|
|
||||||
TU_ASSERT( dcd_edpt_open(rhport, ep_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED );
|
TU_ASSERT(dcd_edpt_open(rhport, ep_desc));
|
||||||
|
|
||||||
if ( edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
||||||
{
|
{
|
||||||
(*ep_in) = ep_desc->bEndpointAddress;
|
(*ep_in) = ep_desc->bEndpointAddress;
|
||||||
}else
|
}else
|
||||||
|
@ -641,10 +641,10 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* ep_
|
||||||
(*ep_out) = ep_desc->bEndpointAddress;
|
(*ep_out) = ep_desc->bEndpointAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep_desc = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) ep_desc );
|
ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to defer an isr function
|
// Helper to defer an isr function
|
||||||
|
|
|
@ -70,7 +70,7 @@ void usbd_control_stall(uint8_t rhport);
|
||||||
/* Helper
|
/* Helper
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
// helper to parse an pair of In and Out endpoint descriptors. They must be consecutive
|
// helper to parse an pair of In and Out endpoint descriptors. They must be consecutive
|
||||||
tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
|
bool usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
|
||||||
|
|
||||||
void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr );
|
void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr );
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,6 @@
|
||||||
#include "../usbh_hcd.h"
|
#include "../usbh_hcd.h"
|
||||||
#include "ehci.h"
|
#include "ehci.h"
|
||||||
|
|
||||||
// TODO remove
|
|
||||||
#include "chip.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
@ -61,13 +58,8 @@
|
||||||
// Periodic frame list must be 4K alignment
|
// Periodic frame list must be 4K alignment
|
||||||
CFG_TUSB_MEM_SECTION ATTR_ALIGNED(4096) static ehci_data_t ehci_data;
|
CFG_TUSB_MEM_SECTION ATTR_ALIGNED(4096) static ehci_data_t ehci_data;
|
||||||
|
|
||||||
//------------- Validation -------------//
|
// EHCI portable
|
||||||
// TODO static assert for memory placement on some known MCU such as lpc43xx
|
uint32_t hcd_ehci_register_addr(uint8_t rhport);
|
||||||
|
|
||||||
uint32_t hcd_ehci_register_addr(uint8_t rhport)
|
|
||||||
{
|
|
||||||
return (uint32_t) (rhport ? &LPC_USB1->USBCMD_H : &LPC_USB0->USBCMD_H );
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// PROTOTYPE
|
// PROTOTYPE
|
||||||
|
@ -117,7 +109,7 @@ static void qtd_init (ehci_qtd_t* p_qtd, void* buffer, uint16_t total_bytes);
|
||||||
static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
|
static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
|
||||||
static inline ehci_link_t* list_next (ehci_link_t *p_link_pointer);
|
static inline ehci_link_t* list_next (ehci_link_t *p_link_pointer);
|
||||||
|
|
||||||
static bool ehci_init (uint8_t hostid);
|
static bool ehci_init (uint8_t rhport);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// HCD API
|
// HCD API
|
||||||
|
@ -181,7 +173,7 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close all opened endpoint belong to this device
|
// Close all opened endpoint belong to this device
|
||||||
void hcd_device_remove(uint8_t rhport, uint8_t dev_addr)
|
void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
// skip dev0
|
// skip dev0
|
||||||
if (dev_addr == 0) return;
|
if (dev_addr == 0) return;
|
||||||
|
@ -200,9 +192,9 @@ void hcd_device_remove(uint8_t rhport, uint8_t dev_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EHCI controller init
|
// EHCI controller init
|
||||||
static bool ehci_init(uint8_t hostid)
|
static bool ehci_init(uint8_t rhport)
|
||||||
{
|
{
|
||||||
ehci_data.regs = (ehci_registers_t* ) hcd_ehci_register_addr(hostid);
|
ehci_data.regs = (ehci_registers_t* ) hcd_ehci_register_addr(rhport);
|
||||||
|
|
||||||
ehci_registers_t* regs = ehci_data.regs;
|
ehci_registers_t* regs = ehci_data.regs;
|
||||||
|
|
||||||
|
@ -215,7 +207,7 @@ static bool ehci_init(uint8_t hostid)
|
||||||
EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC ;
|
EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC ;
|
||||||
|
|
||||||
//------------- Asynchronous List -------------//
|
//------------- Asynchronous List -------------//
|
||||||
ehci_qhd_t * const async_head = qhd_async_head(hostid);
|
ehci_qhd_t * const async_head = qhd_async_head(rhport);
|
||||||
tu_memclr(async_head, sizeof(ehci_qhd_t));
|
tu_memclr(async_head, sizeof(ehci_qhd_t));
|
||||||
|
|
||||||
async_head->next.address = (uint32_t) async_head; // circular list, next is itself
|
async_head->next.address = (uint32_t) async_head; // circular list, next is itself
|
||||||
|
@ -235,7 +227,7 @@ static bool ehci_init(uint8_t hostid)
|
||||||
}
|
}
|
||||||
|
|
||||||
ehci_link_t * const framelist = ehci_data.period_framelist;
|
ehci_link_t * const framelist = ehci_data.period_framelist;
|
||||||
ehci_link_t * const period_1ms = get_period_head(hostid, 1);
|
ehci_link_t * const period_1ms = get_period_head(rhport, 1);
|
||||||
// all links --> period_head_arr[0] (1ms)
|
// all links --> period_head_arr[0] (1ms)
|
||||||
// 0, 2, 4, 6 etc --> period_head_arr[1] (2ms)
|
// 0, 2, 4, 6 etc --> period_head_arr[1] (2ms)
|
||||||
// 1, 5 --> period_head_arr[2] (4ms)
|
// 1, 5 --> period_head_arr[2] (4ms)
|
||||||
|
@ -250,15 +242,15 @@ static bool ehci_init(uint8_t hostid)
|
||||||
|
|
||||||
for(uint32_t i=0; i<EHCI_FRAMELIST_SIZE; i+=2)
|
for(uint32_t i=0; i<EHCI_FRAMELIST_SIZE; i+=2)
|
||||||
{
|
{
|
||||||
list_insert(framelist + i, get_period_head(hostid, 2), EHCI_QTYPE_QHD);
|
list_insert(framelist + i, get_period_head(rhport, 2), EHCI_QTYPE_QHD);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint32_t i=1; i<EHCI_FRAMELIST_SIZE; i+=4)
|
for(uint32_t i=1; i<EHCI_FRAMELIST_SIZE; i+=4)
|
||||||
{
|
{
|
||||||
list_insert(framelist + i, get_period_head(hostid, 4), EHCI_QTYPE_QHD);
|
list_insert(framelist + i, get_period_head(rhport, 4), EHCI_QTYPE_QHD);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_insert(framelist+3, get_period_head(hostid, 8), EHCI_QTYPE_QHD);
|
list_insert(framelist+3, get_period_head(rhport, 8), EHCI_QTYPE_QHD);
|
||||||
|
|
||||||
period_1ms->terminate = 1;
|
period_1ms->terminate = 1;
|
||||||
|
|
||||||
|
@ -279,7 +271,8 @@ static bool ehci_init(uint8_t hostid)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hcd_controller_stop(uint8_t rhport)
|
#if 0
|
||||||
|
static void ehci_stop(uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
|
@ -290,6 +283,7 @@ static void hcd_controller_stop(uint8_t rhport)
|
||||||
// USB Spec: controller has to stop within 16 uframe = 2 frames
|
// USB Spec: controller has to stop within 16 uframe = 2 frames
|
||||||
while( regs->status_bm.hc_halted == 0 ) {}
|
while( regs->status_bm.hc_halted == 0 ) {}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CONTROL PIPE API
|
// CONTROL PIPE API
|
||||||
|
@ -298,8 +292,8 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
// FIXME control only for now
|
// FIXME control only for now
|
||||||
if ( epnum == 0 )
|
if ( epnum == 0 )
|
||||||
|
@ -382,11 +376,11 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||||
{
|
{
|
||||||
case TUSB_XFER_CONTROL:
|
case TUSB_XFER_CONTROL:
|
||||||
case TUSB_XFER_BULK:
|
case TUSB_XFER_BULK:
|
||||||
list_head = (ehci_link_t*) qhd_async_head(_usbh_devices[dev_addr].rhport);
|
list_head = (ehci_link_t*) qhd_async_head(rhport);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_XFER_INTERRUPT:
|
case TUSB_XFER_INTERRUPT:
|
||||||
list_head = get_period_head(_usbh_devices[dev_addr].rhport, p_qhd->interval_ms);
|
list_head = get_period_head(rhport, p_qhd->interval_ms);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_XFER_ISOCHRONOUS:
|
case TUSB_XFER_ISOCHRONOUS:
|
||||||
|
@ -505,7 +499,7 @@ static void qhd_xfer_complete_isr(ehci_qhd_t * p_qhd)
|
||||||
{
|
{
|
||||||
// end of request
|
// end of request
|
||||||
// call USBH callback
|
// call USBH callback
|
||||||
hcd_event_xfer_complete(p_qhd->dev_addr, edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0), XFER_RESULT_SUCCESS, p_qhd->total_xferred_bytes);
|
hcd_event_xfer_complete(p_qhd->dev_addr, tu_edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0), XFER_RESULT_SUCCESS, p_qhd->total_xferred_bytes);
|
||||||
p_qhd->total_xferred_bytes = 0;
|
p_qhd->total_xferred_bytes = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,7 +586,7 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// call USBH callback
|
// call USBH callback
|
||||||
hcd_event_xfer_complete(p_qhd->dev_addr, edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0), error_event, p_qhd->total_xferred_bytes);
|
hcd_event_xfer_complete(p_qhd->dev_addr, tu_edpt_addr(p_qhd->ep_number, p_qhd->pid == EHCI_PID_IN ? 1 : 0), error_event, p_qhd->total_xferred_bytes);
|
||||||
|
|
||||||
p_qhd->total_xferred_bytes = 0;
|
p_qhd->total_xferred_bytes = 0;
|
||||||
}
|
}
|
||||||
|
@ -718,7 +712,7 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||||
for(uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
for(uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
||||||
{
|
{
|
||||||
if ( (qhd_pool[i].dev_addr == dev_addr) &&
|
if ( (qhd_pool[i].dev_addr == dev_addr) &&
|
||||||
ep_addr == edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) )
|
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) )
|
||||||
{
|
{
|
||||||
return &qhd_pool[i];
|
return &qhd_pool[i];
|
||||||
}
|
}
|
||||||
|
@ -779,7 +773,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
|
||||||
|
|
||||||
p_qhd->dev_addr = dev_addr;
|
p_qhd->dev_addr = dev_addr;
|
||||||
p_qhd->fl_inactive_next_xact = 0;
|
p_qhd->fl_inactive_next_xact = 0;
|
||||||
p_qhd->ep_number = edpt_number(ep_desc->bEndpointAddress);
|
p_qhd->ep_number = tu_edpt_number(ep_desc->bEndpointAddress);
|
||||||
p_qhd->ep_speed = _usbh_devices[dev_addr].speed;
|
p_qhd->ep_speed = _usbh_devices[dev_addr].speed;
|
||||||
p_qhd->data_toggle_control= (xfer_type == TUSB_XFER_CONTROL) ? 1 : 0;
|
p_qhd->data_toggle_control= (xfer_type == TUSB_XFER_CONTROL) ? 1 : 0;
|
||||||
p_qhd->head_list_flag = (dev_addr == 0) ? 1 : 0; // addr0's endpoint is the static asyn list head
|
p_qhd->head_list_flag = (dev_addr == 0) ? 1 : 0; // addr0's endpoint is the static asyn list head
|
||||||
|
@ -826,7 +820,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
|
||||||
p_qhd->removing = 0;
|
p_qhd->removing = 0;
|
||||||
p_qhd->p_qtd_list_head = NULL;
|
p_qhd->p_qtd_list_head = NULL;
|
||||||
p_qhd->p_qtd_list_tail = NULL;
|
p_qhd->p_qtd_list_tail = NULL;
|
||||||
p_qhd->pid = edpt_dir(ep_desc->bEndpointAddress) ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint
|
p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint
|
||||||
|
|
||||||
//------------- active, but no TD list -------------//
|
//------------- active, but no TD list -------------//
|
||||||
p_qhd->qtd_overlay.halted = 0;
|
p_qhd->qtd_overlay.halted = 0;
|
||||||
|
|
|
@ -108,8 +108,8 @@ bool hcd_port_connect_status(uint8_t hostid);
|
||||||
void hcd_port_reset(uint8_t hostid);
|
void hcd_port_reset(uint8_t hostid);
|
||||||
tusb_speed_t hcd_port_speed_get(uint8_t hostid);
|
tusb_speed_t hcd_port_speed_get(uint8_t hostid);
|
||||||
|
|
||||||
// HCD closs all opened endpoints belong to this device
|
// HCD closes all opened endpoints belong to this device
|
||||||
void hcd_device_remove(uint8_t rhport, uint8_t dev_addr);
|
void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Event function
|
// Event function
|
||||||
|
@ -135,7 +135,7 @@ bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr);
|
||||||
bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr);
|
bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr);
|
||||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr);
|
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr);
|
||||||
|
|
||||||
|
// TODO merge with pipe_xfer
|
||||||
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
|
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
|
@ -156,21 +156,21 @@ void hub_init(void)
|
||||||
// hub_enum_sem_hdl = osal_semaphore_create( OSAL_SEM_REF(hub_enum_semaphore) );
|
// hub_enum_sem_hdl = osal_semaphore_create( OSAL_SEM_REF(hub_enum_semaphore) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
|
bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
// not support multiple TT yet
|
// not support multiple TT yet
|
||||||
if ( p_interface_desc->bInterfaceProtocol > 1 ) return false;
|
if ( itf_desc->bInterfaceProtocol > 1 ) return false;
|
||||||
|
|
||||||
//------------- Open Interrupt Status Pipe -------------//
|
//------------- Open Interrupt Status Pipe -------------//
|
||||||
tusb_desc_endpoint_t const *ep_desc;
|
tusb_desc_endpoint_t const *ep_desc;
|
||||||
ep_desc = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_interface_desc );
|
ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
|
||||||
|
|
||||||
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
|
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
|
||||||
TU_ASSERT(TUSB_XFER_INTERRUPT == ep_desc->bmAttributes.xfer);
|
TU_ASSERT(TUSB_XFER_INTERRUPT == ep_desc->bmAttributes.xfer);
|
||||||
|
|
||||||
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
||||||
|
|
||||||
hub_data[dev_addr-1].itf_num = p_interface_desc->bInterfaceNumber;
|
hub_data[dev_addr-1].itf_num = itf_desc->bInterfaceNumber;
|
||||||
hub_data[dev_addr-1].ep_status = ep_desc->bEndpointAddress;
|
hub_data[dev_addr-1].ep_status = ep_desc->bEndpointAddress;
|
||||||
|
|
||||||
(*p_length) = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t);
|
(*p_length) = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t);
|
||||||
|
@ -245,7 +245,7 @@ void hub_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xf
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO [HUB] check if hub is still plugged before polling status endpoint since failed usually mean hub unplugged
|
// TODO [HUB] check if hub is still plugged before polling status endpoint since failed usually mean hub unplugged
|
||||||
// TU_ASSERT ( TUSB_ERROR_NONE == hcd_pipe_xfer(pipe_hdl, &p_hub->status_change, 1, true) );
|
// TU_ASSERT ( hub_status_pipe_queue(dev_addr) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ tusb_speed_t hcd_port_speed_get(uint8_t hostid)
|
||||||
|
|
||||||
// endpoints are tied to an address, which only reclaim after a long delay when enumerating
|
// endpoints are tied to an address, which only reclaim after a long delay when enumerating
|
||||||
// thus there is no need to make sure ED is not in HC's cahed as it will not for sure
|
// thus there is no need to make sure ED is not in HC's cahed as it will not for sure
|
||||||
void hcd_device_remove(uint8_t rhport, uint8_t dev_addr)
|
void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
// TODO OHCI
|
// TODO OHCI
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
@ -315,8 +315,8 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
// FIXME control only for now
|
// FIXME control only for now
|
||||||
if ( epnum == 0 )
|
if ( epnum == 0 )
|
||||||
|
@ -344,14 +344,14 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
static inline ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
if ( edpt_number(ep_addr) == 0 ) return &ohci_data.control[dev_addr].ed;
|
if ( tu_edpt_number(ep_addr) == 0 ) return &ohci_data.control[dev_addr].ed;
|
||||||
|
|
||||||
ohci_ed_t* ed_pool = ohci_data.ed_pool;
|
ohci_ed_t* ed_pool = ohci_data.ed_pool;
|
||||||
|
|
||||||
for(uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
for(uint32_t i=0; i<HCD_MAX_ENDPOINT; i++)
|
||||||
{
|
{
|
||||||
if ( (ed_pool[i].dev_addr == dev_addr) &&
|
if ( (ed_pool[i].dev_addr == dev_addr) &&
|
||||||
ep_addr == edpt_addr(ed_pool[i].ep_number, ed_pool[i].pid == OHCI_PID_IN) )
|
ep_addr == tu_edpt_addr(ed_pool[i].ep_number, ed_pool[i].pid == OHCI_PID_IN) )
|
||||||
{
|
{
|
||||||
return &ed_pool[i];
|
return &ed_pool[i];
|
||||||
}
|
}
|
||||||
|
@ -603,7 +603,7 @@ static void done_queue_isr(uint8_t hostid)
|
||||||
}
|
}
|
||||||
|
|
||||||
hcd_event_xfer_complete(p_ed->dev_addr,
|
hcd_event_xfer_complete(p_ed->dev_addr,
|
||||||
edpt_addr(p_ed->ep_number, p_ed->pid == OHCI_PID_IN),
|
tu_edpt_addr(p_ed->ep_number, p_ed->pid == OHCI_PID_IN),
|
||||||
event, xferred_bytes);
|
event, xferred_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,12 +205,12 @@ bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t* request, uint8
|
||||||
// Data stage : first data toggle is always 1
|
// Data stage : first data toggle is always 1
|
||||||
if ( request->wLength )
|
if ( request->wLength )
|
||||||
{
|
{
|
||||||
hcd_edpt_xfer(rhport, dev_addr, edpt_addr(0, request->bmRequestType_bit.direction), data, request->wLength);
|
hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), data, request->wLength);
|
||||||
TU_VERIFY(osal_semaphore_wait(dev->control.sem_hdl, OSAL_TIMEOUT_NORMAL));
|
TU_VERIFY(osal_semaphore_wait(dev->control.sem_hdl, OSAL_TIMEOUT_NORMAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status : data toggle is always 1
|
// Status : data toggle is always 1
|
||||||
hcd_edpt_xfer(rhport, dev_addr, edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
|
hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
|
||||||
TU_VERIFY(osal_semaphore_wait(dev->control.sem_hdl, OSAL_TIMEOUT_NORMAL));
|
TU_VERIFY(osal_semaphore_wait(dev->control.sem_hdl, OSAL_TIMEOUT_NORMAL));
|
||||||
|
|
||||||
osal_mutex_unlock(dev->control.mutex_hdl);
|
osal_mutex_unlock(dev->control.mutex_hdl);
|
||||||
|
@ -249,7 +249,7 @@ void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t ev
|
||||||
{
|
{
|
||||||
usbh_device_t* dev = &_usbh_devices[ dev_addr ];
|
usbh_device_t* dev = &_usbh_devices[ dev_addr ];
|
||||||
|
|
||||||
if (0 == edpt_number(ep_addr))
|
if (0 == tu_edpt_number(ep_addr))
|
||||||
{
|
{
|
||||||
dev->control.pipe_status = event;
|
dev->control.pipe_status = event;
|
||||||
// usbh_devices[ pipe_hdl.dev_addr ].control.xferred_bytes = xferred_bytes; not yet neccessary
|
// usbh_devices[ pipe_hdl.dev_addr ].control.xferred_bytes = xferred_bytes; not yet neccessary
|
||||||
|
@ -257,7 +257,7 @@ void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t ev
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t drv_id = dev->ep2drv[edpt_number(ep_addr)][edpt_dir(ep_addr)];
|
uint8_t drv_id = dev->ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)];
|
||||||
TU_ASSERT(drv_id < USBH_CLASS_DRIVER_COUNT, );
|
TU_ASSERT(drv_id < USBH_CLASS_DRIVER_COUNT, );
|
||||||
|
|
||||||
if (usbh_class_drivers[drv_id].isr)
|
if (usbh_class_drivers[drv_id].isr)
|
||||||
|
@ -334,7 +334,7 @@ static void usbh_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_
|
||||||
memset(dev->itf2drv, 0xff, sizeof(dev->itf2drv)); // invalid mapping
|
memset(dev->itf2drv, 0xff, sizeof(dev->itf2drv)); // invalid mapping
|
||||||
memset(dev->ep2drv , 0xff, sizeof(dev->ep2drv )); // invalid mapping
|
memset(dev->ep2drv , 0xff, sizeof(dev->ep2drv )); // invalid mapping
|
||||||
|
|
||||||
hcd_device_remove(rhport, dev_addr);
|
hcd_device_close(rhport, dev_addr);
|
||||||
|
|
||||||
dev->state = TUSB_DEVICE_STATE_UNPLUG;
|
dev->state = TUSB_DEVICE_STATE_UNPLUG;
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,6 @@ bool enum_task(hcd_event_t* event)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TU_ASSERT_ERR( usbh_pipe_control_open(0, 8) );
|
TU_ASSERT_ERR( usbh_pipe_control_open(0, 8) );
|
||||||
dev0->state = TUSB_DEVICE_STATE_ADDRESSED;
|
|
||||||
|
|
||||||
//------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
|
//------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
|
||||||
request = (tusb_control_request_t ) {
|
request = (tusb_control_request_t ) {
|
||||||
|
@ -493,9 +492,8 @@ bool enum_task(hcd_event_t* event)
|
||||||
new_dev->hub_addr = dev0->hub_addr;
|
new_dev->hub_addr = dev0->hub_addr;
|
||||||
new_dev->hub_port = dev0->hub_port;
|
new_dev->hub_port = dev0->hub_port;
|
||||||
new_dev->speed = dev0->speed;
|
new_dev->speed = dev0->speed;
|
||||||
new_dev->state = TUSB_DEVICE_STATE_ADDRESSED;
|
|
||||||
|
|
||||||
hcd_device_remove(dev0->rhport, 0); // close device 0
|
hcd_device_close(dev0->rhport, 0); // close device 0
|
||||||
dev0->state = TUSB_DEVICE_STATE_UNPLUG;
|
dev0->state = TUSB_DEVICE_STATE_UNPLUG;
|
||||||
|
|
||||||
// open control pipe for new address
|
// open control pipe for new address
|
||||||
|
@ -560,9 +558,9 @@ bool enum_task(hcd_event_t* event)
|
||||||
while( p_desc < _usbh_ctrl_buf + ((tusb_desc_configuration_t*)_usbh_ctrl_buf)->wTotalLength )
|
while( p_desc < _usbh_ctrl_buf + ((tusb_desc_configuration_t*)_usbh_ctrl_buf)->wTotalLength )
|
||||||
{
|
{
|
||||||
// skip until we see interface descriptor
|
// skip until we see interface descriptor
|
||||||
if ( TUSB_DESC_INTERFACE != descriptor_type(p_desc) )
|
if ( TUSB_DESC_INTERFACE != tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
p_desc = descriptor_next(p_desc); // skip the descriptor, increase by the descriptor's length
|
p_desc = tu_desc_next(p_desc); // skip the descriptor, increase by the descriptor's length
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;
|
tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;
|
||||||
|
@ -577,7 +575,7 @@ bool enum_task(hcd_event_t* event)
|
||||||
if( drv_id >= USBH_CLASS_DRIVER_COUNT )
|
if( drv_id >= USBH_CLASS_DRIVER_COUNT )
|
||||||
{
|
{
|
||||||
// skip unsupported class
|
// skip unsupported class
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -589,7 +587,7 @@ bool enum_task(hcd_event_t* event)
|
||||||
{
|
{
|
||||||
// TODO Attach hub to Hub is not currently supported
|
// TODO Attach hub to Hub is not currently supported
|
||||||
// skip this interface
|
// skip this interface
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -655,13 +653,11 @@ void usbh_task(void* param)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline uint8_t get_new_address(void)
|
static inline uint8_t get_new_address(void)
|
||||||
{
|
{
|
||||||
uint8_t addr;
|
for (uint8_t addr=1; addr <= CFG_TUSB_HOST_DEVICE_MAX; addr++)
|
||||||
for (addr=1; addr <= CFG_TUSB_HOST_DEVICE_MAX; addr++)
|
|
||||||
{
|
{
|
||||||
if (_usbh_devices[addr].state == TUSB_DEVICE_STATE_UNPLUG)
|
if (_usbh_devices[addr].state == TUSB_DEVICE_STATE_UNPLUG) return addr;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return addr;
|
return CFG_TUSB_HOST_DEVICE_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t get_configure_number_for_device(tusb_desc_device_t* dev_desc)
|
static inline uint8_t get_configure_number_for_device(tusb_desc_device_t* dev_desc)
|
||||||
|
@ -685,15 +681,15 @@ static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc,
|
||||||
|
|
||||||
while( len < desc_len )
|
while( len < desc_len )
|
||||||
{
|
{
|
||||||
if ( TUSB_DESC_ENDPOINT == descriptor_type(p_desc) )
|
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
|
uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
|
||||||
|
|
||||||
ep2drv[ edpt_number(ep_addr) ][ edpt_dir(ep_addr) ] = driver_id;
|
ep2drv[ tu_edpt_number(ep_addr) ][ tu_edpt_dir(ep_addr) ] = driver_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
len += descriptor_len(p_desc);
|
len += tu_desc_len(p_desc);
|
||||||
p_desc = descriptor_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,8 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress);
|
uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
|
||||||
uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress);
|
uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress);
|
||||||
|
|
||||||
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
||||||
uint32_t size_value = 0;
|
uint32_t size_value = 0;
|
||||||
|
@ -168,8 +168,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
@ -208,19 +208,19 @@ bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
return (edpt_dir(ep_addr) == TUSB_DIR_IN ) ? ep->EPINTFLAG.bit.STALL1 : ep->EPINTFLAG.bit.STALL0;
|
return (tu_edpt_dir(ep_addr) == TUSB_DIR_IN ) ? ep->EPINTFLAG.bit.STALL1 : ep->EPINTFLAG.bit.STALL0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
|
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
|
||||||
} else {
|
} else {
|
||||||
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
|
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
|
||||||
|
@ -236,10 +236,10 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
|
||||||
} else {
|
} else {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
|
||||||
|
@ -253,10 +253,10 @@ bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr)
|
||||||
// USBD shouldn't check control endpoint state
|
// USBD shouldn't check control endpoint state
|
||||||
if ( 0 == ep_addr ) return false;
|
if ( 0 == ep_addr ) return false;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1;
|
return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1;
|
||||||
}
|
}
|
||||||
return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1;
|
return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1;
|
||||||
|
|
|
@ -137,8 +137,8 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress);
|
uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
|
||||||
uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress);
|
uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress);
|
||||||
|
|
||||||
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
||||||
uint32_t size_value = 0;
|
uint32_t size_value = 0;
|
||||||
|
@ -173,8 +173,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
UsbDeviceDescBank* bank = &sram_registers[epnum][dir];
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
@ -212,19 +212,19 @@ bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
return (edpt_dir(ep_addr) == TUSB_DIR_IN ) ? ep->EPINTFLAG.bit.STALL1 : ep->EPINTFLAG.bit.STALL0;
|
return (tu_edpt_dir(ep_addr) == TUSB_DIR_IN ) ? ep->EPINTFLAG.bit.STALL1 : ep->EPINTFLAG.bit.STALL0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
|
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
|
||||||
} else {
|
} else {
|
||||||
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
|
ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
|
||||||
|
@ -240,10 +240,10 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
|
||||||
} else {
|
} else {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
|
||||||
|
@ -257,10 +257,10 @@ bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr)
|
||||||
// USBD shouldn't check control endpoint state
|
// USBD shouldn't check control endpoint state
|
||||||
if ( 0 == ep_addr ) return false;
|
if ( 0 == ep_addr ) return false;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1;
|
return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1;
|
||||||
}
|
}
|
||||||
return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1;
|
return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1;
|
||||||
|
|
|
@ -225,8 +225,8 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress);
|
uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
|
||||||
uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress);
|
uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress);
|
||||||
|
|
||||||
_dcd.xfer[epnum][dir].mps = desc_edpt->wMaxPacketSize.size;
|
_dcd.xfer[epnum][dir].mps = desc_edpt->wMaxPacketSize.size;
|
||||||
|
|
||||||
|
@ -248,8 +248,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
xfer_td_t* xfer = get_td(epnum, dir);
|
xfer_td_t* xfer = get_td(epnum, dir);
|
||||||
|
|
||||||
|
@ -295,15 +295,15 @@ bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
|
||||||
// control is never got halted
|
// control is never got halted
|
||||||
if ( ep_addr == 0 ) return false;
|
if ( ep_addr == 0 ) return false;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
return (edpt_dir(ep_addr) == TUSB_DIR_IN ) ? NRF_USBD->HALTED.EPIN[epnum] : NRF_USBD->HALTED.EPOUT[epnum];
|
return (tu_edpt_dir(ep_addr) == TUSB_DIR_IN ) ? NRF_USBD->HALTED.EPIN[epnum] : NRF_USBD->HALTED.EPOUT[epnum];
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
if ( edpt_number(ep_addr) == 0 )
|
if ( tu_edpt_number(ep_addr) == 0 )
|
||||||
{
|
{
|
||||||
NRF_USBD->TASKS_EP0STALL = 1;
|
NRF_USBD->TASKS_EP0STALL = 1;
|
||||||
}else
|
}else
|
||||||
|
@ -318,7 +318,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
if ( edpt_number(ep_addr) )
|
if ( tu_edpt_number(ep_addr) )
|
||||||
{
|
{
|
||||||
NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr;
|
NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr;
|
||||||
__ISB(); __DSB();
|
__ISB(); __DSB();
|
||||||
|
@ -330,10 +330,10 @@ bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr)
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
// USBD shouldn't check control endpoint state
|
// USBD shouldn't check control endpoint state
|
||||||
if ( 0 == edpt_number(ep_addr) ) return false;
|
if ( 0 == tu_edpt_number(ep_addr) ) return false;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
xfer_td_t* xfer = get_td(epnum, dir);
|
xfer_td_t* xfer = get_td(epnum, dir);
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
if ( edpt_number(ep_addr) == 0 )
|
if ( tu_edpt_number(ep_addr) == 0 )
|
||||||
{
|
{
|
||||||
// TODO cannot able to STALL Control OUT endpoint !!!!! FIXME try some walk-around
|
// TODO cannot able to STALL Control OUT endpoint !!!!! FIXME try some walk-around
|
||||||
_dcd.ep[0][0].stall = _dcd.ep[1][0].stall = 1;
|
_dcd.ep[0][0].stall = _dcd.ep[1][0].stall = 1;
|
||||||
|
@ -209,11 +209,11 @@ bool dcd_edpt_stalled(uint8_t rhport, uint8_t ep_addr)
|
||||||
return _dcd.ep[ep_id][0].stall;
|
return _dcd.ep[ep_id][0].stall;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t edpt_addr)
|
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const ep_id = ep_addr2id(edpt_addr);
|
uint8_t const ep_id = ep_addr2id(ep_addr);
|
||||||
|
|
||||||
_dcd.ep[ep_id][0].stall = 0;
|
_dcd.ep[ep_id][0].stall = 0;
|
||||||
_dcd.ep[ep_id][0].toggle_reset = 1;
|
_dcd.ep[ep_id][0].toggle_reset = 1;
|
||||||
|
|
|
@ -285,7 +285,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(p_endpoint_desc->bEndpointAddress);
|
uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
|
||||||
uint8_t const ep_id = ep_addr2idx(p_endpoint_desc->bEndpointAddress);
|
uint8_t const ep_id = ep_addr2idx(p_endpoint_desc->bEndpointAddress);
|
||||||
|
|
||||||
// Endpoint type is fixed to endpoint number
|
// Endpoint type is fixed to endpoint number
|
||||||
|
@ -336,7 +336,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
if ( edpt_number(ep_addr) == 0 )
|
if ( tu_edpt_number(ep_addr) == 0 )
|
||||||
{
|
{
|
||||||
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK);
|
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK);
|
||||||
}else
|
}else
|
||||||
|
@ -394,9 +394,9 @@ static bool control_xact(uint8_t rhport, uint8_t dir, uint8_t * buffer, uint8_t
|
||||||
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
|
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
|
||||||
{
|
{
|
||||||
// Control transfer is not DMA support, and must be done in slave mode
|
// Control transfer is not DMA support, and must be done in slave mode
|
||||||
if ( edpt_number(ep_addr) == 0 )
|
if ( tu_edpt_number(ep_addr) == 0 )
|
||||||
{
|
{
|
||||||
return control_xact(rhport, edpt_dir(ep_addr), buffer, (uint8_t) total_bytes);
|
return control_xact(rhport, tu_edpt_dir(ep_addr), buffer, (uint8_t) total_bytes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -205,8 +205,8 @@ static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
if ( epnum == 0)
|
if ( epnum == 0)
|
||||||
{
|
{
|
||||||
|
@ -220,16 +220,16 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||||
|
|
||||||
bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
|
bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
return LPC_USB[rhport]->ENDPTCTRL[epnum] & (ENDPTCTRL_MASK_STALL << (dir ? 16 : 0));
|
return LPC_USB[rhport]->ENDPTCTRL[epnum] & (ENDPTCTRL_MASK_STALL << (dir ? 16 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
// data toggle also need to be reset
|
// data toggle also need to be reset
|
||||||
LPC_USB[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_TOGGLE_RESET << ( dir ? 16 : 0 );
|
LPC_USB[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_TOGGLE_RESET << ( dir ? 16 : 0 );
|
||||||
|
@ -241,8 +241,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
|
||||||
// TODO not support ISO yet
|
// TODO not support ISO yet
|
||||||
TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
|
TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
|
||||||
|
|
||||||
uint8_t const epnum = edpt_number(p_endpoint_desc->bEndpointAddress);
|
uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
|
||||||
uint8_t const dir = edpt_dir(p_endpoint_desc->bEndpointAddress);
|
uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
|
||||||
uint8_t const ep_idx = 2*epnum + dir;
|
uint8_t const ep_idx = 2*epnum + dir;
|
||||||
|
|
||||||
// USB0 has 5, USB1 has 3 non-control endpoints
|
// USB0 has 5, USB1 has 3 non-control endpoints
|
||||||
|
@ -264,8 +264,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
|
||||||
|
|
||||||
bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
|
bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
uint8_t const ep_idx = 2*epnum + dir;
|
uint8_t const ep_idx = 2*epnum + dir;
|
||||||
|
|
||||||
dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx];
|
dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx];
|
||||||
|
@ -276,8 +276,8 @@ bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
|
||||||
|
|
||||||
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
|
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
|
||||||
{
|
{
|
||||||
uint8_t const epnum = edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
uint8_t const ep_idx = 2*epnum + dir;
|
uint8_t const ep_idx = 2*epnum + dir;
|
||||||
|
|
||||||
if ( epnum == 0 )
|
if ( epnum == 0 )
|
||||||
|
|
|
@ -42,9 +42,7 @@
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
// LPC18xx and 43xx use EHCI driver
|
||||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void hcd_int_enable(uint8_t rhport)
|
void hcd_int_enable(uint8_t rhport)
|
||||||
{
|
{
|
||||||
|
@ -55,4 +53,10 @@ void hcd_int_disable(uint8_t rhport)
|
||||||
{
|
{
|
||||||
NVIC_DisableIRQ(rhport ? USB1_IRQn : USB0_IRQn);
|
NVIC_DisableIRQ(rhport ? USB1_IRQn : USB0_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t hcd_ehci_register_addr(uint8_t rhport)
|
||||||
|
{
|
||||||
|
return (uint32_t) (rhport ? &LPC_USB1->USBCMD_H : &LPC_USB0->USBCMD_H );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
#define CFG_TUSB_HOST_DEVICE_MAX 5 // TODO be a part of HUB config
|
#define CFG_TUSB_HOST_DEVICE_MAX 5 // TODO be a part of HUB config
|
||||||
|
|
||||||
//------------- CLASS -------------//
|
//------------- CLASS -------------//
|
||||||
#define CFG_TUH_HUB 0
|
#define CFG_TUH_HUB 1
|
||||||
#define CFG_TUH_HID_KEYBOARD 1
|
#define CFG_TUH_HID_KEYBOARD 1
|
||||||
#define CFG_TUH_HID_MOUSE 1
|
#define CFG_TUH_HID_MOUSE 1
|
||||||
#define CFG_TUH_MSC 1
|
#define CFG_TUH_MSC 1
|
||||||
|
|
Loading…
Reference in New Issue