Merge pull request #2542 from hathach/max3421-hcd-deinit

implement hcd_deinit() for max3421
This commit is contained in:
Ha Thach 2024-03-26 11:45:52 +07:00 committed by GitHub
commit 0cb7204e60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 19 deletions

View File

@ -4,44 +4,69 @@ Reference
.. figure:: ../assets/stack.svg
:width: 1600px
:alt: stackup
:alt: TinyUSB
::
.
├── docs # Documentation
├── examples # Examples with make and cmake build system
├── hw
│ ├── bsp # Supported boards source files
│ └── mcu # Low level mcu core & peripheral drivers
├── lib # Sources from 3rd party such as freeRTOS, fatfs ...
├── src # All sources files for TinyUSB stack itself.
├── test # Tests: unit test, fuzzing, hardware test
└── tools # Files used internally
representation of the TinyUSB stack.
Device Stack
============
Supports multiple device configurations by dynamically changing usb descriptors. Low power functions such like suspend, resume, and remote wakeup. Following device classes are supported:
Supports multiple device configurations by dynamically changing USB descriptors, low power functions such like suspend, resume, and remote wakeup. The following device classes are supported:
- Audio Class 2.0 (UAC2)
- Bluetooth Host Controller Interface (BTH HCI)
- Communication Class (CDC)
- Device Firmware Update (DFU): DFU mode (WIP) and Runtinme
- Communication Device Class (CDC)
- Device Firmware Update (DFU): DFU mode (WIP) and Runtime
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
- Mass Storage Class (MSC): with multiple LUNs
- Musical Instrument Digital Interface (MIDI)
- Network with RNDIS, CDC-ECM (work in progress)
- USB Test and Measurement Class (USBTMC)
- Network with RNDIS, Ethernet Control Model (ECM), Network Control Model (NCM)
- Test and Measurement Class (USBTMC)
- Video class 1.5 (UVC): work in progress
- Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file.
- `WebUSB <https://github.com/WICG/webusb>`__ with vendor-specific class
If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface `raspberrypi/pico-sdk#197 <https://github.com/raspberrypi/pico-sdk/pull/197>`__
If you have a special requirement, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 <https://github.com/raspberrypi/pico-sdk/pull/197>`_
Host Stack
==========
- Human Interface Device (HID): Keyboard, Mouse, Generic
- Mass Storage Class (MSC)
- Hub currently only supports 1 level of hub (due to my laziness)
- Communication Device Class: CDC-ACM
- Vendor serial over USB: FTDI, CP210x
- Hub with multiple-level support
Similar to the Device Stack, if you have a special requirement, `usbh_app_driver_get_cb()` can be used to write your own class driver without modifying the stack.
TypeC PD Stack
==============
- Power Delivery 3.0 (PD3.0) with USB Type-C support (WIP)
- Super early stage, only for testing purpose
- Only support STM32 G4
OS Abstraction layer
====================
TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box.
TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) events into a central queue, then processing them later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as Communication Device Class (CDC) FIFO. Therefore the stack needs to use some of the OS's basic APIs. Following OSes are already supported out of the box.
- **No OS**
- **FreeRTOS**
- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo <https://github.com/hathach/mynewt-tinyusb-example>`__
- `RT-Thread <https://github.com/RT-Thread/rt-thread>`_: `repo <https://github.com/RT-Thread-packages/tinyusb>`_
- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo <https://github.com/hathach/mynewt-tinyusb-example>`_
License
=======

View File

@ -321,35 +321,35 @@ static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_is
}
//------------- register write helper -------------//
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) {
reg_write(rhport, HIRQ_ADDR, data, in_isr);
// HIRQ write 1 is clear
_hcd_data.hirq &= (uint8_t) ~data;
}
static inline void hien_write(uint8_t rhport, uint8_t data, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline void hien_write(uint8_t rhport, uint8_t data, bool in_isr) {
_hcd_data.hien = data;
reg_write(rhport, HIEN_ADDR, data, in_isr);
}
static inline void mode_write(uint8_t rhport, uint8_t data, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline void mode_write(uint8_t rhport, uint8_t data, bool in_isr) {
_hcd_data.mode = data;
reg_write(rhport, MODE_ADDR, data, in_isr);
}
static inline void peraddr_write(uint8_t rhport, uint8_t data, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline void peraddr_write(uint8_t rhport, uint8_t data, bool in_isr) {
if ( _hcd_data.peraddr == data ) return; // no need to change address
_hcd_data.peraddr = data;
reg_write(rhport, PERADDR_ADDR, data, in_isr);
}
static inline void hxfr_write(uint8_t rhport, uint8_t data, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline void hxfr_write(uint8_t rhport, uint8_t data, bool in_isr) {
_hcd_data.hxfr = data;
reg_write(rhport, HXFR_ADDR, data, in_isr);
}
static inline void sndbc_write(uint8_t rhport, uint8_t data, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t data, bool in_isr) {
_hcd_data.sndbc = data;
reg_write(rhport, SNDBC_ADDR, data, in_isr);
}
@ -449,7 +449,7 @@ bool hcd_init(uint8_t rhport) {
// full duplex, interrupt negative edge
reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false);
// V1 is 0x01, V2 is 0x12, V3 is 0x13
// v1 is 0x01, v2 is 0x12, v3 is 0x13
uint8_t const revision = reg_read(rhport, REVISION_ADDR, false);
TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false);
TU_LOG2_HEX(revision);
@ -481,6 +481,24 @@ bool hcd_init(uint8_t rhport) {
return true;
}
bool hcd_deinit(uint8_t rhport) {
(void) rhport;
// disable interrupt
tuh_max3421_int_api(rhport, false);
// reset max3421
reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false);
reg_write(rhport, USBCTL_ADDR, 0, false);
#if OSAL_MUTEX_REQUIRED
osal_mutex_delete(_hcd_data.spi_mutex);
_hcd_data.spi_mutex = NULL;
#endif
return true;
}
// Enable USB interrupt
// Not actually enable GPIO interrupt, just set variable to prevent handler to process
void hcd_int_enable (uint8_t rhport) {
@ -598,7 +616,8 @@ void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
hxfr_write(rhport, hxfr, in_isr);
}
TU_ATTR_ALWAYS_INLINE static inline void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
TU_ATTR_ALWAYS_INLINE static inline
void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
if (ep->ep_num == 0 ) {
// setup
if (ep->is_setup) {