Skip to content

Commit

Permalink
Merge pull request #2542 from hathach/max3421-hcd-deinit
Browse files Browse the repository at this point in the history
implement hcd_deinit() for max3421
  • Loading branch information
hathach authored Mar 26, 2024
2 parents 5b0e255 + 64bc0aa commit 0cb7204
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 19 deletions.
47 changes: 36 additions & 11 deletions docs/reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
=======
Expand Down
35 changes: 27 additions & 8 deletions src/portable/analog/max3421/hcd_max3421.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 0cb7204

Please sign in to comment.