mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
commit
616562a48a
25
.gitattributes
vendored
Normal file
25
.gitattributes
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
*.c text
|
||||||
|
*.cpp text
|
||||||
|
*.h text
|
||||||
|
*.icf text
|
||||||
|
*.js text
|
||||||
|
*.json text
|
||||||
|
*.ld text
|
||||||
|
*.md text
|
||||||
|
*.mk text
|
||||||
|
*.py text
|
||||||
|
*.rst text
|
||||||
|
*.s text
|
||||||
|
*.txt text
|
||||||
|
*.xml text
|
||||||
|
*.yml text
|
||||||
|
|
||||||
|
Makefile text
|
||||||
|
|
||||||
|
# Windows-only Visual Studio things
|
||||||
|
|
||||||
|
*.sln text eol=crlf
|
||||||
|
*.csproj text eol=crlf
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -24,7 +24,8 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example: ['board_test', 'cdc_msc', 'dfu_rt', 'hid_composite', 'hid_generic_inout', 'midi_test', 'msc_dual_lun', 'usbtmc', 'webusb_serial']
|
example: ['board_test', 'cdc_dual_ports', 'cdc_msc', 'dfu_rt', 'hid_composite',
|
||||||
|
'hid_generic_inout', 'midi_test', 'msc_dual_lun', 'usbtmc', 'webusb_serial']
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
@ -52,3 +53,4 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: python3 tools/build_all.py ${{ matrix.example }}
|
run: python3 tools/build_all.py ${{ matrix.example }}
|
||||||
|
|
||||||
|
14
.github/workflows/trigger.yml
vendored
Normal file
14
.github/workflows/trigger.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: Trigger Repos
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
trigger:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mynewt-tinyusb-example
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Authorization: token ${{ secrets.GH_REPO_TOKEN }}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" --data '{"event_type": "rebuild"}' https://api.github.com/repos/hathach/mynewt-tinyusb-example/dispatches
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -19,3 +19,6 @@
|
|||||||
[submodule "hw/mcu/microchip"]
|
[submodule "hw/mcu/microchip"]
|
||||||
path = hw/mcu/microchip
|
path = hw/mcu/microchip
|
||||||
url = https://github.com/hathach/microchip_driver.git
|
url = https://github.com/hathach/microchip_driver.git
|
||||||
|
[submodule "hw/mcu/nuvoton"]
|
||||||
|
path = hw/mcu/nuvoton
|
||||||
|
url = https://github.com/majbthrd/nuc_driver.git
|
@ -23,6 +23,11 @@
|
|||||||
* USBTMC class driver support with example
|
* USBTMC class driver support with example
|
||||||
* Various improvement e.g Zero-length packet, Lint setup
|
* Various improvement e.g Zero-length packet, Lint setup
|
||||||
* Board support for STM32F070RB Nucleo, STM32F303 Discovery
|
* Board support for STM32F070RB Nucleo, STM32F303 Discovery
|
||||||
|
|
||||||
|
* **[Peter Lawrence](https://github.com/majbthrd)**
|
||||||
|
* Nuvoton NUC 121, 125, 126 device driver port
|
||||||
|
* Board support for NuTiny NUC121s, NUC125s, NUC126V
|
||||||
|
* Complete multiple class interfaces & add cdc_dual_ports example
|
||||||
|
|
||||||
* **[Scott Shawcroft](https://github.com/tannewt)**
|
* **[Scott Shawcroft](https://github.com/tannewt)**
|
||||||
* SAMD21 and SAMD51 device driver port
|
* SAMD21 and SAMD51 device driver port
|
||||||
|
23
README.md
23
README.md
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
![tinyUSB_240x100](https://user-images.githubusercontent.com/249515/62646655-f9393200-b978-11e9-9c53-484862f15503.png)
|
![tinyUSB_240x100](https://user-images.githubusercontent.com/249515/62646655-f9393200-b978-11e9-9c53-484862f15503.png)
|
||||||
|
|
||||||
[![Build Status](https://github.com/hathach/tinyusb/workflows/Build/badge.svg)](https://travis-ci.org/hathach/tinyusb) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) [![Coverity](https://img.shields.io/coverity/scan/458.svg)](https://scan.coverity.com/projects/tinyusb)
|
[![Build Status](https://github.com/hathach/tinyusb/workflows/Build/badge.svg)](https://github.com/hathach/tinyusb/actions) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) [![Coverity](https://img.shields.io/coverity/scan/458.svg)](https://scan.coverity.com/projects/tinyusb)
|
||||||
|
|
||||||
TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.
|
TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.
|
||||||
|
|
||||||
@ -23,12 +23,12 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst
|
|||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
Special thanks for all the people who had spent their precious time and effort to helped this project so far. Check out
|
Special thanks to all the people who spent their precious time and effort to help this project so far. Check out the
|
||||||
[CONTRIBUTORS.md](CONTRIBUTORS.md) file for the list of all contributors and their awesome work for the stack.
|
[CONTRIBUTORS.md](CONTRIBUTORS.md) file for the list of all contributors and their awesome work for the stack.
|
||||||
|
|
||||||
## Supported MCUs
|
## Supported MCUs
|
||||||
|
|
||||||
The stack supports the following MCUs
|
The stack supports the following MCUs:
|
||||||
|
|
||||||
- **MicroChip:** SAMD21, SAMD51 (device only)
|
- **MicroChip:** SAMD21, SAMD51 (device only)
|
||||||
- **Nordic:** nRF52840, nRF52833
|
- **Nordic:** nRF52840, nRF52833
|
||||||
@ -38,12 +38,13 @@ The stack supports the following MCUs
|
|||||||
- **Sony:** CXD56
|
- **Sony:** CXD56
|
||||||
- **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only)
|
- **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only)
|
||||||
- **[ValentyUSB](https://github.com/im-tomu/valentyusb)** eptri
|
- **[ValentyUSB](https://github.com/im-tomu/valentyusb)** eptri
|
||||||
|
- **Nuvoton:** NUC121/NUC125, NUC126
|
||||||
|
|
||||||
[Here is the list of supported Boards](docs/boards.md) that can be used with provided examples.
|
[Here is the list of supported Boards](docs/boards.md) that can be used with provided examples.
|
||||||
|
|
||||||
## Device Stack
|
## Device Stack
|
||||||
|
|
||||||
Support multiple device configurations by dynamically changing usb descriptors. Low power functions such as 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. Following device classes are supported:
|
||||||
|
|
||||||
- Communication Class (CDC)
|
- Communication Class (CDC)
|
||||||
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
|
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
|
||||||
@ -58,11 +59,11 @@ Support multiple device configurations by dynamically changing usb descriptors.
|
|||||||
|
|
||||||
- Human Interface Device (HID): Keyboard, Mouse, Generic
|
- Human Interface Device (HID): Keyboard, Mouse, Generic
|
||||||
- Mass Storage Class (MSC)
|
- Mass Storage Class (MSC)
|
||||||
- Hub currently only support 1 level of hub (due to my laziness)
|
- Hub currently only supports 1 level of hub (due to my laziness)
|
||||||
|
|
||||||
## OS Abtraction layer
|
## 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 semphore/mutex to access shared resource 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 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.
|
||||||
|
|
||||||
- **No OS** : Disabling USB IRQ is used as way to provide mutex
|
- **No OS** : Disabling USB IRQ is used as way to provide mutex
|
||||||
- **FreeRTOS**
|
- **FreeRTOS**
|
||||||
@ -70,11 +71,11 @@ TinyUSB is completely thread-safe by pushing all ISR events into a central queue
|
|||||||
|
|
||||||
## Compiler & IDE
|
## Compiler & IDE
|
||||||
|
|
||||||
The stack is developed with GCC compiler, and should be compilable with others. Folder `examples` provide Makefile and Segger Embedded Studio build support. [Here is instruction to build example](examples/readme.md).
|
The stack is developed with GCC compiler and should be compilable with others. The `examples` folder provides Makefile and Segger Embedded Studio build support. [Here are example build instructions](examples/readme.md).
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
[Here is the details for getting started](docs/getting_started.md) with the stack.
|
[Here are the details for getting started](docs/getting_started.md) with the stack.
|
||||||
|
|
||||||
## Porting
|
## Porting
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ Want to help add TinyUSB support for a new MCU? Read [here](docs/porting.md) for
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT license for all TinyUSB sources `src` folder, [Full license is here](LICENSE). However each file 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.
|
MIT license for all TinyUSB sources `src` folder, [Full license is here](LICENSE). However, each file 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.
|
||||||
|
|
||||||
## Uses
|
## Uses
|
||||||
|
|
||||||
@ -95,4 +96,4 @@ TinyUSB is currently used by these other projects:
|
|||||||
* [MicroPython](https://github.com/micropython/micropython)
|
* [MicroPython](https://github.com/micropython/micropython)
|
||||||
* [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
|
* [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
|
||||||
|
|
||||||
Let's me know if your project also uses TinyUSB and want to share.
|
Let me know if your project also uses TinyUSB and want to share.
|
||||||
|
@ -7,7 +7,7 @@ The board support code is only used for self-contained examples and testing. It
|
|||||||
|
|
||||||
## Supported Boards
|
## Supported Boards
|
||||||
|
|
||||||
This code base already had supported for a handful of following boards
|
This code base already had supported for a handful of following boards (sorted alphabetically)
|
||||||
|
|
||||||
### MicroChip SAMD
|
### MicroChip SAMD
|
||||||
|
|
||||||
@ -25,6 +25,13 @@ This code base already had supported for a handful of following boards
|
|||||||
- [Nordic nRF52840 Development Kit (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
|
- [Nordic nRF52840 Development Kit (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
|
||||||
- [Nordic nRF52840 Dongle (aka pca10059)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle)
|
- [Nordic nRF52840 Dongle (aka pca10059)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle)
|
||||||
- [Nordic nRF52833 Development Kit (aka pca10100)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK)
|
- [Nordic nRF52833 Development Kit (aka pca10100)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK)
|
||||||
|
- [Raytac MDBT50Q-RX Dongle](https://www.raytac.com/product/ins.php?index_id=89)
|
||||||
|
|
||||||
|
### Nuvoton
|
||||||
|
|
||||||
|
- [NuTiny NUC121S](https://direct.nuvoton.com/en/nutiny-nuc121s)
|
||||||
|
- [NuTiny NUC125S](https://direct.nuvoton.com/en/nutiny-nuc125s)
|
||||||
|
- [NuTiny NUC126V](https://direct.nuvoton.com/en/nutiny-nuc126v)
|
||||||
|
|
||||||
### NXP iMX RT
|
### NXP iMX RT
|
||||||
|
|
||||||
@ -34,6 +41,7 @@ This code base already had supported for a handful of following boards
|
|||||||
- [MIMX RT1050 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1050-evaluation-kit:MIMXRT1050-EVK)
|
- [MIMX RT1050 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1050-evaluation-kit:MIMXRT1050-EVK)
|
||||||
- [MIMX RT1060 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1060-evk-i.mx-rt1060-evaluation-kit:MIMXRT1060-EVK)
|
- [MIMX RT1060 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1060-evk-i.mx-rt1060-evaluation-kit:MIMXRT1060-EVK)
|
||||||
- [MIMX RT1064 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1064-evk-i.mx-rt1064-evaluation-kit:MIMXRT1064-EVK)
|
- [MIMX RT1064 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1064-evk-i.mx-rt1064-evaluation-kit:MIMXRT1064-EVK)
|
||||||
|
- [Teensy 4.0 Development Board](https://www.pjrc.com/store/teensy40.html)
|
||||||
|
|
||||||
### NXP LPC
|
### NXP LPC
|
||||||
|
|
||||||
@ -64,7 +72,9 @@ This code base already had supported for a handful of following boards
|
|||||||
- STM32 F103c Blue Pill
|
- STM32 F103c Blue Pill
|
||||||
- [STM32 F207zg Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f207zg.html)
|
- [STM32 F207zg Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f207zg.html)
|
||||||
- [STM32 F303vc Discovery](https://www.st.com/en/evaluation-tools/stm32f3discovery.html)
|
- [STM32 F303vc Discovery](https://www.st.com/en/evaluation-tools/stm32f3discovery.html)
|
||||||
|
- STM32 F401cc Black Pill
|
||||||
- [STM32 F407vg Discovery](https://www.st.com/en/evaluation-tools/stm32f4discovery.html)
|
- [STM32 F407vg Discovery](https://www.st.com/en/evaluation-tools/stm32f4discovery.html)
|
||||||
|
- STM32 F411ce Black Pill
|
||||||
- [STM32 F411ve Discovery](https://www.st.com/en/evaluation-tools/32f411ediscovery.html)
|
- [STM32 F411ve Discovery](https://www.st.com/en/evaluation-tools/32f411ediscovery.html)
|
||||||
- [STM32 F412zg Discovery](https://www.st.com/en/evaluation-tools/32f412gdiscovery.html)
|
- [STM32 F412zg Discovery](https://www.st.com/en/evaluation-tools/32f412gdiscovery.html)
|
||||||
- [STM32 F767zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f767zi.html)
|
- [STM32 F767zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f767zi.html)
|
||||||
|
12
examples/device/cdc_dual_ports/Makefile
Normal file
12
examples/device/cdc_dual_ports/Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
include ../../../tools/top.mk
|
||||||
|
include ../../make.mk
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
src \
|
||||||
|
$(TOP)/hw \
|
||||||
|
|
||||||
|
# Example source
|
||||||
|
EXAMPLE_SOURCE += $(wildcard src/*.c)
|
||||||
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||||
|
|
||||||
|
include ../../rules.mk
|
100
examples/device/cdc_dual_ports/src/main.c
Normal file
100
examples/device/cdc_dual_ports/src/main.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "bsp/board.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
//------------- prototypes -------------//
|
||||||
|
static void cdc_task(void);
|
||||||
|
|
||||||
|
/*------------- MAIN -------------*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
board_init();
|
||||||
|
|
||||||
|
tusb_init();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
tud_task(); // tinyusb device task
|
||||||
|
cdc_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo to either Serial0 or Serial1
|
||||||
|
// with Serial0 as all lower case, Serial1 as all upper case
|
||||||
|
static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count)
|
||||||
|
{
|
||||||
|
for(uint32_t i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
if (itf == 0)
|
||||||
|
{
|
||||||
|
// echo back 1st port as lower case
|
||||||
|
if (isupper(buf[i])) buf[i] += 'a' - 'A';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// echo back additional ports as upper case
|
||||||
|
if (islower(buf[i])) buf[i] -= 'a' - 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
tud_cdc_n_write_char(itf, buf[i]);
|
||||||
|
|
||||||
|
if ( buf[i] == '\r' ) tud_cdc_n_write_char(itf, '\n');
|
||||||
|
}
|
||||||
|
tud_cdc_n_write_flush(itf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// USB CDC
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
static void cdc_task(void)
|
||||||
|
{
|
||||||
|
uint8_t itf;
|
||||||
|
|
||||||
|
for (itf = 0; itf < CFG_TUD_CDC; itf++)
|
||||||
|
{
|
||||||
|
if ( tud_cdc_n_connected(itf) )
|
||||||
|
{
|
||||||
|
if ( tud_cdc_n_available(itf) )
|
||||||
|
{
|
||||||
|
uint8_t buf[64];
|
||||||
|
|
||||||
|
uint32_t count = tud_cdc_n_read(itf, buf, sizeof(buf));
|
||||||
|
|
||||||
|
// echo back to both serial ports
|
||||||
|
echo_serial_port(0, buf, count);
|
||||||
|
echo_serial_port(1, buf, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
examples/device/cdc_dual_ports/src/tusb_config.h
Normal file
92
examples/device/cdc_dual_ports/src/tusb_config.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TUSB_CONFIG_H_
|
||||||
|
#define _TUSB_CONFIG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// COMMON CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// defined by compiler flags for flexibility
|
||||||
|
#ifndef CFG_TUSB_MCU
|
||||||
|
#error CFG_TUSB_MCU must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
|
||||||
|
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||||
|
#else
|
||||||
|
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CFG_TUSB_OS OPT_OS_NONE
|
||||||
|
|
||||||
|
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||||
|
// #define CFG_TUSB_DEBUG 0
|
||||||
|
|
||||||
|
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||||
|
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||||
|
* into those specific section.
|
||||||
|
* e.g
|
||||||
|
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||||
|
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||||
|
*/
|
||||||
|
#ifndef CFG_TUSB_MEM_SECTION
|
||||||
|
#define CFG_TUSB_MEM_SECTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_MEM_ALIGN
|
||||||
|
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------- CLASS -------------//
|
||||||
|
#define CFG_TUD_CDC 2
|
||||||
|
#define CFG_TUD_MSC 0
|
||||||
|
#define CFG_TUD_HID 0
|
||||||
|
#define CFG_TUD_MIDI 0
|
||||||
|
#define CFG_TUD_VENDOR 0
|
||||||
|
|
||||||
|
// CDC FIFO size of TX and RX
|
||||||
|
#define CFG_TUD_CDC_RX_BUFSIZE 64
|
||||||
|
#define CFG_TUD_CDC_TX_BUFSIZE 64
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TUSB_CONFIG_H_ */
|
163
examples/device/cdc_dual_ports/src/usb_descriptors.c
Normal file
163
examples/device/cdc_dual_ports/src/usb_descriptors.c
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||||
|
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||||
|
*
|
||||||
|
* Auto ProductID layout's Bitmap:
|
||||||
|
* [MSB] MIDI | HID | MSC | CDC [LSB]
|
||||||
|
*/
|
||||||
|
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||||
|
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||||
|
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
tusb_desc_device_t const desc_device =
|
||||||
|
{
|
||||||
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
|
||||||
|
// Use Interface Association Descriptor (IAD) for CDC
|
||||||
|
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
||||||
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
|
.idVendor = 0xCafe,
|
||||||
|
.idProduct = USB_PID,
|
||||||
|
.bcdDevice = 0x0100,
|
||||||
|
|
||||||
|
.iManufacturer = 0x01,
|
||||||
|
.iProduct = 0x02,
|
||||||
|
.iSerialNumber = 0x03,
|
||||||
|
|
||||||
|
.bNumConfigurations = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
uint8_t const * tud_descriptor_device_cb(void)
|
||||||
|
{
|
||||||
|
return (uint8_t const *) &desc_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Configuration Descriptor
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ITF_NUM_CDC1 = 0,
|
||||||
|
ITF_NUM_CDC_DATA1,
|
||||||
|
ITF_NUM_CDC2,
|
||||||
|
ITF_NUM_CDC_DATA2,
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN)
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
|
||||||
|
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||||
|
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
|
||||||
|
#define EPNUM_CDC 2
|
||||||
|
#else
|
||||||
|
#define EPNUM_CDC 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t const desc_configuration[] =
|
||||||
|
{
|
||||||
|
// Interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||||
|
|
||||||
|
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, 4, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, 64),
|
||||||
|
|
||||||
|
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC2, 4, 0x83, 8, EPNUM_CDC + 2, 0x80 | (EPNUM_CDC + 2), 64),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
// Descriptor contents must exist long enough for transfer to complete
|
||||||
|
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||||
|
{
|
||||||
|
(void) index; // for multiple configurations
|
||||||
|
return desc_configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// array of pointer to string descriptors
|
||||||
|
char const* string_desc_arr [] =
|
||||||
|
{
|
||||||
|
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||||
|
"TinyUSB", // 1: Manufacturer
|
||||||
|
"TinyUSB Device", // 2: Product
|
||||||
|
"123456", // 3: Serials, should use chip ID
|
||||||
|
"TinyUSB CDC", // 4: CDC Interface
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t _desc_str[32];
|
||||||
|
|
||||||
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
|
uint16_t const* tud_descriptor_string_cb(uint8_t index)
|
||||||
|
{
|
||||||
|
uint8_t chr_count;
|
||||||
|
|
||||||
|
if ( index == 0)
|
||||||
|
{
|
||||||
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
|
chr_count = 1;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// Convert ASCII string into UTF-16
|
||||||
|
|
||||||
|
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
|
||||||
|
|
||||||
|
const char* str = string_desc_arr[index];
|
||||||
|
|
||||||
|
// Cap at max char
|
||||||
|
chr_count = strlen(str);
|
||||||
|
if ( chr_count > 31 ) chr_count = 31;
|
||||||
|
|
||||||
|
for(uint8_t i=0; i<chr_count; i++)
|
||||||
|
{
|
||||||
|
_desc_str[1+i] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// first byte is length (including header), second byte is string type
|
||||||
|
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
|
||||||
|
|
||||||
|
return _desc_str;
|
||||||
|
}
|
@ -12,7 +12,7 @@ $ cd tinyusb
|
|||||||
TinyUSB examples includes external repos aka submodules to provide low-level MCU peripheral's driver to compile with. Therefore we will firstly fetch those mcu driver repo by running this command in the top folder repo
|
TinyUSB examples includes external repos aka submodules to provide low-level MCU peripheral's driver to compile with. Therefore we will firstly fetch those mcu driver repo by running this command in the top folder repo
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git submodule update --init --rescursive
|
$ git submodule update --init --recursive
|
||||||
```
|
```
|
||||||
|
|
||||||
It will takes a bit of time due to the number of supported MCUs, luckily we only need to do this once.
|
It will takes a bit of time due to the number of supported MCUs, luckily we only need to do this once.
|
||||||
|
@ -109,7 +109,7 @@ size: $(BUILD)/$(BOARD)-firmware.elf
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD)
|
rm -rf $(BUILD)
|
||||||
|
|
||||||
# Flash binary using Jlink
|
# Flash binary using Jlink
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
JLINKEXE = JLink.exe
|
JLINKEXE = JLink.exe
|
||||||
@ -120,8 +120,13 @@ endif
|
|||||||
# Flash using jlink
|
# Flash using jlink
|
||||||
flash-jlink: $(BUILD)/$(BOARD)-firmware.hex
|
flash-jlink: $(BUILD)/$(BOARD)-firmware.hex
|
||||||
@echo halt > $(BUILD)/$(BOARD).jlink
|
@echo halt > $(BUILD)/$(BOARD).jlink
|
||||||
|
@echo r > $(BUILD)/$(BOARD).jlink
|
||||||
@echo loadfile $^ >> $(BUILD)/$(BOARD).jlink
|
@echo loadfile $^ >> $(BUILD)/$(BOARD).jlink
|
||||||
@echo r >> $(BUILD)/$(BOARD).jlink
|
@echo r >> $(BUILD)/$(BOARD).jlink
|
||||||
@echo go >> $(BUILD)/$(BOARD).jlink
|
@echo go >> $(BUILD)/$(BOARD).jlink
|
||||||
@echo exit >> $(BUILD)/$(BOARD).jlink
|
@echo exit >> $(BUILD)/$(BOARD).jlink
|
||||||
$(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink
|
$(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink
|
||||||
|
|
||||||
|
# flash STM32 MCU using stlink with STM32 Cube Programmer CLI
|
||||||
|
flash-stlink: $(BUILD)/$(BOARD)-firmware.elf
|
||||||
|
STM32_Programmer_CLI --connect port=swd --write $< --go
|
||||||
|
@ -25,7 +25,7 @@ INC += \
|
|||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/pm/ \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
|
||||||
|
@ -46,6 +46,6 @@ JLINK_IF = swd
|
|||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
# Path to STM32 Cube Programmer CLI, should be added into system path
|
||||||
STM32Prog = STM32_Programmer_CLI
|
STM32Prog = STM32_Programmer_CLI
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target ROM bootloader
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.bin
|
flash: $(BUILD)/$(BOARD)-firmware.bin
|
||||||
dfu-util -R -a 0 --dfuse-address 0x08000000 -D $<
|
dfu-util -R -a 0 --dfuse-address 0x08000000 -D $<
|
||||||
|
@ -67,7 +67,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 4
|
* APB1 Prescaler = 4
|
||||||
* APB2 Prescaler = 2
|
* APB2 Prescaler = 2
|
||||||
* HSE Frequency(Hz) = 12000000
|
* HSE Frequency(Hz) = 12000000
|
||||||
* PLL_M = 12
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 336
|
* PLL_N = 336
|
||||||
* PLL_P = 2
|
* PLL_P = 2
|
||||||
* PLL_Q = 7
|
* PLL_Q = 7
|
||||||
@ -95,7 +95,7 @@ static void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 12;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 336;
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
@ -25,7 +25,7 @@ INC += \
|
|||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/pm/ \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
|
||||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
|
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
|
||||||
|
@ -11,7 +11,8 @@ CFLAGS += \
|
|||||||
-DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX
|
-DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX
|
||||||
|
|
||||||
# mcu driver cause following warnings
|
# mcu driver cause following warnings
|
||||||
CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough=
|
# CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough=
|
||||||
|
CFLAGS += -Wno-error=unused-parameter
|
||||||
|
|
||||||
MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1011
|
MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1011
|
||||||
|
|
||||||
|
57
hw/bsp/nutiny_nuc121s/board.mk
Normal file
57
hw/bsp/nutiny_nuc121s/board.mk
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-flto \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs-linux \
|
||||||
|
-mcpu=cortex-m0 \
|
||||||
|
-D__ARM_FEATURE_DSP=0 \
|
||||||
|
-DUSE_ASSERT=0 \
|
||||||
|
-DCFG_EXAMPLE_MSC_READONLY \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_NUC121
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = hw/bsp/nutiny_nuc121s/nuc121_flash.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Source/system_NUC121.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/adc.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/bpwm.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/clk.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/fmc.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/gpio.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/i2c.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/pdma.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/pwm.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/spi_i2s.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/sys.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/timer.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/uart.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/usbd.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/usci_i2c.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/usci_spi.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/usci_uart.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/wdt.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/wwdt.c
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Source/GCC/startup_NUC121.S
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Include \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc121_125/StdDriver/inc \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc121_125/CMSIS/Include
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = nuvoton
|
||||||
|
CHIP_FAMILY = nuc121
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM0
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = NUC121SC2AE
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton
|
||||||
|
# Please compile and install it from github source
|
||||||
|
flash: $(BUILD)/$(BOARD)-firmware.elf
|
||||||
|
openocd -f interface/nulink.cfg -f target/numicroM0.cfg -c "program $< reset exit"
|
195
hw/bsp/nutiny_nuc121s/nuc121_flash.ld
Normal file
195
hw/bsp/nutiny_nuc121s/nuc121_flash.ld
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* Linker script to configure memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000 /* 32k */
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x2000 /* 8k */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Library configurations */
|
||||||
|
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||||
|
|
||||||
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
* with other linker script that defines memory regions FLASH and RAM.
|
||||||
|
* It references following symbols, which must be defined in code:
|
||||||
|
* Reset_Handler : Entry of reset handler
|
||||||
|
*
|
||||||
|
* It defines following symbols, which code can use without definition:
|
||||||
|
* __exidx_start
|
||||||
|
* __exidx_end
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_end__
|
||||||
|
* __etext
|
||||||
|
* __data_start__
|
||||||
|
* __preinit_array_start
|
||||||
|
* __preinit_array_end
|
||||||
|
* __init_array_start
|
||||||
|
* __init_array_end
|
||||||
|
* __fini_array_start
|
||||||
|
* __fini_array_end
|
||||||
|
* __data_end__
|
||||||
|
* __bss_start__
|
||||||
|
* __bss_end__
|
||||||
|
* __end__
|
||||||
|
* end
|
||||||
|
* __HeapLimit
|
||||||
|
* __StackLimit
|
||||||
|
* __StackTop
|
||||||
|
* __stack
|
||||||
|
* __Vectors_End
|
||||||
|
* __Vectors_Size
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
__Vectors_End = .;
|
||||||
|
__Vectors_Size = __Vectors_End - __Vectors;
|
||||||
|
__end__ = .;
|
||||||
|
|
||||||
|
*(.text*)
|
||||||
|
|
||||||
|
KEEP(*(.init))
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
/* .ctors */
|
||||||
|
*crtbegin.o(.ctors)
|
||||||
|
*crtbegin?.o(.ctors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||||
|
*(SORT(.ctors.*))
|
||||||
|
*(.ctors)
|
||||||
|
|
||||||
|
/* .dtors */
|
||||||
|
*crtbegin.o(.dtors)
|
||||||
|
*crtbegin?.o(.dtors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||||
|
*(SORT(.dtors.*))
|
||||||
|
*(.dtors)
|
||||||
|
|
||||||
|
*(.rodata*)
|
||||||
|
|
||||||
|
KEEP(*(.eh_frame*))
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__HeapBase = .;
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
KEEP(*(.heap*))
|
||||||
|
__HeapLimit = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
* used for linker to calculate size of stack sections, and assign
|
||||||
|
* values to stack symbols later */
|
||||||
|
.stack_dummy (COPY):
|
||||||
|
{
|
||||||
|
KEEP(*(.stack*))
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* Set stack top to end of RAM, and stack limit move down by
|
||||||
|
* size of stack_dummy section */
|
||||||
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||||
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||||
|
}
|
110
hw/bsp/nutiny_nuc121s/nutiny_nuc121.c
Normal file
110
hw/bsp/nutiny_nuc121s/nutiny_nuc121.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board.h"
|
||||||
|
#include "NuMicro.h"
|
||||||
|
#include "clk.h"
|
||||||
|
#include "sys.h"
|
||||||
|
|
||||||
|
#define LED_PORT PB
|
||||||
|
#define LED_PIN 4
|
||||||
|
#define LED_PIN_IO PB4
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
/* Unlock protected registers */
|
||||||
|
SYS_UnlockReg();
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* Init System Clock */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Enable Internal HIRC 48 MHz clock */
|
||||||
|
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN);
|
||||||
|
|
||||||
|
/* Waiting for Internal RC clock ready */
|
||||||
|
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
|
||||||
|
|
||||||
|
/* Switch HCLK clock source to Internal HIRC and HCLK source divide 1 */
|
||||||
|
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
|
||||||
|
|
||||||
|
/* Enable module clock */
|
||||||
|
CLK_EnableModuleClock(USBD_MODULE);
|
||||||
|
|
||||||
|
/* Select module clock source */
|
||||||
|
CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_HIRC, CLK_CLKDIV0_USB(1));
|
||||||
|
|
||||||
|
/* Enable module clock */
|
||||||
|
CLK_EnableModuleClock(USBD_MODULE);
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(48000000 / 1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// LED
|
||||||
|
GPIO_SetMode(LED_PORT, 1 << LED_PIN, GPIO_MODE_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler (void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
LED_PIN_IO = (state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
41
hw/bsp/nutiny_nuc125s/board.mk
Normal file
41
hw/bsp/nutiny_nuc125s/board.mk
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-flto \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs-linux \
|
||||||
|
-mcpu=cortex-m0 \
|
||||||
|
-D__ARM_FEATURE_DSP=0 \
|
||||||
|
-DUSE_ASSERT=0 \
|
||||||
|
-DCFG_EXAMPLE_MSC_READONLY \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_NUC121
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = hw/bsp/nutiny_nuc125s/nuc125_flash.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Source/system_NUC121.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/clk.c \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/StdDriver/src/gpio.c
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Source/GCC/startup_NUC121.S
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Include \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc121_125/StdDriver/inc \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc121_125/CMSIS/Include
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = nuvoton
|
||||||
|
CHIP_FAMILY = nuc121
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM0
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = NUC125SC2AE
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton
|
||||||
|
# Please compile and install it from github source
|
||||||
|
flash: $(BUILD)/$(BOARD)-firmware.elf
|
||||||
|
openocd -f interface/nulink.cfg -f target/numicroM0.cfg -c "program $< reset exit"
|
195
hw/bsp/nutiny_nuc125s/nuc125_flash.ld
Normal file
195
hw/bsp/nutiny_nuc125s/nuc125_flash.ld
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* Linker script to configure memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000 /* 32k */
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x2000 /* 8k */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Library configurations */
|
||||||
|
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||||
|
|
||||||
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
* with other linker script that defines memory regions FLASH and RAM.
|
||||||
|
* It references following symbols, which must be defined in code:
|
||||||
|
* Reset_Handler : Entry of reset handler
|
||||||
|
*
|
||||||
|
* It defines following symbols, which code can use without definition:
|
||||||
|
* __exidx_start
|
||||||
|
* __exidx_end
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_end__
|
||||||
|
* __etext
|
||||||
|
* __data_start__
|
||||||
|
* __preinit_array_start
|
||||||
|
* __preinit_array_end
|
||||||
|
* __init_array_start
|
||||||
|
* __init_array_end
|
||||||
|
* __fini_array_start
|
||||||
|
* __fini_array_end
|
||||||
|
* __data_end__
|
||||||
|
* __bss_start__
|
||||||
|
* __bss_end__
|
||||||
|
* __end__
|
||||||
|
* end
|
||||||
|
* __HeapLimit
|
||||||
|
* __StackLimit
|
||||||
|
* __StackTop
|
||||||
|
* __stack
|
||||||
|
* __Vectors_End
|
||||||
|
* __Vectors_Size
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
__Vectors_End = .;
|
||||||
|
__Vectors_Size = __Vectors_End - __Vectors;
|
||||||
|
__end__ = .;
|
||||||
|
|
||||||
|
*(.text*)
|
||||||
|
|
||||||
|
KEEP(*(.init))
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
/* .ctors */
|
||||||
|
*crtbegin.o(.ctors)
|
||||||
|
*crtbegin?.o(.ctors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||||
|
*(SORT(.ctors.*))
|
||||||
|
*(.ctors)
|
||||||
|
|
||||||
|
/* .dtors */
|
||||||
|
*crtbegin.o(.dtors)
|
||||||
|
*crtbegin?.o(.dtors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||||
|
*(SORT(.dtors.*))
|
||||||
|
*(.dtors)
|
||||||
|
|
||||||
|
*(.rodata*)
|
||||||
|
|
||||||
|
KEEP(*(.eh_frame*))
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__HeapBase = .;
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
KEEP(*(.heap*))
|
||||||
|
__HeapLimit = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
* used for linker to calculate size of stack sections, and assign
|
||||||
|
* values to stack symbols later */
|
||||||
|
.stack_dummy (COPY):
|
||||||
|
{
|
||||||
|
KEEP(*(.stack*))
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* Set stack top to end of RAM, and stack limit move down by
|
||||||
|
* size of stack_dummy section */
|
||||||
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||||
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||||
|
}
|
110
hw/bsp/nutiny_nuc125s/nutiny_nuc125.c
Normal file
110
hw/bsp/nutiny_nuc125s/nutiny_nuc125.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board.h"
|
||||||
|
#include "NuMicro.h"
|
||||||
|
#include "clk.h"
|
||||||
|
#include "sys.h"
|
||||||
|
|
||||||
|
#define LED_PORT PB
|
||||||
|
#define LED_PIN 4
|
||||||
|
#define LED_PIN_IO PB4
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
/* Unlock protected registers */
|
||||||
|
SYS_UnlockReg();
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* Init System Clock */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Enable Internal HIRC 48 MHz clock */
|
||||||
|
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN);
|
||||||
|
|
||||||
|
/* Waiting for Internal RC clock ready */
|
||||||
|
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
|
||||||
|
|
||||||
|
/* Switch HCLK clock source to Internal HIRC and HCLK source divide 1 */
|
||||||
|
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
|
||||||
|
|
||||||
|
/* Enable module clock */
|
||||||
|
CLK_EnableModuleClock(USBD_MODULE);
|
||||||
|
|
||||||
|
/* Select module clock source */
|
||||||
|
CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_HIRC, CLK_CLKDIV0_USB(1));
|
||||||
|
|
||||||
|
/* Enable module clock */
|
||||||
|
CLK_EnableModuleClock(USBD_MODULE);
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(48000000 / 1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// LED
|
||||||
|
GPIO_SetMode(LED_PORT, 1 << LED_PIN, GPIO_MODE_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler (void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
LED_PIN_IO = (state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
61
hw/bsp/nutiny_nuc126v/board.mk
Normal file
61
hw/bsp/nutiny_nuc126v/board.mk
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-flto \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs-linux \
|
||||||
|
-mcpu=cortex-m0 \
|
||||||
|
-D__ARM_FEATURE_DSP=0 \
|
||||||
|
-DUSE_ASSERT=0 \
|
||||||
|
-D__CORTEX_SC=0 \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_NUC126
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = hw/bsp/nutiny_nuc126v/nuc126_flash.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
hw/mcu/nuvoton/nuc126/Device/Nuvoton/NUC126/Source/system_NUC126.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/acmp.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/adc.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/clk.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/crc.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/ebi.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/fmc.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/gpio.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/pdma.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/pwm.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/rtc.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/sc.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/scuart.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/spi.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/sys.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/timer.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/timer_pwm.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/uart.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/usbd.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/usci_spi.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/usci_uart.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/wdt.c \
|
||||||
|
hw/mcu/nuvoton/nuc126/StdDriver/src/wwdt.c
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
hw/mcu/nuvoton/nuc126/Device/Nuvoton/NUC126/Source/GCC/startup_NUC126.S
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc126/Device/Nuvoton/NUC126/Include \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc126/StdDriver/inc \
|
||||||
|
$(TOP)/hw/mcu/nuvoton/nuc126/CMSIS/Include
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = nuvoton
|
||||||
|
CHIP_FAMILY = nuc121
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM0
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = NUC126VG4AE
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton
|
||||||
|
# Please compile and install it from github source
|
||||||
|
flash: $(BUILD)/$(BOARD)-firmware.elf
|
||||||
|
openocd -f interface/nulink.cfg -f target/numicroM0.cfg -c "program $< reset exit"
|
195
hw/bsp/nutiny_nuc126v/nuc126_flash.ld
Normal file
195
hw/bsp/nutiny_nuc126v/nuc126_flash.ld
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* Linker script to configure memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000 /* 256k */
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x5000 /* 20k */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Library configurations */
|
||||||
|
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||||
|
|
||||||
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
* with other linker script that defines memory regions FLASH and RAM.
|
||||||
|
* It references following symbols, which must be defined in code:
|
||||||
|
* Reset_Handler : Entry of reset handler
|
||||||
|
*
|
||||||
|
* It defines following symbols, which code can use without definition:
|
||||||
|
* __exidx_start
|
||||||
|
* __exidx_end
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_end__
|
||||||
|
* __etext
|
||||||
|
* __data_start__
|
||||||
|
* __preinit_array_start
|
||||||
|
* __preinit_array_end
|
||||||
|
* __init_array_start
|
||||||
|
* __init_array_end
|
||||||
|
* __fini_array_start
|
||||||
|
* __fini_array_end
|
||||||
|
* __data_end__
|
||||||
|
* __bss_start__
|
||||||
|
* __bss_end__
|
||||||
|
* __end__
|
||||||
|
* end
|
||||||
|
* __HeapLimit
|
||||||
|
* __StackLimit
|
||||||
|
* __StackTop
|
||||||
|
* __stack
|
||||||
|
* __Vectors_End
|
||||||
|
* __Vectors_Size
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
__Vectors_End = .;
|
||||||
|
__Vectors_Size = __Vectors_End - __Vectors;
|
||||||
|
__end__ = .;
|
||||||
|
|
||||||
|
*(.text*)
|
||||||
|
|
||||||
|
KEEP(*(.init))
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
/* .ctors */
|
||||||
|
*crtbegin.o(.ctors)
|
||||||
|
*crtbegin?.o(.ctors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||||
|
*(SORT(.ctors.*))
|
||||||
|
*(.ctors)
|
||||||
|
|
||||||
|
/* .dtors */
|
||||||
|
*crtbegin.o(.dtors)
|
||||||
|
*crtbegin?.o(.dtors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||||
|
*(SORT(.dtors.*))
|
||||||
|
*(.dtors)
|
||||||
|
|
||||||
|
*(.rodata*)
|
||||||
|
|
||||||
|
KEEP(*(.eh_frame*))
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__HeapBase = .;
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
KEEP(*(.heap*))
|
||||||
|
__HeapLimit = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
* used for linker to calculate size of stack sections, and assign
|
||||||
|
* values to stack symbols later */
|
||||||
|
.stack_dummy (COPY):
|
||||||
|
{
|
||||||
|
KEEP(*(.stack*))
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* Set stack top to end of RAM, and stack limit move down by
|
||||||
|
* size of stack_dummy section */
|
||||||
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||||
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||||
|
}
|
141
hw/bsp/nutiny_nuc126v/nutiny_nuc126.c
Normal file
141
hw/bsp/nutiny_nuc126v/nutiny_nuc126.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board.h"
|
||||||
|
#include "NuMicro.h"
|
||||||
|
#include "clk.h"
|
||||||
|
#include "sys.h"
|
||||||
|
|
||||||
|
#define LED_PORT PC
|
||||||
|
#define LED_PIN 9
|
||||||
|
#define LED_PIN_IO PC9
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
#define CRYSTAL_LESS /* system will be 48MHz when defined, otherwise, system is 72MHz */
|
||||||
|
#define HIRC48_AUTO_TRIM SYS_IRCTCTL1_REFCKSEL_Msk | (1UL << SYS_IRCTCTL1_LOOPSEL_Pos) | (2UL << SYS_IRCTCTL1_FREQSEL_Pos)
|
||||||
|
#define TRIM_INIT (SYS_BASE+0x118)
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
/* Unlock protected registers */
|
||||||
|
SYS_UnlockReg();
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
/* Init System Clock */
|
||||||
|
/*---------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Enable Internal RC 22.1184 MHz clock */
|
||||||
|
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
|
||||||
|
|
||||||
|
/* Waiting for Internal RC clock ready */
|
||||||
|
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
|
||||||
|
|
||||||
|
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
|
||||||
|
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
|
||||||
|
|
||||||
|
#ifndef CRYSTAL_LESS
|
||||||
|
/* Enable external XTAL 12 MHz clock */
|
||||||
|
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
|
||||||
|
|
||||||
|
/* Waiting for external XTAL clock ready */
|
||||||
|
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
|
||||||
|
|
||||||
|
/* Set core clock */
|
||||||
|
CLK_SetCoreClock(72000000);
|
||||||
|
|
||||||
|
/* Use HIRC as UART clock source */
|
||||||
|
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HIRC, CLK_CLKDIV0_UART(1));
|
||||||
|
|
||||||
|
/* Use PLL as USB clock source */
|
||||||
|
CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_PLL, CLK_CLKDIV0_USB(3));
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Enable Internal RC 48MHz clock */
|
||||||
|
CLK_EnableXtalRC(CLK_PWRCTL_HIRC48EN_Msk);
|
||||||
|
|
||||||
|
/* Waiting for Internal RC clock ready */
|
||||||
|
CLK_WaitClockReady(CLK_STATUS_HIRC48STB_Msk);
|
||||||
|
|
||||||
|
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
|
||||||
|
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC48, CLK_CLKDIV0_HCLK(1));
|
||||||
|
|
||||||
|
/* Use HIRC as UART clock source */
|
||||||
|
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HIRC, CLK_CLKDIV0_UART(1));
|
||||||
|
|
||||||
|
/* Use HIRC48 as USB clock source */
|
||||||
|
CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_HIRC48, CLK_CLKDIV0_USB(1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable module clock */
|
||||||
|
CLK_EnableModuleClock(USBD_MODULE);
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(48000000 / 1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// LED
|
||||||
|
GPIO_SetMode(LED_PORT, 1 << LED_PIN, GPIO_MODE_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler (void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
LED_PIN_IO = (state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
@ -42,9 +42,5 @@ FREERTOS_PORT = ARM_CM4F
|
|||||||
JLINK_DEVICE = stm32f405rg
|
JLINK_DEVICE = stm32f405rg
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -56,7 +56,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 4
|
* APB1 Prescaler = 4
|
||||||
* APB2 Prescaler = 2
|
* APB2 Prescaler = 2
|
||||||
* HSE Frequency(Hz) = 12000000
|
* HSE Frequency(Hz) = 12000000
|
||||||
* PLL_M = 12
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 336
|
* PLL_N = 336
|
||||||
* PLL_P = 2
|
* PLL_P = 2
|
||||||
* PLL_Q = 7
|
* PLL_Q = 7
|
||||||
@ -84,7 +84,7 @@ static void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 12;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 336;
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
54
hw/bsp/raytac_mdbt50q_rx/board.mk
Normal file
54
hw/bsp/raytac_mdbt50q_rx/board.mk
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-flto \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs \
|
||||||
|
-mcpu=cortex-m4 \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv4-sp-d16 \
|
||||||
|
-DNRF52840_XXAA \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_NRF5X
|
||||||
|
|
||||||
|
# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49
|
||||||
|
CFLAGS += -Wno-error=undef -Wno-error=unused-parameter
|
||||||
|
|
||||||
|
# due to tusb_hal_nrf_power_event
|
||||||
|
GCCVERSION = $(firstword $(subst ., ,$(shell arm-none-eabi-gcc -dumpversion)))
|
||||||
|
ifeq ($(shell expr $(GCCVERSION) \>= 8), 1)
|
||||||
|
CFLAGS += -Wno-error=cast-function-type
|
||||||
|
endif
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf52840_xxaa.ld
|
||||||
|
|
||||||
|
LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \
|
||||||
|
hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/mcu/nordic/cmsis/Include \
|
||||||
|
$(TOP)/hw/mcu/nordic \
|
||||||
|
$(TOP)/hw/mcu/nordic/nrfx \
|
||||||
|
$(TOP)/hw/mcu/nordic/nrfx/mdk \
|
||||||
|
$(TOP)/hw/mcu/nordic/nrfx/hal \
|
||||||
|
$(TOP)/hw/mcu/nordic/nrfx/drivers/include \
|
||||||
|
$(TOP)/hw/mcu/nordic/nrfx/drivers/src \
|
||||||
|
|
||||||
|
SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S
|
||||||
|
|
||||||
|
ASFLAGS += -D__HEAP_SIZE=0
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = nordic
|
||||||
|
CHIP_FAMILY = nrf5x
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM4F
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = nRF52840_xxAA
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# flash using jlink
|
||||||
|
flash: flash-jlink
|
190
hw/bsp/raytac_mdbt50q_rx/raytac_mdbt50q_rx.c
Normal file
190
hw/bsp/raytac_mdbt50q_rx/raytac_mdbt50q_rx.c
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board.h"
|
||||||
|
|
||||||
|
#include "nrfx.h"
|
||||||
|
#include "nrfx/hal/nrf_gpio.h"
|
||||||
|
#include "nrfx/drivers/include/nrfx_power.h"
|
||||||
|
|
||||||
|
#ifdef SOFTDEVICE_PRESENT
|
||||||
|
#include "nrf_sdm.h"
|
||||||
|
#include "nrf_soc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
/* MACRO TYPEDEF CONSTANT ENUM
|
||||||
|
*------------------------------------------------------------------*/
|
||||||
|
#define LED_PIN (32+13) // P1.13
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
// Button 1
|
||||||
|
#define BUTTON_PIN 15 // P0.15
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
// tinyusb function that handles power event (detected, ready, removed)
|
||||||
|
// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
|
||||||
|
extern void tusb_hal_nrf_power_event(uint32_t event);
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
// Config clock source: XTAL or RC in sdk_config.h
|
||||||
|
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
|
||||||
|
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
|
||||||
|
|
||||||
|
// LED
|
||||||
|
nrf_gpio_cfg_output(LED_PIN);
|
||||||
|
board_led_write(false);
|
||||||
|
|
||||||
|
// Button
|
||||||
|
nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(SystemCoreClock/1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TUSB_OPT_DEVICE_ENABLED
|
||||||
|
// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
|
||||||
|
// 2 is highest for application
|
||||||
|
NVIC_SetPriority(USBD_IRQn, 2);
|
||||||
|
|
||||||
|
// USB power may already be ready at this time -> no event generated
|
||||||
|
// We need to invoke the handler based on the status initially
|
||||||
|
uint32_t usb_reg;
|
||||||
|
|
||||||
|
#ifdef SOFTDEVICE_PRESENT
|
||||||
|
uint8_t sd_en = false;
|
||||||
|
sd_softdevice_is_enabled(&sd_en);
|
||||||
|
|
||||||
|
if ( sd_en ) {
|
||||||
|
sd_power_usbdetected_enable(true);
|
||||||
|
sd_power_usbpwrrdy_enable(true);
|
||||||
|
sd_power_usbremoved_enable(true);
|
||||||
|
|
||||||
|
sd_power_usbregstatus_get(&usb_reg);
|
||||||
|
}else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Power module init
|
||||||
|
const nrfx_power_config_t pwr_cfg = { 0 };
|
||||||
|
nrfx_power_init(&pwr_cfg);
|
||||||
|
|
||||||
|
// Register tusb function as USB power handler
|
||||||
|
const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
|
||||||
|
nrfx_power_usbevt_init(&config);
|
||||||
|
|
||||||
|
nrfx_power_usbevt_enable();
|
||||||
|
|
||||||
|
usb_reg = NRF_POWER->USBREGSTATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
|
||||||
|
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler (void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SOFTDEVICE_PRESENT
|
||||||
|
// process SOC event from SD
|
||||||
|
uint32_t proc_soc(void)
|
||||||
|
{
|
||||||
|
uint32_t soc_evt;
|
||||||
|
uint32_t err = sd_evt_get(&soc_evt);
|
||||||
|
|
||||||
|
if (NRF_SUCCESS == err)
|
||||||
|
{
|
||||||
|
/*------------- usb power event handler -------------*/
|
||||||
|
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
|
||||||
|
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
|
||||||
|
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
|
||||||
|
|
||||||
|
if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t proc_ble(void)
|
||||||
|
{
|
||||||
|
// do nothing with ble
|
||||||
|
return NRF_ERROR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SD_EVT_IRQHandler(void)
|
||||||
|
{
|
||||||
|
// process BLE and SOC until there is no more events
|
||||||
|
while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info)
|
||||||
|
{
|
||||||
|
(void) id;
|
||||||
|
(void) pc;
|
||||||
|
(void) info;
|
||||||
|
}
|
||||||
|
#endif
|
@ -46,9 +46,5 @@ FREERTOS_PORT = ARM_CM0
|
|||||||
JLINK_DEVICE = stm32f070rb
|
JLINK_DEVICE = stm32f070rb
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -47,9 +47,5 @@ FREERTOS_PORT = ARM_CM0
|
|||||||
JLINK_DEVICE = stm32f072rb
|
JLINK_DEVICE = stm32f072rb
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -42,12 +42,9 @@ CHIP_FAMILY = stm32_fsdev
|
|||||||
FREERTOS_PORT = ARM_CM3
|
FREERTOS_PORT = ARM_CM3
|
||||||
|
|
||||||
# For flash-jlink target
|
# For flash-jlink target
|
||||||
JLINK_DEVICE = stm32f303vc
|
JLINK_DEVICE = stm32f103c8
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
# flash target ROM bootloader
|
||||||
STM32Prog = STM32_Programmer_CLI
|
flash: $(BUILD)/$(BOARD)-firmware.bin
|
||||||
|
dfu-util -R -a 0 --dfuse-address 0x08000000 -D $<
|
||||||
# flash target using on-board stlink
|
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -45,9 +45,5 @@ FREERTOS_PORT = ARM_CM3
|
|||||||
JLINK_DEVICE = stm32f207zg
|
JLINK_DEVICE = stm32f207zg
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -56,7 +56,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 4
|
* APB1 Prescaler = 4
|
||||||
* APB2 Prescaler = 2
|
* APB2 Prescaler = 2
|
||||||
* HSE Frequency(Hz) = 8000000
|
* HSE Frequency(Hz) = 8000000
|
||||||
* PLL_M = 8
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 240
|
* PLL_N = 240
|
||||||
* PLL_P = 2
|
* PLL_P = 2
|
||||||
* PLL_Q = 5
|
* PLL_Q = 5
|
||||||
@ -75,7 +75,7 @@ void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
|
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 8;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 240;
|
RCC_OscInitStruct.PLL.PLLN = 240;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 5;
|
RCC_OscInitStruct.PLL.PLLQ = 5;
|
||||||
|
@ -46,9 +46,5 @@ FREERTOS_PORT = ARM_CM4F
|
|||||||
JLINK_DEVICE = stm32f303vc
|
JLINK_DEVICE = stm32f303vc
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
169
hw/bsp/stm32f401blackpill/STM32F401VCTx_FLASH.ld
Normal file
169
hw/bsp/stm32f401blackpill/STM32F401VCTx_FLASH.ld
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
*****************************************************************************
|
||||||
|
**
|
||||||
|
|
||||||
|
** File : LinkerScript.ld
|
||||||
|
**
|
||||||
|
** Abstract : Linker script for STM32F401VCTx Device with
|
||||||
|
** 256KByte FLASH, 64KByte RAM
|
||||||
|
**
|
||||||
|
** Set heap size, stack size and stack location according
|
||||||
|
** to application requirements.
|
||||||
|
**
|
||||||
|
** Set memory bank area and size if external memory is used.
|
||||||
|
**
|
||||||
|
** Target : STMicroelectronics STM32
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Distribution: The file is distributed as is, without any warranty
|
||||||
|
** of any kind.
|
||||||
|
**
|
||||||
|
** (c)Copyright Ac6.
|
||||||
|
** You may use this file as-is or modify it according to the needs of your
|
||||||
|
** project. Distribution of this file (unmodified or modified) is not
|
||||||
|
** permitted. Ac6 permit registered System Workbench for MCU users the
|
||||||
|
** rights to distribute the assembled, compiled & linked contents of this
|
||||||
|
** file as part of an application binary file, provided that it is built
|
||||||
|
** using the System Workbench for MCU toolchain.
|
||||||
|
**
|
||||||
|
*****************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Entry Point */
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
/* Highest address of the user mode stack */
|
||||||
|
_estack = 0x20010000; /* end of RAM */
|
||||||
|
/* Generate a link error if heap and stack don't fit into RAM */
|
||||||
|
_Min_Heap_Size = 0x200;; /* required amount of heap */
|
||||||
|
_Min_Stack_Size = 0x400;; /* required amount of stack */
|
||||||
|
|
||||||
|
/* Specify the memory areas */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define output sections */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* The startup code goes first into FLASH */
|
||||||
|
.isr_vector :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
/* The program code and other data goes into FLASH */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text) /* .text sections (code) */
|
||||||
|
*(.text*) /* .text* sections (code) */
|
||||||
|
*(.glue_7) /* glue arm to thumb code */
|
||||||
|
*(.glue_7t) /* glue thumb to arm code */
|
||||||
|
*(.eh_frame)
|
||||||
|
|
||||||
|
KEEP (*(.init))
|
||||||
|
KEEP (*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .; /* define a global symbols at end of code */
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
/* Constant data goes into FLASH */
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||||
|
.ARM : {
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array*))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >FLASH
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array*))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >FLASH
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
/* used by the startup to initialize data */
|
||||||
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
|
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sdata = .; /* create a global symbol at data start */
|
||||||
|
*(.data) /* .data sections */
|
||||||
|
*(.data*) /* .data* sections */
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .; /* define a global symbol at data end */
|
||||||
|
} >RAM AT> FLASH
|
||||||
|
|
||||||
|
|
||||||
|
/* Uninitialized data section */
|
||||||
|
. = ALIGN(4);
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
/* This is used by the startup in order to initialize the .bss secion */
|
||||||
|
_sbss = .; /* define a global symbol at bss start */
|
||||||
|
__bss_start__ = _sbss;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = .; /* define a global symbol at bss end */
|
||||||
|
__bss_end__ = _ebss;
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||||
|
._user_heap_stack :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE ( end = . );
|
||||||
|
PROVIDE ( _end = . );
|
||||||
|
. = . + _Min_Heap_Size;
|
||||||
|
. = . + _Min_Stack_Size;
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove information from the standard libraries */
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
libc.a ( * )
|
||||||
|
libm.a ( * )
|
||||||
|
libgcc.a ( * )
|
||||||
|
}
|
||||||
|
|
||||||
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
47
hw/bsp/stm32f401blackpill/board.mk
Normal file
47
hw/bsp/stm32f401blackpill/board.mk
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-flto \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs \
|
||||||
|
-mcpu=cortex-m4 \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv4-sp-d16 \
|
||||||
|
-nostdlib -nostartfiles \
|
||||||
|
-DSTM32F401xC \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_STM32F4
|
||||||
|
|
||||||
|
ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver
|
||||||
|
ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F4xx
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = hw/bsp/$(BOARD)/STM32F401VCTx_FLASH.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
$(ST_CMSIS)/Source/Templates/system_stm32f4xx.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal_cortex.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal_rcc.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal_gpio.c
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
$(ST_CMSIS)/Source/Templates/gcc/startup_stm32f401xc.s
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/mcu/st/st_driver/CMSIS/Include \
|
||||||
|
$(TOP)/$(ST_CMSIS)/Include \
|
||||||
|
$(TOP)/$(ST_HAL_DRIVER)/Inc \
|
||||||
|
$(TOP)/hw/bsp/$(BOARD)
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = st
|
||||||
|
CHIP_FAMILY = synopsys
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM4F
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = stm32f401cc
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# flash target ROM bootloader
|
||||||
|
flash: $(BUILD)/$(BOARD)-firmware.bin
|
||||||
|
dfu-util -R -a 0 --dfuse-address 0x08000000 -D $<
|
215
hw/bsp/stm32f401blackpill/stm32f401blackpill.c
Normal file
215
hw/bsp/stm32f401blackpill/stm32f401blackpill.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../board.h"
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f4xx_hal_conf.h"
|
||||||
|
|
||||||
|
#define LED_PORT GPIOC
|
||||||
|
#define LED_PIN GPIO_PIN_13
|
||||||
|
#define LED_STATE_ON 1
|
||||||
|
|
||||||
|
#define BUTTON_PORT GPIOA
|
||||||
|
#define BUTTON_PIN GPIO_PIN_0
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
// enable all LED, Button, Uart, USB clock
|
||||||
|
static void all_rcc_clk_enable(void)
|
||||||
|
{
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D-, Button
|
||||||
|
__HAL_RCC_GPIOC_CLK_ENABLE(); // LED
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System Clock Configuration
|
||||||
|
* The system Clock is configured as follow :
|
||||||
|
* System Clock source = PLL (HSE)
|
||||||
|
* SYSCLK(Hz) = 84000000
|
||||||
|
* HCLK(Hz) = 84000000
|
||||||
|
* AHB Prescaler = 1
|
||||||
|
* APB1 Prescaler = 2
|
||||||
|
* APB2 Prescaler = 1
|
||||||
|
* HSE Frequency(Hz) = 25000000
|
||||||
|
* PLL_M = HSE_VALUE/1000000
|
||||||
|
* PLL_N = 336
|
||||||
|
* PLL_P = 4
|
||||||
|
* PLL_Q = 7
|
||||||
|
* VDD(V) = 3.3
|
||||||
|
* Main regulator output voltage = Scale2 mode
|
||||||
|
* Flash Latency(WS) = 2
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void SystemClock_Config(void)
|
||||||
|
{
|
||||||
|
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||||
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||||
|
|
||||||
|
/* Enable Power Control clock */
|
||||||
|
__HAL_RCC_PWR_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* The voltage scaling allows optimizing the power consumption when the device is
|
||||||
|
clocked below the maximum system frequency, to update the voltage scaling value
|
||||||
|
regarding system frequency refer to product datasheet. */
|
||||||
|
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||||
|
|
||||||
|
/* Enable HSE Oscillator and activate PLL with HSE as source */
|
||||||
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||||
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
|
||||||
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||||
|
|
||||||
|
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
|
||||||
|
clocks dividers */
|
||||||
|
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
|
||||||
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||||
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||||
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||||
|
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(SystemCoreClock / 1000);
|
||||||
|
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
|
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
||||||
|
//NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SystemClock_Config();
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
all_rcc_clk_enable();
|
||||||
|
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
|
// LED
|
||||||
|
GPIO_InitStruct.Pin = LED_PIN;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
|
||||||
|
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
board_led_write(false);
|
||||||
|
|
||||||
|
// Button
|
||||||
|
GPIO_InitStruct.Pin = BUTTON_PIN;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
|
||||||
|
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* Configure USB FS GPIOs */
|
||||||
|
/* Configure USB D+ D- Pins */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* Configure VBUS Pin */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* This for ID line debug */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
// Enable USB OTG clock
|
||||||
|
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
|
||||||
|
|
||||||
|
// Blackpill doens't use VBUS sense (B device)
|
||||||
|
// explicitly disable it
|
||||||
|
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
|
||||||
|
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
|
||||||
|
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler (void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void HardFault_Handler (void)
|
||||||
|
{
|
||||||
|
asm("bkpt");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required by __libc_init_array in startup code if we are compiling using
|
||||||
|
// -nostdlib/-nostartfiles.
|
||||||
|
void _init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
394
hw/bsp/stm32f401blackpill/stm32f4xx_hal_conf.h
Normal file
394
hw/bsp/stm32f401blackpill/stm32f4xx_hal_conf.h
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file GPIO/GPIO_EXTI/Inc/stm32f4xx_hal_conf.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief HAL configuration file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_HAL_CONF_H
|
||||||
|
#define __STM32F4xx_HAL_CONF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ########################## Module Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief This is the list of modules to be used in the HAL driver
|
||||||
|
*/
|
||||||
|
#define HAL_MODULE_ENABLED
|
||||||
|
/* #define HAL_ADC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CAN_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CRC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CRYP_MODULE_ENABLED */
|
||||||
|
/* #define HAL_DAC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_DCMI_MODULE_ENABLED */
|
||||||
|
#define HAL_DMA_MODULE_ENABLED
|
||||||
|
/* #define HAL_DMA2D_MODULE_ENABLED */
|
||||||
|
/* #define HAL_ETH_MODULE_ENABLED */
|
||||||
|
#define HAL_FLASH_MODULE_ENABLED
|
||||||
|
/* #define HAL_NAND_MODULE_ENABLED */
|
||||||
|
/* #define HAL_NOR_MODULE_ENABLED */
|
||||||
|
/* #define HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SRAM_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SDRAM_MODULE_ENABLED */
|
||||||
|
/* #define HAL_HASH_MODULE_ENABLED */
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
// #define HAL_I2C_MODULE_ENABLED
|
||||||
|
/* #define HAL_I2S_MODULE_ENABLED */
|
||||||
|
/* #define HAL_IWDG_MODULE_ENABLED */
|
||||||
|
/* #define HAL_LTDC_MODULE_ENABLED */
|
||||||
|
#define HAL_PWR_MODULE_ENABLED
|
||||||
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
/* #define HAL_RNG_MODULE_ENABLED */
|
||||||
|
/* #define HAL_RTC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SAI_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SD_MODULE_ENABLED */
|
||||||
|
// #define HAL_SPI_MODULE_ENABLED
|
||||||
|
/* #define HAL_TIM_MODULE_ENABLED */
|
||||||
|
/* #define HAL_UART_MODULE_ENABLED */
|
||||||
|
/* #define HAL_USART_MODULE_ENABLED */
|
||||||
|
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
/* #define HAL_WWDG_MODULE_ENABLED */
|
||||||
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
|
/* #define HAL_PCD_MODULE_ENABLED */
|
||||||
|
/* #define HAL_HCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||||
|
/**
|
||||||
|
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||||
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
|
* (when HSE is used as system clock source, directly or through the PLL).
|
||||||
|
*/
|
||||||
|
#if !defined (HSE_VALUE)
|
||||||
|
#define HSE_VALUE (25000000U) /*!< Value of the External oscillator in Hz */
|
||||||
|
#endif /* HSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||||
|
#define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */
|
||||||
|
#endif /* HSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal High Speed oscillator (HSI) value.
|
||||||
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
|
* (when HSI is used as system clock source, directly or through the PLL).
|
||||||
|
*/
|
||||||
|
#if !defined (HSI_VALUE)
|
||||||
|
#define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal Low Speed oscillator (LSI) value.
|
||||||
|
*/
|
||||||
|
#if !defined (LSI_VALUE)
|
||||||
|
#define LSI_VALUE (32000U)
|
||||||
|
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||||
|
The real value may vary depending on the variations
|
||||||
|
in voltage and temperature. */
|
||||||
|
/**
|
||||||
|
* @brief External Low Speed oscillator (LSE) value.
|
||||||
|
*/
|
||||||
|
#if !defined (LSE_VALUE)
|
||||||
|
#define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */
|
||||||
|
#endif /* LSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||||
|
#define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */
|
||||||
|
#endif /* LSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief External clock source for I2S peripheral
|
||||||
|
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||||
|
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||||
|
*/
|
||||||
|
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||||
|
#define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/
|
||||||
|
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||||
|
|
||||||
|
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||||
|
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||||
|
|
||||||
|
/* ########################### System Configuration ######################### */
|
||||||
|
/**
|
||||||
|
* @brief This is the HAL system configuration section
|
||||||
|
*/
|
||||||
|
#define VDD_VALUE (3300U) /*!< Value of VDD in mv */
|
||||||
|
#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */
|
||||||
|
#define USE_RTOS 0U
|
||||||
|
#define PREFETCH_ENABLE 1U
|
||||||
|
#define INSTRUCTION_CACHE_ENABLE 1U
|
||||||
|
#define DATA_CACHE_ENABLE 1U
|
||||||
|
|
||||||
|
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||||
|
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||||
|
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||||
|
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||||
|
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||||
|
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||||
|
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||||
|
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||||
|
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||||
|
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||||
|
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||||
|
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||||
|
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||||
|
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
|
||||||
|
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||||
|
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||||
|
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||||
|
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||||
|
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||||
|
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||||
|
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||||
|
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||||
|
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||||
|
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||||
|
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||||
|
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||||
|
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||||
|
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||||
|
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||||
|
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||||
|
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||||
|
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||||
|
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||||
|
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||||
|
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||||
|
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||||
|
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||||
|
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||||
|
|
||||||
|
/* ########################## Assert Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||||
|
* HAL drivers code
|
||||||
|
*/
|
||||||
|
/* #define USE_FULL_ASSERT 1U */
|
||||||
|
|
||||||
|
/* ################## SPI peripheral configuration ########################## */
|
||||||
|
|
||||||
|
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||||
|
* Activated: CRC code is present inside driver
|
||||||
|
* Deactivated: CRC code cleaned from driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_SPI_CRC 1U
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief Include module's header file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAL_RCC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_rcc.h"
|
||||||
|
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_gpio.h"
|
||||||
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DMA_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dma.h"
|
||||||
|
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_cortex.h"
|
||||||
|
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_ADC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_adc.h"
|
||||||
|
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_can.h"
|
||||||
|
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_can_legacy.h"
|
||||||
|
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CRC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_crc.h"
|
||||||
|
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_cryp.h"
|
||||||
|
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dma2d.h"
|
||||||
|
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DAC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dac.h"
|
||||||
|
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dcmi.h"
|
||||||
|
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_ETH_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_eth.h"
|
||||||
|
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_flash.h"
|
||||||
|
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sram.h"
|
||||||
|
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_NOR_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_nor.h"
|
||||||
|
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_NAND_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_nand.h"
|
||||||
|
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_pccard.h"
|
||||||
|
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sdram.h"
|
||||||
|
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_HASH_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_hash.h"
|
||||||
|
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_I2C_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_i2c.h"
|
||||||
|
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_I2S_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_i2s.h"
|
||||||
|
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_iwdg.h"
|
||||||
|
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_ltdc.h"
|
||||||
|
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PWR_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_pwr.h"
|
||||||
|
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_RNG_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_rng.h"
|
||||||
|
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_RTC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_rtc.h"
|
||||||
|
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SAI_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sai.h"
|
||||||
|
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sd.h"
|
||||||
|
#endif /* HAL_SD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SPI_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_spi.h"
|
||||||
|
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_TIM_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_tim.h"
|
||||||
|
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_UART_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_uart.h"
|
||||||
|
#endif /* HAL_UART_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_USART_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_usart.h"
|
||||||
|
#endif /* HAL_USART_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_irda.h"
|
||||||
|
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_smartcard.h"
|
||||||
|
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_wwdg.h"
|
||||||
|
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PCD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_pcd.h"
|
||||||
|
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_HCD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_hcd.h"
|
||||||
|
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
/**
|
||||||
|
* @brief The assert_param macro is used for function's parameters check.
|
||||||
|
* @param expr: If expr is false, it calls assert_failed function
|
||||||
|
* which reports the name of the source file and the source
|
||||||
|
* line number of the call that failed.
|
||||||
|
* If expr is true, it returns no value.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
void assert_failed(uint8_t* file, uint32_t line);
|
||||||
|
#else
|
||||||
|
#define assert_param(expr) ((void)0U)
|
||||||
|
#endif /* USE_FULL_ASSERT */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F4xx_HAL_CONF_H */
|
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -42,9 +42,5 @@ FREERTOS_PORT = ARM_CM4F
|
|||||||
JLINK_DEVICE = stm32f407vg
|
JLINK_DEVICE = stm32f407vg
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -55,7 +55,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 4
|
* APB1 Prescaler = 4
|
||||||
* APB2 Prescaler = 2
|
* APB2 Prescaler = 2
|
||||||
* HSE Frequency(Hz) = 8000000
|
* HSE Frequency(Hz) = 8000000
|
||||||
* PLL_M = 8
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 336
|
* PLL_N = 336
|
||||||
* PLL_P = 2
|
* PLL_P = 2
|
||||||
* PLL_Q = 7
|
* PLL_Q = 7
|
||||||
@ -83,7 +83,7 @@ static void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 8;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 336;
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
169
hw/bsp/stm32f411blackpill/STM32F411CEUx_FLASH.ld
Normal file
169
hw/bsp/stm32f411blackpill/STM32F411CEUx_FLASH.ld
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
*****************************************************************************
|
||||||
|
**
|
||||||
|
|
||||||
|
** File : LinkerScript.ld
|
||||||
|
**
|
||||||
|
** Abstract : Linker script for STM32F411CEUx Device with
|
||||||
|
** 512KByte FLASH, 128KByte RAM
|
||||||
|
**
|
||||||
|
** Set heap size, stack size and stack location according
|
||||||
|
** to application requirements.
|
||||||
|
**
|
||||||
|
** Set memory bank area and size if external memory is used.
|
||||||
|
**
|
||||||
|
** Target : STMicroelectronics STM32
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Distribution: The file is distributed as is, without any warranty
|
||||||
|
** of any kind.
|
||||||
|
**
|
||||||
|
** (c)Copyright Ac6.
|
||||||
|
** You may use this file as-is or modify it according to the needs of your
|
||||||
|
** project. Distribution of this file (unmodified or modified) is not
|
||||||
|
** permitted. Ac6 permit registered System Workbench for MCU users the
|
||||||
|
** rights to distribute the assembled, compiled & linked contents of this
|
||||||
|
** file as part of an application binary file, provided that it is built
|
||||||
|
** using the System Workbench for MCU toolchain.
|
||||||
|
**
|
||||||
|
*****************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Entry Point */
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
/* Highest address of the user mode stack */
|
||||||
|
_estack = 0x20020000; /* end of RAM */
|
||||||
|
/* Generate a link error if heap and stack don't fit into RAM */
|
||||||
|
_Min_Heap_Size = 0x200;; /* required amount of heap */
|
||||||
|
_Min_Stack_Size = 0x400;; /* required amount of stack */
|
||||||
|
|
||||||
|
/* Specify the memory areas */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define output sections */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* The startup code goes first into FLASH */
|
||||||
|
.isr_vector :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
/* The program code and other data goes into FLASH */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text) /* .text sections (code) */
|
||||||
|
*(.text*) /* .text* sections (code) */
|
||||||
|
*(.glue_7) /* glue arm to thumb code */
|
||||||
|
*(.glue_7t) /* glue thumb to arm code */
|
||||||
|
*(.eh_frame)
|
||||||
|
|
||||||
|
KEEP (*(.init))
|
||||||
|
KEEP (*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .; /* define a global symbols at end of code */
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
/* Constant data goes into FLASH */
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||||
|
.ARM : {
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array*))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >FLASH
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array*))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >FLASH
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
/* used by the startup to initialize data */
|
||||||
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
|
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sdata = .; /* create a global symbol at data start */
|
||||||
|
*(.data) /* .data sections */
|
||||||
|
*(.data*) /* .data* sections */
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .; /* define a global symbol at data end */
|
||||||
|
} >RAM AT> FLASH
|
||||||
|
|
||||||
|
|
||||||
|
/* Uninitialized data section */
|
||||||
|
. = ALIGN(4);
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
/* This is used by the startup in order to initialize the .bss secion */
|
||||||
|
_sbss = .; /* define a global symbol at bss start */
|
||||||
|
__bss_start__ = _sbss;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = .; /* define a global symbol at bss end */
|
||||||
|
__bss_end__ = _ebss;
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||||
|
._user_heap_stack :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE ( end = . );
|
||||||
|
PROVIDE ( _end = . );
|
||||||
|
. = . + _Min_Heap_Size;
|
||||||
|
. = . + _Min_Stack_Size;
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove information from the standard libraries */
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
libc.a ( * )
|
||||||
|
libm.a ( * )
|
||||||
|
libgcc.a ( * )
|
||||||
|
}
|
||||||
|
|
||||||
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
47
hw/bsp/stm32f411blackpill/board.mk
Normal file
47
hw/bsp/stm32f411blackpill/board.mk
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-flto \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs \
|
||||||
|
-mcpu=cortex-m4 \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv4-sp-d16 \
|
||||||
|
-nostdlib -nostartfiles \
|
||||||
|
-DSTM32F411xE \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_STM32F4
|
||||||
|
|
||||||
|
ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver
|
||||||
|
ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F4xx
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = hw/bsp/$(BOARD)/STM32F411CEUx_FLASH.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
$(ST_CMSIS)/Source/Templates/system_stm32f4xx.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal_cortex.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal_rcc.c \
|
||||||
|
$(ST_HAL_DRIVER)/Src/stm32f4xx_hal_gpio.c
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
$(ST_CMSIS)/Source/Templates/gcc/startup_stm32f411xe.s
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/mcu/st/st_driver/CMSIS/Include \
|
||||||
|
$(TOP)/$(ST_CMSIS)/Include \
|
||||||
|
$(TOP)/$(ST_HAL_DRIVER)/Inc \
|
||||||
|
$(TOP)/hw/bsp/$(BOARD)
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = st
|
||||||
|
CHIP_FAMILY = synopsys
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM4F
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = stm32f411ce
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# flash target ROM bootloader
|
||||||
|
flash: $(BUILD)/$(BOARD)-firmware.bin
|
||||||
|
dfu-util -R -a 0 --dfuse-address 0x08000000 -D $<
|
215
hw/bsp/stm32f411blackpill/stm32f411blackpill.c
Normal file
215
hw/bsp/stm32f411blackpill/stm32f411blackpill.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../board.h"
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f4xx_hal_conf.h"
|
||||||
|
|
||||||
|
#define LED_PORT GPIOC
|
||||||
|
#define LED_PIN GPIO_PIN_13
|
||||||
|
#define LED_STATE_ON 1
|
||||||
|
|
||||||
|
#define BUTTON_PORT GPIOA
|
||||||
|
#define BUTTON_PIN GPIO_PIN_0
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
// enable all LED, Button, Uart, USB clock
|
||||||
|
static void all_rcc_clk_enable(void)
|
||||||
|
{
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D-, Button
|
||||||
|
__HAL_RCC_GPIOC_CLK_ENABLE(); // LED
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System Clock Configuration
|
||||||
|
* The system Clock is configured as follow :
|
||||||
|
* System Clock source = PLL (HSE)
|
||||||
|
* SYSCLK(Hz) = 84000000
|
||||||
|
* HCLK(Hz) = 84000000
|
||||||
|
* AHB Prescaler = 1
|
||||||
|
* APB1 Prescaler = 2
|
||||||
|
* APB2 Prescaler = 1
|
||||||
|
* HSE Frequency(Hz) = 25000000
|
||||||
|
* PLL_M = HSE_VALUE/1000000
|
||||||
|
* PLL_N = 336
|
||||||
|
* PLL_P = 4
|
||||||
|
* PLL_Q = 7
|
||||||
|
* VDD(V) = 3.3
|
||||||
|
* Main regulator output voltage = Scale2 mode
|
||||||
|
* Flash Latency(WS) = 2
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void SystemClock_Config(void)
|
||||||
|
{
|
||||||
|
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||||
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||||
|
|
||||||
|
/* Enable Power Control clock */
|
||||||
|
__HAL_RCC_PWR_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* The voltage scaling allows optimizing the power consumption when the device is
|
||||||
|
clocked below the maximum system frequency, to update the voltage scaling value
|
||||||
|
regarding system frequency refer to product datasheet. */
|
||||||
|
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||||
|
|
||||||
|
/* Enable HSE Oscillator and activate PLL with HSE as source */
|
||||||
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||||
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
|
||||||
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||||
|
|
||||||
|
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
|
||||||
|
clocks dividers */
|
||||||
|
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
|
||||||
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||||
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||||
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||||
|
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(SystemCoreClock / 1000);
|
||||||
|
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
|
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
||||||
|
//NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SystemClock_Config();
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
all_rcc_clk_enable();
|
||||||
|
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
|
// LED
|
||||||
|
GPIO_InitStruct.Pin = LED_PIN;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
|
||||||
|
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
board_led_write(false);
|
||||||
|
|
||||||
|
// Button
|
||||||
|
GPIO_InitStruct.Pin = BUTTON_PIN;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
|
||||||
|
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* Configure USB FS GPIOs */
|
||||||
|
/* Configure USB D+ D- Pins */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* Configure VBUS Pin */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* This for ID line debug */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
// Enable USB OTG clock
|
||||||
|
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
|
||||||
|
|
||||||
|
// Blackpill doens't use VBUS sense (B device)
|
||||||
|
// explicitly disable it
|
||||||
|
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
|
||||||
|
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
|
||||||
|
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler (void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void HardFault_Handler (void)
|
||||||
|
{
|
||||||
|
asm("bkpt");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required by __libc_init_array in startup code if we are compiling using
|
||||||
|
// -nostdlib/-nostartfiles.
|
||||||
|
void _init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
394
hw/bsp/stm32f411blackpill/stm32f4xx_hal_conf.h
Normal file
394
hw/bsp/stm32f411blackpill/stm32f4xx_hal_conf.h
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file GPIO/GPIO_EXTI/Inc/stm32f4xx_hal_conf.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief HAL configuration file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F4xx_HAL_CONF_H
|
||||||
|
#define __STM32F4xx_HAL_CONF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ########################## Module Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief This is the list of modules to be used in the HAL driver
|
||||||
|
*/
|
||||||
|
#define HAL_MODULE_ENABLED
|
||||||
|
/* #define HAL_ADC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CAN_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CRC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_CRYP_MODULE_ENABLED */
|
||||||
|
/* #define HAL_DAC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_DCMI_MODULE_ENABLED */
|
||||||
|
#define HAL_DMA_MODULE_ENABLED
|
||||||
|
/* #define HAL_DMA2D_MODULE_ENABLED */
|
||||||
|
/* #define HAL_ETH_MODULE_ENABLED */
|
||||||
|
#define HAL_FLASH_MODULE_ENABLED
|
||||||
|
/* #define HAL_NAND_MODULE_ENABLED */
|
||||||
|
/* #define HAL_NOR_MODULE_ENABLED */
|
||||||
|
/* #define HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SRAM_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SDRAM_MODULE_ENABLED */
|
||||||
|
/* #define HAL_HASH_MODULE_ENABLED */
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
// #define HAL_I2C_MODULE_ENABLED
|
||||||
|
/* #define HAL_I2S_MODULE_ENABLED */
|
||||||
|
/* #define HAL_IWDG_MODULE_ENABLED */
|
||||||
|
/* #define HAL_LTDC_MODULE_ENABLED */
|
||||||
|
#define HAL_PWR_MODULE_ENABLED
|
||||||
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
/* #define HAL_RNG_MODULE_ENABLED */
|
||||||
|
/* #define HAL_RTC_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SAI_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SD_MODULE_ENABLED */
|
||||||
|
// #define HAL_SPI_MODULE_ENABLED
|
||||||
|
/* #define HAL_TIM_MODULE_ENABLED */
|
||||||
|
/* #define HAL_UART_MODULE_ENABLED */
|
||||||
|
/* #define HAL_USART_MODULE_ENABLED */
|
||||||
|
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||||
|
/* #define HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
/* #define HAL_WWDG_MODULE_ENABLED */
|
||||||
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
|
/* #define HAL_PCD_MODULE_ENABLED */
|
||||||
|
/* #define HAL_HCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||||
|
/**
|
||||||
|
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||||
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
|
* (when HSE is used as system clock source, directly or through the PLL).
|
||||||
|
*/
|
||||||
|
#if !defined (HSE_VALUE)
|
||||||
|
#define HSE_VALUE (25000000U) /*!< Value of the External oscillator in Hz */
|
||||||
|
#endif /* HSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||||
|
#define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */
|
||||||
|
#endif /* HSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal High Speed oscillator (HSI) value.
|
||||||
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
|
* (when HSI is used as system clock source, directly or through the PLL).
|
||||||
|
*/
|
||||||
|
#if !defined (HSI_VALUE)
|
||||||
|
#define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal Low Speed oscillator (LSI) value.
|
||||||
|
*/
|
||||||
|
#if !defined (LSI_VALUE)
|
||||||
|
#define LSI_VALUE (32000U)
|
||||||
|
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||||
|
The real value may vary depending on the variations
|
||||||
|
in voltage and temperature. */
|
||||||
|
/**
|
||||||
|
* @brief External Low Speed oscillator (LSE) value.
|
||||||
|
*/
|
||||||
|
#if !defined (LSE_VALUE)
|
||||||
|
#define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */
|
||||||
|
#endif /* LSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||||
|
#define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */
|
||||||
|
#endif /* LSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief External clock source for I2S peripheral
|
||||||
|
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||||
|
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||||
|
*/
|
||||||
|
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||||
|
#define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/
|
||||||
|
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||||
|
|
||||||
|
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||||
|
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||||
|
|
||||||
|
/* ########################### System Configuration ######################### */
|
||||||
|
/**
|
||||||
|
* @brief This is the HAL system configuration section
|
||||||
|
*/
|
||||||
|
#define VDD_VALUE (3300U) /*!< Value of VDD in mv */
|
||||||
|
#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */
|
||||||
|
#define USE_RTOS 0U
|
||||||
|
#define PREFETCH_ENABLE 1U
|
||||||
|
#define INSTRUCTION_CACHE_ENABLE 1U
|
||||||
|
#define DATA_CACHE_ENABLE 1U
|
||||||
|
|
||||||
|
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||||
|
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||||
|
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||||
|
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||||
|
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||||
|
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||||
|
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||||
|
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||||
|
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||||
|
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||||
|
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||||
|
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||||
|
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||||
|
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
|
||||||
|
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||||
|
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||||
|
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||||
|
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||||
|
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||||
|
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||||
|
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||||
|
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||||
|
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||||
|
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||||
|
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||||
|
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||||
|
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||||
|
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||||
|
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||||
|
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||||
|
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||||
|
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||||
|
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||||
|
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||||
|
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||||
|
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||||
|
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||||
|
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||||
|
|
||||||
|
/* ########################## Assert Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||||
|
* HAL drivers code
|
||||||
|
*/
|
||||||
|
/* #define USE_FULL_ASSERT 1U */
|
||||||
|
|
||||||
|
/* ################## SPI peripheral configuration ########################## */
|
||||||
|
|
||||||
|
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||||
|
* Activated: CRC code is present inside driver
|
||||||
|
* Deactivated: CRC code cleaned from driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_SPI_CRC 1U
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief Include module's header file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAL_RCC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_rcc.h"
|
||||||
|
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_gpio.h"
|
||||||
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DMA_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dma.h"
|
||||||
|
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_cortex.h"
|
||||||
|
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_ADC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_adc.h"
|
||||||
|
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_can.h"
|
||||||
|
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_can_legacy.h"
|
||||||
|
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CRC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_crc.h"
|
||||||
|
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_cryp.h"
|
||||||
|
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dma2d.h"
|
||||||
|
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DAC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dac.h"
|
||||||
|
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_dcmi.h"
|
||||||
|
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_ETH_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_eth.h"
|
||||||
|
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_flash.h"
|
||||||
|
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sram.h"
|
||||||
|
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_NOR_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_nor.h"
|
||||||
|
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_NAND_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_nand.h"
|
||||||
|
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_pccard.h"
|
||||||
|
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sdram.h"
|
||||||
|
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_HASH_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_hash.h"
|
||||||
|
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_I2C_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_i2c.h"
|
||||||
|
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_I2S_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_i2s.h"
|
||||||
|
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_iwdg.h"
|
||||||
|
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_ltdc.h"
|
||||||
|
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PWR_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_pwr.h"
|
||||||
|
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_RNG_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_rng.h"
|
||||||
|
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_RTC_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_rtc.h"
|
||||||
|
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SAI_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sai.h"
|
||||||
|
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_sd.h"
|
||||||
|
#endif /* HAL_SD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SPI_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_spi.h"
|
||||||
|
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_TIM_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_tim.h"
|
||||||
|
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_UART_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_uart.h"
|
||||||
|
#endif /* HAL_UART_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_USART_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_usart.h"
|
||||||
|
#endif /* HAL_USART_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_irda.h"
|
||||||
|
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_smartcard.h"
|
||||||
|
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_wwdg.h"
|
||||||
|
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PCD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_pcd.h"
|
||||||
|
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_HCD_MODULE_ENABLED
|
||||||
|
#include "stm32f4xx_hal_hcd.h"
|
||||||
|
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
/**
|
||||||
|
* @brief The assert_param macro is used for function's parameters check.
|
||||||
|
* @param expr: If expr is false, it calls assert_failed function
|
||||||
|
* which reports the name of the source file and the source
|
||||||
|
* line number of the call that failed.
|
||||||
|
* If expr is true, it returns no value.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
void assert_failed(uint8_t* file, uint32_t line);
|
||||||
|
#else
|
||||||
|
#define assert_param(expr) ((void)0U)
|
||||||
|
#endif /* USE_FULL_ASSERT */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F4xx_HAL_CONF_H */
|
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -39,12 +39,8 @@ CHIP_FAMILY = synopsys
|
|||||||
FREERTOS_PORT = ARM_CM4F
|
FREERTOS_PORT = ARM_CM4F
|
||||||
|
|
||||||
# For flash-jlink target
|
# For flash-jlink target
|
||||||
JLINK_DEVICE = stm32f41ve
|
JLINK_DEVICE = stm32f411ve
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -54,7 +54,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 2
|
* APB1 Prescaler = 2
|
||||||
* APB2 Prescaler = 1
|
* APB2 Prescaler = 1
|
||||||
* HSE Frequency(Hz) = 8000000
|
* HSE Frequency(Hz) = 8000000
|
||||||
* PLL_M = 8
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 336
|
* PLL_N = 336
|
||||||
* PLL_P = 4
|
* PLL_P = 4
|
||||||
* PLL_Q = 7
|
* PLL_Q = 7
|
||||||
@ -82,7 +82,7 @@ static void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 8;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 336;
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
@ -46,9 +46,5 @@ FREERTOS_PORT = ARM_CM4F
|
|||||||
JLINK_DEVICE = stm32f41zx
|
JLINK_DEVICE = stm32f41zx
|
||||||
JLINK_IF = swd
|
JLINK_IF = swd
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -56,7 +56,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 2
|
* APB1 Prescaler = 2
|
||||||
* APB2 Prescaler = 1
|
* APB2 Prescaler = 1
|
||||||
* HSE Frequency(Hz) = 8000000
|
* HSE Frequency(Hz) = 8000000
|
||||||
* PLL_M = 8
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 200
|
* PLL_N = 200
|
||||||
* PLL_P = 2
|
* PLL_P = 2
|
||||||
* PLL_Q = 7
|
* PLL_Q = 7
|
||||||
@ -91,7 +91,7 @@ static void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 8;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 200;
|
RCC_OscInitStruct.PLL.PLLN = 200;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
@ -41,9 +41,5 @@ INC += \
|
|||||||
VENDOR = st
|
VENDOR = st
|
||||||
CHIP_FAMILY = synopsys
|
CHIP_FAMILY = synopsys
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -66,7 +66,7 @@ static void all_rcc_clk_enable(void)
|
|||||||
* APB1 Prescaler = 4
|
* APB1 Prescaler = 4
|
||||||
* APB2 Prescaler = 2
|
* APB2 Prescaler = 2
|
||||||
* HSE Frequency(Hz) = 8000000
|
* HSE Frequency(Hz) = 8000000
|
||||||
* PLL_M = 8
|
* PLL_M = HSE_VALUE/1000000
|
||||||
* PLL_N = 432
|
* PLL_N = 432
|
||||||
* PLL_P = 2
|
* PLL_P = 2
|
||||||
* PLL_Q = 9
|
* PLL_Q = 9
|
||||||
@ -99,7 +99,7 @@ void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 8;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 432;
|
RCC_OscInitStruct.PLL.PLLN = 432;
|
||||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 9;
|
RCC_OscInitStruct.PLL.PLLQ = 9;
|
||||||
|
@ -40,9 +40,5 @@ INC += \
|
|||||||
VENDOR = st
|
VENDOR = st
|
||||||
CHIP_FAMILY = synopsys
|
CHIP_FAMILY = synopsys
|
||||||
|
|
||||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
|
||||||
STM32Prog = STM32_Programmer_CLI
|
|
||||||
|
|
||||||
# flash target using on-board stlink
|
# flash target using on-board stlink
|
||||||
flash: $(BUILD)/$(BOARD)-firmware.elf
|
flash: flash-stlink
|
||||||
$(STM32Prog) --connect port=swd --write $< --go
|
|
||||||
|
@ -94,7 +94,7 @@ static void SystemClock_Config(void)
|
|||||||
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
|
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
RCC_OscInitStruct.PLL.PLLM = 8;
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
|
||||||
RCC_OscInitStruct.PLL.PLLN = 336;
|
RCC_OscInitStruct.PLL.PLLN = 336;
|
||||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
36
hw/bsp/teensy_40/board.h
Normal file
36
hw/bsp/teensy_40/board.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BOARD_H_
|
||||||
|
#define BOARD_H_
|
||||||
|
|
||||||
|
|
||||||
|
// required since iMX RT10xx SDK include this file for board size
|
||||||
|
#define BOARD_FLASH_SIZE (2 * 1024 * 1024)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BOARD_H_ */
|
54
hw/bsp/teensy_40/board.mk
Normal file
54
hw/bsp/teensy_40/board.mk
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
CFLAGS += \
|
||||||
|
-mthumb \
|
||||||
|
-mabi=aapcs \
|
||||||
|
-mcpu=cortex-m7 \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv5-d16 \
|
||||||
|
-D__ARMVFP__=0 -D__ARMFPV5__=0\
|
||||||
|
-DCPU_MIMXRT1062DVL6A \
|
||||||
|
-DXIP_EXTERNAL_FLASH=1 \
|
||||||
|
-DXIP_BOOT_HEADER_ENABLE=1 \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX
|
||||||
|
|
||||||
|
# mcu driver cause following warnings
|
||||||
|
#CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs
|
||||||
|
CFLAGS += -Wno-error=unused-parameter
|
||||||
|
|
||||||
|
MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1062
|
||||||
|
|
||||||
|
# All source paths should be relative to the top level.
|
||||||
|
LD_FILE = $(MCU_DIR)/gcc/MIMXRT1062xxxxx_flexspi_nor.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
$(MCU_DIR)/system_MIMXRT1062.c \
|
||||||
|
$(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \
|
||||||
|
$(MCU_DIR)/project_template/clock_config.c \
|
||||||
|
$(MCU_DIR)/drivers/fsl_clock.c \
|
||||||
|
$(MCU_DIR)/drivers/fsl_gpio.c \
|
||||||
|
$(MCU_DIR)/drivers/fsl_common.c \
|
||||||
|
$(MCU_DIR)/drivers/fsl_lpuart.c
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/hw/bsp/$(BOARD) \
|
||||||
|
$(TOP)/$(MCU_DIR)/../../CMSIS/Include \
|
||||||
|
$(TOP)/$(MCU_DIR) \
|
||||||
|
$(TOP)/$(MCU_DIR)/drivers \
|
||||||
|
$(TOP)/$(MCU_DIR)/project_template \
|
||||||
|
|
||||||
|
SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1062.S
|
||||||
|
|
||||||
|
# For TinyUSB port source
|
||||||
|
VENDOR = nxp
|
||||||
|
CHIP_FAMILY = transdimension
|
||||||
|
|
||||||
|
# For freeRTOS port source
|
||||||
|
FREERTOS_PORT = ARM_CM7
|
||||||
|
|
||||||
|
# For flash-jlink target
|
||||||
|
JLINK_DEVICE = MIMXRT1062xxx6A
|
||||||
|
JLINK_IF = swd
|
||||||
|
|
||||||
|
# flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli
|
||||||
|
# Make sure it is in your PATH
|
||||||
|
flash: $(BUILD)/$(BOARD)-firmware.hex
|
||||||
|
teensy_loader_cli --mcu=imxrt1062 -v -w $<
|
185
hw/bsp/teensy_40/teensy40.c
Normal file
185
hw/bsp/teensy_40/teensy40.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018, hathach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../board.h"
|
||||||
|
#include "fsl_device_registers.h"
|
||||||
|
#include "fsl_gpio.h"
|
||||||
|
#include "fsl_iomuxc.h"
|
||||||
|
#include "fsl_clock.h"
|
||||||
|
#include "fsl_lpuart.h"
|
||||||
|
|
||||||
|
#include "clock_config.h"
|
||||||
|
|
||||||
|
#define LED_PINMUX IOMUXC_GPIO_B0_03_GPIO2_IO03 // D13
|
||||||
|
#define LED_PORT GPIO2
|
||||||
|
#define LED_PIN 3
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
// no button
|
||||||
|
#define BUTTON_PINMUX IOMUXC_GPIO_B0_01_GPIO2_IO01 // D12
|
||||||
|
#define BUTTON_PORT GPIO2
|
||||||
|
#define BUTTON_PIN 1
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
// UART
|
||||||
|
#define UART_PORT LPUART6
|
||||||
|
#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_03_LPUART6_RX // D0
|
||||||
|
#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_02_LPUART6_TX // D1
|
||||||
|
|
||||||
|
const uint8_t dcd_data[] = { 0x00 };
|
||||||
|
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
// Init clock
|
||||||
|
BOARD_BootClockRUN();
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
|
// Enable IOCON clock
|
||||||
|
CLOCK_EnableClock(kCLOCK_Iomuxc);
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
// 1ms tick timer
|
||||||
|
SysTick_Config(SystemCoreClock / 1000);
|
||||||
|
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
|
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
||||||
|
// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// LED
|
||||||
|
IOMUXC_SetPinMux( LED_PINMUX, 0U);
|
||||||
|
IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U);
|
||||||
|
|
||||||
|
gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode };
|
||||||
|
GPIO_PinInit(LED_PORT, LED_PIN, &led_config);
|
||||||
|
board_led_write(true);
|
||||||
|
|
||||||
|
// Button
|
||||||
|
IOMUXC_SetPinMux( BUTTON_PINMUX, 0U);
|
||||||
|
IOMUXC_SetPinConfig(BUTTON_PINMUX, 0x01B0A0U);
|
||||||
|
gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_NoIntmode };
|
||||||
|
GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config);
|
||||||
|
|
||||||
|
// UART
|
||||||
|
IOMUXC_SetPinMux( UART_TX_PINMUX, 0U);
|
||||||
|
IOMUXC_SetPinMux( UART_RX_PINMUX, 0U);
|
||||||
|
IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u);
|
||||||
|
IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u);
|
||||||
|
|
||||||
|
lpuart_config_t uart_config;
|
||||||
|
LPUART_GetDefaultConfig(&uart_config);
|
||||||
|
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
|
||||||
|
uart_config.enableTx = true;
|
||||||
|
uart_config.enableRx = true;
|
||||||
|
LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U));
|
||||||
|
|
||||||
|
//------------- USB0 -------------//
|
||||||
|
// Clock
|
||||||
|
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||||
|
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
|
||||||
|
|
||||||
|
USBPHY_Type* usb_phy = USBPHY1;
|
||||||
|
|
||||||
|
// Enable PHY support for Low speed device + LS via FS Hub
|
||||||
|
usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK;
|
||||||
|
|
||||||
|
// Enable all power for normal operation
|
||||||
|
usb_phy->PWD = 0;
|
||||||
|
|
||||||
|
// TX Timing
|
||||||
|
uint32_t phytx = usb_phy->TX;
|
||||||
|
phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK);
|
||||||
|
phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
|
||||||
|
usb_phy->TX = phytx;
|
||||||
|
|
||||||
|
// USB1
|
||||||
|
// CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||||
|
// CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// USB Interrupt Handler
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void USB_OTG1_IRQHandler(void)
|
||||||
|
{
|
||||||
|
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST
|
||||||
|
tuh_isr(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE
|
||||||
|
tud_isr(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void USB_OTG2_IRQHandler(void)
|
||||||
|
{
|
||||||
|
#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST
|
||||||
|
tuh_isr(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE
|
||||||
|
tud_isr(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board porting API
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
// active low
|
||||||
|
return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
LPUART_ReadBlocking(UART_PORT, buf, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
void SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void)
|
||||||
|
{
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
49
hw/bsp/teensy_40/teensy40_flexspi_nor_config.c
Normal file
49
hw/bsp/teensy_40/teensy40_flexspi_nor_config.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "teensy40_flexspi_nor_config.h"
|
||||||
|
|
||||||
|
/* Component ID definition, used by tools. */
|
||||||
|
#ifndef FSL_COMPONENT_ID
|
||||||
|
#define FSL_COMPONENT_ID "platform.drivers.xip_board"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code
|
||||||
|
******************************************************************************/
|
||||||
|
#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
|
||||||
|
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
|
||||||
|
__attribute__((section(".boot_hdr.conf")))
|
||||||
|
#elif defined(__ICCARM__)
|
||||||
|
#pragma location = ".boot_hdr.conf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const flexspi_nor_config_t qspiflash_config = {
|
||||||
|
.memConfig =
|
||||||
|
{
|
||||||
|
.tag = FLEXSPI_CFG_BLK_TAG,
|
||||||
|
.version = FLEXSPI_CFG_BLK_VERSION,
|
||||||
|
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
|
||||||
|
.csHoldTime = 3u,
|
||||||
|
.csSetupTime = 3u,
|
||||||
|
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
|
||||||
|
.sflashPadType = kSerialFlash_4Pads,
|
||||||
|
.serialClkFreq = kFlexSpiSerialClk_100MHz,
|
||||||
|
.sflashA1Size = 2u * 1024u * 1024u,
|
||||||
|
.lookupTable =
|
||||||
|
{
|
||||||
|
// Read LUTs
|
||||||
|
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
|
||||||
|
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.pageSize = 256u,
|
||||||
|
.sectorSize = 4u * 1024u,
|
||||||
|
.blockSize = 256u * 1024u,
|
||||||
|
.isUniformBlockSize = false,
|
||||||
|
};
|
||||||
|
#endif /* XIP_BOOT_HEADER_ENABLE */
|
268
hw/bsp/teensy_40/teensy40_flexspi_nor_config.h
Normal file
268
hw/bsp/teensy_40/teensy40_flexspi_nor_config.h
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__
|
||||||
|
#define __TEENSY40_FLEXSPI_NOR_CONFIG__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "fsl_common.h"
|
||||||
|
|
||||||
|
/*! @name Driver version */
|
||||||
|
/*@{*/
|
||||||
|
/*! @brief XIP_BOARD driver version 2.0.0. */
|
||||||
|
#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
/* FLEXSPI memory config block related defintions */
|
||||||
|
#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian
|
||||||
|
#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0
|
||||||
|
#define FLEXSPI_CFG_BLK_SIZE (512)
|
||||||
|
|
||||||
|
/* FLEXSPI Feature related definitions */
|
||||||
|
#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1
|
||||||
|
|
||||||
|
/* Lookup table related defintions */
|
||||||
|
#define CMD_INDEX_READ 0
|
||||||
|
#define CMD_INDEX_READSTATUS 1
|
||||||
|
#define CMD_INDEX_WRITEENABLE 2
|
||||||
|
#define CMD_INDEX_WRITE 4
|
||||||
|
|
||||||
|
#define CMD_LUT_SEQ_IDX_READ 0
|
||||||
|
#define CMD_LUT_SEQ_IDX_READSTATUS 1
|
||||||
|
#define CMD_LUT_SEQ_IDX_WRITEENABLE 3
|
||||||
|
#define CMD_LUT_SEQ_IDX_WRITE 9
|
||||||
|
|
||||||
|
#define CMD_SDR 0x01
|
||||||
|
#define CMD_DDR 0x21
|
||||||
|
#define RADDR_SDR 0x02
|
||||||
|
#define RADDR_DDR 0x22
|
||||||
|
#define CADDR_SDR 0x03
|
||||||
|
#define CADDR_DDR 0x23
|
||||||
|
#define MODE1_SDR 0x04
|
||||||
|
#define MODE1_DDR 0x24
|
||||||
|
#define MODE2_SDR 0x05
|
||||||
|
#define MODE2_DDR 0x25
|
||||||
|
#define MODE4_SDR 0x06
|
||||||
|
#define MODE4_DDR 0x26
|
||||||
|
#define MODE8_SDR 0x07
|
||||||
|
#define MODE8_DDR 0x27
|
||||||
|
#define WRITE_SDR 0x08
|
||||||
|
#define WRITE_DDR 0x28
|
||||||
|
#define READ_SDR 0x09
|
||||||
|
#define READ_DDR 0x29
|
||||||
|
#define LEARN_SDR 0x0A
|
||||||
|
#define LEARN_DDR 0x2A
|
||||||
|
#define DATSZ_SDR 0x0B
|
||||||
|
#define DATSZ_DDR 0x2B
|
||||||
|
#define DUMMY_SDR 0x0C
|
||||||
|
#define DUMMY_DDR 0x2C
|
||||||
|
#define DUMMY_RWDS_SDR 0x0D
|
||||||
|
#define DUMMY_RWDS_DDR 0x2D
|
||||||
|
#define JMP_ON_CS 0x1F
|
||||||
|
#define STOP 0
|
||||||
|
|
||||||
|
#define FLEXSPI_1PAD 0
|
||||||
|
#define FLEXSPI_2PAD 1
|
||||||
|
#define FLEXSPI_4PAD 2
|
||||||
|
#define FLEXSPI_8PAD 3
|
||||||
|
|
||||||
|
#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
|
||||||
|
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
|
||||||
|
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
|
||||||
|
|
||||||
|
//!@brief Definitions for FlexSPI Serial Clock Frequency
|
||||||
|
typedef enum _FlexSpiSerialClockFreq
|
||||||
|
{
|
||||||
|
kFlexSpiSerialClk_30MHz = 1,
|
||||||
|
kFlexSpiSerialClk_50MHz = 2,
|
||||||
|
kFlexSpiSerialClk_60MHz = 3,
|
||||||
|
kFlexSpiSerialClk_75MHz = 4,
|
||||||
|
kFlexSpiSerialClk_80MHz = 5,
|
||||||
|
kFlexSpiSerialClk_100MHz = 6,
|
||||||
|
kFlexSpiSerialClk_120MHz = 7,
|
||||||
|
kFlexSpiSerialClk_133MHz = 8,
|
||||||
|
kFlexSpiSerialClk_166MHz = 9,
|
||||||
|
} flexspi_serial_clk_freq_t;
|
||||||
|
|
||||||
|
//!@brief FlexSPI clock configuration type
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kFlexSpiClk_SDR, //!< Clock configure for SDR mode
|
||||||
|
kFlexSpiClk_DDR, //!< Clock configurat for DDR mode
|
||||||
|
};
|
||||||
|
|
||||||
|
//!@brief FlexSPI Read Sample Clock Source definition
|
||||||
|
typedef enum _FlashReadSampleClkSource
|
||||||
|
{
|
||||||
|
kFlexSPIReadSampleClk_LoopbackInternally = 0,
|
||||||
|
kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1,
|
||||||
|
kFlexSPIReadSampleClk_LoopbackFromSckPad = 2,
|
||||||
|
kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3,
|
||||||
|
} flexspi_read_sample_clk_t;
|
||||||
|
|
||||||
|
//!@brief Misc feature bit definitions
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable
|
||||||
|
kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable
|
||||||
|
kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable
|
||||||
|
kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable
|
||||||
|
kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable
|
||||||
|
kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable
|
||||||
|
kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication.
|
||||||
|
};
|
||||||
|
|
||||||
|
//!@brief Flash Type Definition
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR
|
||||||
|
kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND
|
||||||
|
kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH
|
||||||
|
kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND
|
||||||
|
kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs
|
||||||
|
};
|
||||||
|
|
||||||
|
//!@brief Flash Pad Definitions
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kSerialFlash_1Pad = 1,
|
||||||
|
kSerialFlash_2Pads = 2,
|
||||||
|
kSerialFlash_4Pads = 4,
|
||||||
|
kSerialFlash_8Pads = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
//!@brief FlexSPI LUT Sequence structure
|
||||||
|
typedef struct _lut_sequence
|
||||||
|
{
|
||||||
|
uint8_t seqNum; //!< Sequence Number, valid number: 1-16
|
||||||
|
uint8_t seqId; //!< Sequence Index, valid number: 0-15
|
||||||
|
uint16_t reserved;
|
||||||
|
} flexspi_lut_seq_t;
|
||||||
|
|
||||||
|
//!@brief Flash Configuration Command Type
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc
|
||||||
|
kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command
|
||||||
|
kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode
|
||||||
|
kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode
|
||||||
|
kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode
|
||||||
|
kDeviceConfigCmdType_Reset, //!< Reset device command
|
||||||
|
};
|
||||||
|
|
||||||
|
//!@brief FlexSPI Memory Configuration Block
|
||||||
|
typedef struct _FlexSPIConfig
|
||||||
|
{
|
||||||
|
uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL
|
||||||
|
uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix
|
||||||
|
uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use
|
||||||
|
uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3
|
||||||
|
uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3
|
||||||
|
uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3
|
||||||
|
uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For
|
||||||
|
//! Serial NAND, need to refer to datasheet
|
||||||
|
uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable
|
||||||
|
uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch,
|
||||||
|
//! Generic configuration, etc.
|
||||||
|
uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for
|
||||||
|
//! DPI/QPI/OPI switch or reset command
|
||||||
|
flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt
|
||||||
|
//! sequence number, [31:16] Reserved
|
||||||
|
uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration
|
||||||
|
uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable
|
||||||
|
uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe
|
||||||
|
flexspi_lut_seq_t
|
||||||
|
configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq
|
||||||
|
uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use
|
||||||
|
uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands
|
||||||
|
uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use
|
||||||
|
uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more
|
||||||
|
//! details
|
||||||
|
uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details
|
||||||
|
uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal
|
||||||
|
uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
|
||||||
|
//! Chapter for more details
|
||||||
|
uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
|
||||||
|
//! be done using 1 LUT sequence, currently, only applicable to HyperFLASH
|
||||||
|
uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use
|
||||||
|
uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1
|
||||||
|
uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2
|
||||||
|
uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1
|
||||||
|
uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2
|
||||||
|
uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value
|
||||||
|
uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value
|
||||||
|
uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value
|
||||||
|
uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value
|
||||||
|
uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command
|
||||||
|
uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands
|
||||||
|
uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns
|
||||||
|
uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31
|
||||||
|
uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 -
|
||||||
|
//! busy flag is 0 when flash device is busy
|
||||||
|
uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences
|
||||||
|
flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences
|
||||||
|
uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use
|
||||||
|
} flexspi_mem_config_t;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0
|
||||||
|
#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1
|
||||||
|
#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2
|
||||||
|
#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3
|
||||||
|
#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4
|
||||||
|
#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5
|
||||||
|
#define NOR_CMD_INDEX_DUMMY 6 //!< 6
|
||||||
|
#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7
|
||||||
|
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \
|
||||||
|
CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \
|
||||||
|
2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \
|
||||||
|
CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \
|
||||||
|
4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \
|
||||||
|
CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \
|
||||||
|
14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block
|
||||||
|
#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \
|
||||||
|
15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial NOR configuration block
|
||||||
|
*/
|
||||||
|
typedef struct _flexspi_nor_config
|
||||||
|
{
|
||||||
|
flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI
|
||||||
|
uint32_t pageSize; //!< Page size of Serial NOR
|
||||||
|
uint32_t sectorSize; //!< Sector size of Serial NOR
|
||||||
|
uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command
|
||||||
|
uint8_t isUniformBlockSize; //!< Sector/Block size is the same
|
||||||
|
uint8_t reserved0[2]; //!< Reserved for future use
|
||||||
|
uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3
|
||||||
|
uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command
|
||||||
|
uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false
|
||||||
|
uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution
|
||||||
|
uint32_t blockSize; //!< Block size
|
||||||
|
uint32_t reserve2[11]; //!< Reserved for future use
|
||||||
|
} flexspi_nor_config_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */
|
1
hw/mcu/nuvoton
Submodule
1
hw/mcu/nuvoton
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit dc96fff794d14818c93ea1d4d760d51a014d70c5
|
@ -1,100 +1,100 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_class
|
/** \ingroup group_class
|
||||||
* \defgroup ClassDriver_Audio Audio
|
* \defgroup ClassDriver_Audio Audio
|
||||||
* Currently only MIDI subclass is supported
|
* Currently only MIDI subclass is supported
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_AUDIO_H__
|
#ifndef _TUSB_AUDIO_H__
|
||||||
#define _TUSB_AUDIO_H__
|
#define _TUSB_AUDIO_H__
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Audio Interface Subclass Codes
|
/// Audio Interface Subclass Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
AUDIO_SUBCLASS_CONTROL = 0x01 , ///< Audio Control
|
AUDIO_SUBCLASS_CONTROL = 0x01 , ///< Audio Control
|
||||||
AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming
|
AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming
|
||||||
AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
|
AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
|
||||||
} audio_subclass_type_t;
|
} audio_subclass_type_t;
|
||||||
|
|
||||||
/// Audio Protocol Codes
|
/// Audio Protocol Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
AUDIO_PROTOCOL_V1 = 0x00, ///< Version 1.0
|
AUDIO_PROTOCOL_V1 = 0x00, ///< Version 1.0
|
||||||
AUDIO_PROTOCOL_V2 = 0x20, ///< Version 2.0
|
AUDIO_PROTOCOL_V2 = 0x20, ///< Version 2.0
|
||||||
AUDIO_PROTOCOL_V3 = 0x30, ///< Version 3.0
|
AUDIO_PROTOCOL_V3 = 0x30, ///< Version 3.0
|
||||||
} audio_protocol_type_t;
|
} audio_protocol_type_t;
|
||||||
|
|
||||||
/// Audio Function Category Codes
|
/// Audio Function Category Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
AUDIO_FUNC_DESKTOP_SPEAKER = 0x01,
|
AUDIO_FUNC_DESKTOP_SPEAKER = 0x01,
|
||||||
AUDIO_FUNC_HOME_THEATER = 0x02,
|
AUDIO_FUNC_HOME_THEATER = 0x02,
|
||||||
AUDIO_FUNC_MICROPHONE = 0x03,
|
AUDIO_FUNC_MICROPHONE = 0x03,
|
||||||
AUDIO_FUNC_HEADSET = 0x04,
|
AUDIO_FUNC_HEADSET = 0x04,
|
||||||
AUDIO_FUNC_TELEPHONE = 0x05,
|
AUDIO_FUNC_TELEPHONE = 0x05,
|
||||||
AUDIO_FUNC_CONVERTER = 0x06,
|
AUDIO_FUNC_CONVERTER = 0x06,
|
||||||
AUDIO_FUNC_SOUND_RECODER = 0x07,
|
AUDIO_FUNC_SOUND_RECODER = 0x07,
|
||||||
AUDIO_FUNC_IO_BOX = 0x08,
|
AUDIO_FUNC_IO_BOX = 0x08,
|
||||||
AUDIO_FUNC_MUSICAL_INSTRUMENT = 0x09,
|
AUDIO_FUNC_MUSICAL_INSTRUMENT = 0x09,
|
||||||
AUDIO_FUNC_PRO_AUDIO = 0x0A,
|
AUDIO_FUNC_PRO_AUDIO = 0x0A,
|
||||||
AUDIO_FUNC_AUDIO_VIDEO = 0x0B,
|
AUDIO_FUNC_AUDIO_VIDEO = 0x0B,
|
||||||
AUDIO_FUNC_CONTROL_PANEL = 0x0C
|
AUDIO_FUNC_CONTROL_PANEL = 0x0C
|
||||||
} audio_function_t;
|
} audio_function_t;
|
||||||
|
|
||||||
/// Audio Class-Specific AC Interface Descriptor Subtypes
|
/// Audio Class-Specific AC Interface Descriptor Subtypes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
AUDIO_CS_INTERFACE_HEADER = 0x01,
|
AUDIO_CS_INTERFACE_HEADER = 0x01,
|
||||||
AUDIO_CS_INTERFACE_INPUT_TERMINAL = 0x02,
|
AUDIO_CS_INTERFACE_INPUT_TERMINAL = 0x02,
|
||||||
AUDIO_CS_INTERFACE_OUTPUT_TERMINAL = 0x03,
|
AUDIO_CS_INTERFACE_OUTPUT_TERMINAL = 0x03,
|
||||||
AUDIO_CS_INTERFACE_MIXER_UNIT = 0x04,
|
AUDIO_CS_INTERFACE_MIXER_UNIT = 0x04,
|
||||||
AUDIO_CS_INTERFACE_SELECTOR_UNIT = 0x05,
|
AUDIO_CS_INTERFACE_SELECTOR_UNIT = 0x05,
|
||||||
AUDIO_CS_INTERFACE_FEATURE_UNIT = 0x06,
|
AUDIO_CS_INTERFACE_FEATURE_UNIT = 0x06,
|
||||||
AUDIO_CS_INTERFACE_EFFECT_UNIT = 0x07,
|
AUDIO_CS_INTERFACE_EFFECT_UNIT = 0x07,
|
||||||
AUDIO_CS_INTERFACE_PROCESSING_UNIT = 0x08,
|
AUDIO_CS_INTERFACE_PROCESSING_UNIT = 0x08,
|
||||||
AUDIO_CS_INTERFACE_EXTENSION_UNIT = 0x09,
|
AUDIO_CS_INTERFACE_EXTENSION_UNIT = 0x09,
|
||||||
AUDIO_CS_INTERFACE_CLOCK_SOURCE = 0x0A,
|
AUDIO_CS_INTERFACE_CLOCK_SOURCE = 0x0A,
|
||||||
AUDIO_CS_INTERFACE_CLOCK_SELECTOR = 0x0B,
|
AUDIO_CS_INTERFACE_CLOCK_SELECTOR = 0x0B,
|
||||||
AUDIO_CS_INTERFACE_CLOCK_MULTIPLIER = 0x0C,
|
AUDIO_CS_INTERFACE_CLOCK_MULTIPLIER = 0x0C,
|
||||||
AUDIO_CS_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D,
|
AUDIO_CS_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D,
|
||||||
} audio_cs_interface_subtype_t;
|
} audio_cs_interface_subtype_t;
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,405 +1,405 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_class
|
/** \ingroup group_class
|
||||||
* \defgroup ClassDriver_CDC Communication Device Class (CDC)
|
* \defgroup ClassDriver_CDC Communication Device Class (CDC)
|
||||||
* Currently only Abstract Control Model subclass is supported
|
* Currently only Abstract Control Model subclass is supported
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_CDC_H__
|
#ifndef _TUSB_CDC_H__
|
||||||
#define _TUSB_CDC_H__
|
#define _TUSB_CDC_H__
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \defgroup ClassDriver_CDC_Common Common Definitions
|
/** \defgroup ClassDriver_CDC_Common Common Definitions
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
// TODO remove
|
// TODO remove
|
||||||
/// CDC Pipe ID, used to indicate which pipe the API is addressing to (Notification, Out, In)
|
/// CDC Pipe ID, used to indicate which pipe the API is addressing to (Notification, Out, In)
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CDC_PIPE_NOTIFICATION , ///< Notification pipe
|
CDC_PIPE_NOTIFICATION , ///< Notification pipe
|
||||||
CDC_PIPE_DATA_IN , ///< Data in pipe
|
CDC_PIPE_DATA_IN , ///< Data in pipe
|
||||||
CDC_PIPE_DATA_OUT , ///< Data out pipe
|
CDC_PIPE_DATA_OUT , ///< Data out pipe
|
||||||
CDC_PIPE_ERROR , ///< Invalid Pipe ID
|
CDC_PIPE_ERROR , ///< Invalid Pipe ID
|
||||||
}cdc_pipeid_t;
|
}cdc_pipeid_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CDC Communication Interface Class
|
// CDC Communication Interface Class
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// Communication Interface Subclass Codes
|
/// Communication Interface Subclass Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2]
|
CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2]
|
||||||
CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL , ///< Abstract Control Model [USBPSTN1.2]
|
CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL , ///< Abstract Control Model [USBPSTN1.2]
|
||||||
CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL , ///< Telephone Control Model [USBPSTN1.2]
|
CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL , ///< Telephone Control Model [USBPSTN1.2]
|
||||||
CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL , ///< Multi-Channel Control Model [USBISDN1.2]
|
CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL , ///< Multi-Channel Control Model [USBISDN1.2]
|
||||||
CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL , ///< CAPI Control Model [USBISDN1.2]
|
CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL , ///< CAPI Control Model [USBISDN1.2]
|
||||||
CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL , ///< Ethernet Networking Control Model [USBECM1.2]
|
CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL , ///< Ethernet Networking Control Model [USBECM1.2]
|
||||||
CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL , ///< ATM Networking Control Model [USBATM1.2]
|
CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL , ///< ATM Networking Control Model [USBATM1.2]
|
||||||
CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL , ///< Wireless Handset Control Model [USBWMC1.1]
|
CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL , ///< Wireless Handset Control Model [USBWMC1.1]
|
||||||
CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT , ///< Device Management [USBWMC1.1]
|
CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT , ///< Device Management [USBWMC1.1]
|
||||||
CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL , ///< Mobile Direct Line Model [USBWMC1.1]
|
CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL , ///< Mobile Direct Line Model [USBWMC1.1]
|
||||||
CDC_COMM_SUBCLASS_OBEX , ///< OBEX [USBWMC1.1]
|
CDC_COMM_SUBCLASS_OBEX , ///< OBEX [USBWMC1.1]
|
||||||
CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model [USBEEM1.0]
|
CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model [USBEEM1.0]
|
||||||
} cdc_comm_sublcass_type_t;
|
} cdc_comm_sublcass_type_t;
|
||||||
|
|
||||||
/// Communication Interface Protocol Codes
|
/// Communication Interface Protocol Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol
|
CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol
|
||||||
CDC_COMM_PROTOCOL_ATCOMMAND , ///< AT Commands: V.250 etc
|
CDC_COMM_PROTOCOL_ATCOMMAND , ///< AT Commands: V.250 etc
|
||||||
CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 , ///< AT Commands defined by PCCA-101
|
CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 , ///< AT Commands defined by PCCA-101
|
||||||
CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO , ///< AT Commands defined by PCCA-101 & Annex O
|
CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO , ///< AT Commands defined by PCCA-101 & Annex O
|
||||||
CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 , ///< AT Commands defined by GSM 07.07
|
CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 , ///< AT Commands defined by GSM 07.07
|
||||||
CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 , ///< AT Commands defined by 3GPP 27.007
|
CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 , ///< AT Commands defined by 3GPP 27.007
|
||||||
CDC_COMM_PROTOCOL_ATCOMMAND_CDMA , ///< AT Commands defined by TIA for CDMA
|
CDC_COMM_PROTOCOL_ATCOMMAND_CDMA , ///< AT Commands defined by TIA for CDMA
|
||||||
CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model
|
CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model
|
||||||
} cdc_comm_protocol_type_t;
|
} cdc_comm_protocol_type_t;
|
||||||
|
|
||||||
//------------- SubType Descriptor in COMM Functional Descriptor -------------//
|
//------------- SubType Descriptor in COMM Functional Descriptor -------------//
|
||||||
/// Communication Interface SubType Descriptor
|
/// Communication Interface SubType Descriptor
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CDC_FUNC_DESC_HEADER = 0x00 , ///< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface.
|
CDC_FUNC_DESC_HEADER = 0x00 , ///< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface.
|
||||||
CDC_FUNC_DESC_CALL_MANAGEMENT = 0x01 , ///< Call Management Functional Descriptor.
|
CDC_FUNC_DESC_CALL_MANAGEMENT = 0x01 , ///< Call Management Functional Descriptor.
|
||||||
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT = 0x02 , ///< Abstract Control Management Functional Descriptor.
|
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT = 0x02 , ///< Abstract Control Management Functional Descriptor.
|
||||||
CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT = 0x03 , ///< Direct Line Management Functional Descriptor.
|
CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT = 0x03 , ///< Direct Line Management Functional Descriptor.
|
||||||
CDC_FUNC_DESC_TELEPHONE_RINGER = 0x04 , ///< Telephone Ringer Functional Descriptor.
|
CDC_FUNC_DESC_TELEPHONE_RINGER = 0x04 , ///< Telephone Ringer Functional Descriptor.
|
||||||
CDC_FUNC_DESC_TELEPHONE_CALL_AND_LINE_STATE_REPORTING_CAPACITY = 0x05 , ///< Telephone Call and Line State Reporting Capabilities Functional Descriptor.
|
CDC_FUNC_DESC_TELEPHONE_CALL_AND_LINE_STATE_REPORTING_CAPACITY = 0x05 , ///< Telephone Call and Line State Reporting Capabilities Functional Descriptor.
|
||||||
CDC_FUNC_DESC_UNION = 0x06 , ///< Union Functional Descriptor
|
CDC_FUNC_DESC_UNION = 0x06 , ///< Union Functional Descriptor
|
||||||
CDC_FUNC_DESC_COUNTRY_SELECTION = 0x07 , ///< Country Selection Functional Descriptor
|
CDC_FUNC_DESC_COUNTRY_SELECTION = 0x07 , ///< Country Selection Functional Descriptor
|
||||||
CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES = 0x08 , ///< Telephone Operational ModesFunctional Descriptor
|
CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES = 0x08 , ///< Telephone Operational ModesFunctional Descriptor
|
||||||
CDC_FUNC_DESC_USB_TERMINAL = 0x09 , ///< USB Terminal Functional Descriptor
|
CDC_FUNC_DESC_USB_TERMINAL = 0x09 , ///< USB Terminal Functional Descriptor
|
||||||
CDC_FUNC_DESC_NETWORK_CHANNEL_TERMINAL = 0x0A , ///< Network Channel Terminal Descriptor
|
CDC_FUNC_DESC_NETWORK_CHANNEL_TERMINAL = 0x0A , ///< Network Channel Terminal Descriptor
|
||||||
CDC_FUNC_DESC_PROTOCOL_UNIT = 0x0B , ///< Protocol Unit Functional Descriptor
|
CDC_FUNC_DESC_PROTOCOL_UNIT = 0x0B , ///< Protocol Unit Functional Descriptor
|
||||||
CDC_FUNC_DESC_EXTENSION_UNIT = 0x0C , ///< Extension Unit Functional Descriptor
|
CDC_FUNC_DESC_EXTENSION_UNIT = 0x0C , ///< Extension Unit Functional Descriptor
|
||||||
CDC_FUNC_DESC_MULTICHANEL_MANAGEMENT = 0x0D , ///< Multi-Channel Management Functional Descriptor
|
CDC_FUNC_DESC_MULTICHANEL_MANAGEMENT = 0x0D , ///< Multi-Channel Management Functional Descriptor
|
||||||
CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT = 0x0E , ///< CAPI Control Management Functional Descriptor
|
CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT = 0x0E , ///< CAPI Control Management Functional Descriptor
|
||||||
CDC_FUNC_DESC_ETHERNET_NETWORKING = 0x0F , ///< Ethernet Networking Functional Descriptor
|
CDC_FUNC_DESC_ETHERNET_NETWORKING = 0x0F , ///< Ethernet Networking Functional Descriptor
|
||||||
CDC_FUNC_DESC_ATM_NETWORKING = 0x10 , ///< ATM Networking Functional Descriptor
|
CDC_FUNC_DESC_ATM_NETWORKING = 0x10 , ///< ATM Networking Functional Descriptor
|
||||||
CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL = 0x11 , ///< Wireless Handset Control Model Functional Descriptor
|
CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL = 0x11 , ///< Wireless Handset Control Model Functional Descriptor
|
||||||
CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL = 0x12 , ///< Mobile Direct Line Model Functional Descriptor
|
CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL = 0x12 , ///< Mobile Direct Line Model Functional Descriptor
|
||||||
CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL = 0x13 , ///< MDLM Detail Functional Descriptor
|
CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL = 0x13 , ///< MDLM Detail Functional Descriptor
|
||||||
CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL = 0x14 , ///< Device Management Model Functional Descriptor
|
CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL = 0x14 , ///< Device Management Model Functional Descriptor
|
||||||
CDC_FUNC_DESC_OBEX = 0x15 , ///< OBEX Functional Descriptor
|
CDC_FUNC_DESC_OBEX = 0x15 , ///< OBEX Functional Descriptor
|
||||||
CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor
|
CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor
|
||||||
CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor
|
CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor
|
||||||
CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor
|
CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor
|
||||||
CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 ///< OBEX Service Identifier Functional Descriptor
|
CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 ///< OBEX Service Identifier Functional Descriptor
|
||||||
}cdc_func_desc_type_t;
|
}cdc_func_desc_type_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CDC Data Interface Class
|
// CDC Data Interface Class
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// SUBCLASS code of Data Interface is not used and should/must be zero
|
// SUBCLASS code of Data Interface is not used and should/must be zero
|
||||||
/// Data Interface Protocol Codes
|
/// Data Interface Protocol Codes
|
||||||
typedef enum{
|
typedef enum{
|
||||||
CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI
|
CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI
|
||||||
CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC
|
CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC
|
||||||
CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, ///< Transparent
|
CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, ///< Transparent
|
||||||
CDC_DATA_PROTOCOL_Q921_MANAGEMENT = 0x50, ///< Management protocol for Q.921 data link protocol
|
CDC_DATA_PROTOCOL_Q921_MANAGEMENT = 0x50, ///< Management protocol for Q.921 data link protocol
|
||||||
CDC_DATA_PROTOCOL_Q921_DATA_LINK = 0x51, ///< Data link protocol for Q.931
|
CDC_DATA_PROTOCOL_Q921_DATA_LINK = 0x51, ///< Data link protocol for Q.931
|
||||||
CDC_DATA_PROTOCOL_Q921_TEI_MULTIPLEXOR = 0x52, ///< TEI-multiplexor for Q.921 data link protocol
|
CDC_DATA_PROTOCOL_Q921_TEI_MULTIPLEXOR = 0x52, ///< TEI-multiplexor for Q.921 data link protocol
|
||||||
CDC_DATA_PROTOCOL_V42BIS_DATA_COMPRESSION = 0x90, ///< Data compression procedures
|
CDC_DATA_PROTOCOL_V42BIS_DATA_COMPRESSION = 0x90, ///< Data compression procedures
|
||||||
CDC_DATA_PROTOCOL_EURO_ISDN = 0x91, ///< Euro-ISDN protocol control
|
CDC_DATA_PROTOCOL_EURO_ISDN = 0x91, ///< Euro-ISDN protocol control
|
||||||
CDC_DATA_PROTOCOL_V24_RATE_ADAPTION_TO_ISDN = 0x92, ///< V.24 rate adaptation to ISDN
|
CDC_DATA_PROTOCOL_V24_RATE_ADAPTION_TO_ISDN = 0x92, ///< V.24 rate adaptation to ISDN
|
||||||
CDC_DATA_PROTOCOL_CAPI_COMMAND = 0x93, ///< CAPI Commands
|
CDC_DATA_PROTOCOL_CAPI_COMMAND = 0x93, ///< CAPI Commands
|
||||||
CDC_DATA_PROTOCOL_HOST_BASED_DRIVER = 0xFD, ///< Host based driver. Note: This protocol code should only be used in messages between host and device to identify the host driver portion of a protocol stack.
|
CDC_DATA_PROTOCOL_HOST_BASED_DRIVER = 0xFD, ///< Host based driver. Note: This protocol code should only be used in messages between host and device to identify the host driver portion of a protocol stack.
|
||||||
CDC_DATA_PROTOCOL_IN_PROTOCOL_UNIT_FUNCTIONAL_DESCRIPTOR = 0xFE ///< The protocol(s) are described using a ProtocolUnit Functional Descriptors on Communications Class Interface
|
CDC_DATA_PROTOCOL_IN_PROTOCOL_UNIT_FUNCTIONAL_DESCRIPTOR = 0xFE ///< The protocol(s) are described using a ProtocolUnit Functional Descriptors on Communications Class Interface
|
||||||
}cdc_data_protocol_type_t;
|
}cdc_data_protocol_type_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Management Element Request (Control Endpoint)
|
// Management Element Request (Control Endpoint)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// Communication Interface Management Element Request Codes
|
/// Communication Interface Management Element Request Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface
|
CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface
|
||||||
CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface.
|
CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface.
|
||||||
|
|
||||||
CDC_REQUEST_SET_COMM_FEATURE = 0x02,
|
CDC_REQUEST_SET_COMM_FEATURE = 0x02,
|
||||||
CDC_REQUEST_GET_COMM_FEATURE = 0x03,
|
CDC_REQUEST_GET_COMM_FEATURE = 0x03,
|
||||||
CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04,
|
CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04,
|
||||||
|
|
||||||
CDC_REQUEST_SET_AUX_LINE_STATE = 0x10,
|
CDC_REQUEST_SET_AUX_LINE_STATE = 0x10,
|
||||||
CDC_REQUEST_SET_HOOK_STATE = 0x11,
|
CDC_REQUEST_SET_HOOK_STATE = 0x11,
|
||||||
CDC_REQUEST_PULSE_SETUP = 0x12,
|
CDC_REQUEST_PULSE_SETUP = 0x12,
|
||||||
CDC_REQUEST_SEND_PULSE = 0x13,
|
CDC_REQUEST_SEND_PULSE = 0x13,
|
||||||
CDC_REQUEST_SET_PULSE_TIME = 0x14,
|
CDC_REQUEST_SET_PULSE_TIME = 0x14,
|
||||||
CDC_REQUEST_RING_AUX_JACK = 0x15,
|
CDC_REQUEST_RING_AUX_JACK = 0x15,
|
||||||
|
|
||||||
CDC_REQUEST_SET_LINE_CODING = 0x20,
|
CDC_REQUEST_SET_LINE_CODING = 0x20,
|
||||||
CDC_REQUEST_GET_LINE_CODING = 0x21,
|
CDC_REQUEST_GET_LINE_CODING = 0x21,
|
||||||
CDC_REQUEST_SET_CONTROL_LINE_STATE = 0x22,
|
CDC_REQUEST_SET_CONTROL_LINE_STATE = 0x22,
|
||||||
CDC_REQUEST_SEND_BREAK = 0x23,
|
CDC_REQUEST_SEND_BREAK = 0x23,
|
||||||
|
|
||||||
CDC_REQUEST_SET_RINGER_PARMS = 0x30,
|
CDC_REQUEST_SET_RINGER_PARMS = 0x30,
|
||||||
CDC_REQUEST_GET_RINGER_PARMS = 0x31,
|
CDC_REQUEST_GET_RINGER_PARMS = 0x31,
|
||||||
CDC_REQUEST_SET_OPERATION_PARMS = 0x32,
|
CDC_REQUEST_SET_OPERATION_PARMS = 0x32,
|
||||||
CDC_REQUEST_GET_OPERATION_PARMS = 0x33,
|
CDC_REQUEST_GET_OPERATION_PARMS = 0x33,
|
||||||
CDC_REQUEST_SET_LINE_PARMS = 0x34,
|
CDC_REQUEST_SET_LINE_PARMS = 0x34,
|
||||||
CDC_REQUEST_GET_LINE_PARMS = 0x35,
|
CDC_REQUEST_GET_LINE_PARMS = 0x35,
|
||||||
CDC_REQUEST_DIAL_DIGITS = 0x36,
|
CDC_REQUEST_DIAL_DIGITS = 0x36,
|
||||||
CDC_REQUEST_SET_UNIT_PARAMETER = 0x37,
|
CDC_REQUEST_SET_UNIT_PARAMETER = 0x37,
|
||||||
CDC_REQUEST_GET_UNIT_PARAMETER = 0x38,
|
CDC_REQUEST_GET_UNIT_PARAMETER = 0x38,
|
||||||
CDC_REQUEST_CLEAR_UNIT_PARAMETER = 0x39,
|
CDC_REQUEST_CLEAR_UNIT_PARAMETER = 0x39,
|
||||||
CDC_REQUEST_GET_PROFILE = 0x3A,
|
CDC_REQUEST_GET_PROFILE = 0x3A,
|
||||||
|
|
||||||
CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
|
CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
|
||||||
CDC_REQUEST_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
|
CDC_REQUEST_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
|
||||||
CDC_REQUEST_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
|
CDC_REQUEST_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
|
||||||
CDC_REQUEST_SET_ETHERNET_PACKET_FILTER = 0x43,
|
CDC_REQUEST_SET_ETHERNET_PACKET_FILTER = 0x43,
|
||||||
CDC_REQUEST_GET_ETHERNET_STATISTIC = 0x44,
|
CDC_REQUEST_GET_ETHERNET_STATISTIC = 0x44,
|
||||||
|
|
||||||
CDC_REQUEST_SET_ATM_DATA_FORMAT = 0x50,
|
CDC_REQUEST_SET_ATM_DATA_FORMAT = 0x50,
|
||||||
CDC_REQUEST_GET_ATM_DEVICE_STATISTICS = 0x51,
|
CDC_REQUEST_GET_ATM_DEVICE_STATISTICS = 0x51,
|
||||||
CDC_REQUEST_SET_ATM_DEFAULT_VC = 0x52,
|
CDC_REQUEST_SET_ATM_DEFAULT_VC = 0x52,
|
||||||
CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53,
|
CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53,
|
||||||
|
|
||||||
CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60,
|
CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60,
|
||||||
}cdc_management_request_t;
|
}cdc_management_request_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Management Elemenent Notification (Notification Endpoint)
|
// Management Elemenent Notification (Notification Endpoint)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// Communication Interface Management Element Notification Codes
|
/// Communication Interface Management Element Notification Codes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status.
|
NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status.
|
||||||
RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request.
|
RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request.
|
||||||
|
|
||||||
AUX_JACK_HOOK_STATE = 0x08,
|
AUX_JACK_HOOK_STATE = 0x08,
|
||||||
RING_DETECT = 0x09,
|
RING_DETECT = 0x09,
|
||||||
|
|
||||||
SERIAL_STATE = 0x20,
|
SERIAL_STATE = 0x20,
|
||||||
|
|
||||||
CALL_STATE_CHANGE = 0x28,
|
CALL_STATE_CHANGE = 0x28,
|
||||||
LINE_STATE_CHANGE = 0x29,
|
LINE_STATE_CHANGE = 0x29,
|
||||||
CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred
|
CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred
|
||||||
MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40,
|
MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40,
|
||||||
}cdc_notification_request_t;
|
}cdc_notification_request_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Class Specific Functional Descriptor (Communication Interface)
|
// Class Specific Functional Descriptor (Communication Interface)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// Header Functional Descriptor (Communication Interface)
|
/// Header Functional Descriptor (Communication Interface)
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_
|
||||||
uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal
|
uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal
|
||||||
}cdc_desc_func_header_t;
|
}cdc_desc_func_header_t;
|
||||||
|
|
||||||
/// Union Functional Descriptor (Communication Interface)
|
/// Union Functional Descriptor (Communication Interface)
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
uint8_t bControlInterface ; ///< Interface number of Communication Interface
|
uint8_t bControlInterface ; ///< Interface number of Communication Interface
|
||||||
uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
|
uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
|
||||||
}cdc_desc_func_union_t;
|
}cdc_desc_func_union_t;
|
||||||
|
|
||||||
#define cdc_desc_func_union_n_t(no_slave)\
|
#define cdc_desc_func_union_n_t(no_slave)\
|
||||||
struct TU_ATTR_PACKED { \
|
struct TU_ATTR_PACKED { \
|
||||||
uint8_t bLength ;\
|
uint8_t bLength ;\
|
||||||
uint8_t bDescriptorType ;\
|
uint8_t bDescriptorType ;\
|
||||||
uint8_t bDescriptorSubType ;\
|
uint8_t bDescriptorSubType ;\
|
||||||
uint8_t bControlInterface ;\
|
uint8_t bControlInterface ;\
|
||||||
uint8_t bSubordinateInterface[no_slave] ;\
|
uint8_t bSubordinateInterface[no_slave] ;\
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Country Selection Functional Descriptor (Communication Interface)
|
/// Country Selection Functional Descriptor (Communication Interface)
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
|
uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
|
||||||
uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country.
|
uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country.
|
||||||
}cdc_desc_func_country_selection_t;
|
}cdc_desc_func_country_selection_t;
|
||||||
|
|
||||||
#define cdc_desc_func_country_selection_n_t(no_country) \
|
#define cdc_desc_func_country_selection_n_t(no_country) \
|
||||||
struct TU_ATTR_PACKED {\
|
struct TU_ATTR_PACKED {\
|
||||||
uint8_t bLength ;\
|
uint8_t bLength ;\
|
||||||
uint8_t bDescriptorType ;\
|
uint8_t bDescriptorType ;\
|
||||||
uint8_t bDescriptorSubType ;\
|
uint8_t bDescriptorSubType ;\
|
||||||
uint8_t iCountryCodeRelDate ;\
|
uint8_t iCountryCodeRelDate ;\
|
||||||
uint16_t wCountryCode[no_country] ;\
|
uint16_t wCountryCode[no_country] ;\
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS
|
// PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// \brief Call Management Functional Descriptor
|
/// \brief Call Management Functional Descriptor
|
||||||
/// \details This functional descriptor describes the processing of calls for the Communications Class interface.
|
/// \details This functional descriptor describes the processing of calls for the Communications Class interface.
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface.
|
uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface.
|
||||||
uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself.
|
uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself.
|
||||||
uint8_t : 0;
|
uint8_t : 0;
|
||||||
} bmCapabilities;
|
} bmCapabilities;
|
||||||
|
|
||||||
uint8_t bDataInterface;
|
uint8_t bDataInterface;
|
||||||
}cdc_desc_func_call_management_t;
|
}cdc_desc_func_call_management_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
|
uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
|
||||||
uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.
|
uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.
|
||||||
uint8_t support_send_break : 1; ///< Device supports the request Send_Break
|
uint8_t support_send_break : 1; ///< Device supports the request Send_Break
|
||||||
uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection.
|
uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection.
|
||||||
uint8_t : 0;
|
uint8_t : 0;
|
||||||
}cdc_acm_capability_t;
|
}cdc_acm_capability_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler");
|
TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler");
|
||||||
|
|
||||||
/// \brief Abstract Control Management Functional Descriptor
|
/// \brief Abstract Control Management Functional Descriptor
|
||||||
/// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
|
/// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
cdc_acm_capability_t bmCapabilities ;
|
cdc_acm_capability_t bmCapabilities ;
|
||||||
}cdc_desc_func_acm_t;
|
}cdc_desc_func_acm_t;
|
||||||
|
|
||||||
/// \brief Direct Line Management Functional Descriptor
|
/// \brief Direct Line Management Functional Descriptor
|
||||||
/// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT
|
/// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
struct {
|
struct {
|
||||||
uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit.
|
uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit.
|
||||||
uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State.
|
uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State.
|
||||||
uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time.
|
uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time.
|
||||||
uint8_t : 0;
|
uint8_t : 0;
|
||||||
} bmCapabilities;
|
} bmCapabilities;
|
||||||
}cdc_desc_func_direct_line_management_t;
|
}cdc_desc_func_direct_line_management_t;
|
||||||
|
|
||||||
/// \brief Telephone Ringer Functional Descriptor
|
/// \brief Telephone Ringer Functional Descriptor
|
||||||
/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface,
|
/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface,
|
||||||
/// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
|
/// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
uint8_t bRingerVolSteps ;
|
uint8_t bRingerVolSteps ;
|
||||||
uint8_t bNumRingerPatterns ;
|
uint8_t bNumRingerPatterns ;
|
||||||
}cdc_desc_func_telephone_ringer_t;
|
}cdc_desc_func_telephone_ringer_t;
|
||||||
|
|
||||||
/// \brief Telephone Operational Modes Functional Descriptor
|
/// \brief Telephone Operational Modes Functional Descriptor
|
||||||
/// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by
|
/// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by
|
||||||
/// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
|
/// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
struct {
|
struct {
|
||||||
uint8_t simple_mode : 1;
|
uint8_t simple_mode : 1;
|
||||||
uint8_t standalone_mode : 1;
|
uint8_t standalone_mode : 1;
|
||||||
uint8_t computer_centric_mode : 1;
|
uint8_t computer_centric_mode : 1;
|
||||||
uint8_t : 0;
|
uint8_t : 0;
|
||||||
} bmCapabilities;
|
} bmCapabilities;
|
||||||
}cdc_desc_func_telephone_operational_modes_t;
|
}cdc_desc_func_telephone_operational_modes_t;
|
||||||
|
|
||||||
/// \brief Telephone Call and Line State Reporting Capabilities Descriptor
|
/// \brief Telephone Call and Line State Reporting Capabilities Descriptor
|
||||||
/// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a
|
/// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a
|
||||||
/// telephone device to report optional call and line states.
|
/// telephone device to report optional call and line states.
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
|
||||||
struct {
|
struct {
|
||||||
uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone
|
uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone
|
||||||
uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states.
|
uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states.
|
||||||
uint32_t caller_id : 1; ///< 0 : Does not report caller ID. 1 : Reports caller ID information.
|
uint32_t caller_id : 1; ///< 0 : Does not report caller ID. 1 : Reports caller ID information.
|
||||||
uint32_t incoming_distinctive : 1; ///< 0 : Reports only incoming ringing. 1 : Reports incoming distinctive ringing patterns.
|
uint32_t incoming_distinctive : 1; ///< 0 : Reports only incoming ringing. 1 : Reports incoming distinctive ringing patterns.
|
||||||
uint32_t dual_tone_multi_freq : 1; ///< 0 : Cannot report dual tone multi-frequency (DTMF) digits input remotely over the telephone line. 1 : Can report DTMF digits input remotely over the telephone line.
|
uint32_t dual_tone_multi_freq : 1; ///< 0 : Cannot report dual tone multi-frequency (DTMF) digits input remotely over the telephone line. 1 : Can report DTMF digits input remotely over the telephone line.
|
||||||
uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification
|
uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification
|
||||||
uint32_t : 0;
|
uint32_t : 0;
|
||||||
} bmCapabilities;
|
} bmCapabilities;
|
||||||
}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
|
}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
|
||||||
|
|
||||||
static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
|
static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
|
||||||
{
|
{
|
||||||
return p_desc[2];
|
return p_desc[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Requests
|
// Requests
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint32_t bit_rate;
|
uint32_t bit_rate;
|
||||||
uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits
|
uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits
|
||||||
uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
|
uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
|
||||||
uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
|
uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
|
||||||
} cdc_line_coding_t;
|
} cdc_line_coding_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct");
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR.
|
uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR.
|
||||||
uint16_t half_duplex_carrier_control : 1;
|
uint16_t half_duplex_carrier_control : 1;
|
||||||
uint16_t : 14;
|
uint16_t : 14;
|
||||||
} cdc_line_control_state_t;
|
} cdc_line_control_state_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,394 +1,415 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_CDC)
|
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_CDC)
|
||||||
|
|
||||||
#include "cdc_device.h"
|
#include "cdc_device.h"
|
||||||
#include "device/usbd_pvt.h"
|
#include "device/usbd_pvt.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t itf_num;
|
uint8_t itf_num;
|
||||||
uint8_t ep_notif;
|
uint8_t ep_notif;
|
||||||
uint8_t ep_in;
|
uint8_t ep_in;
|
||||||
uint8_t ep_out;
|
uint8_t ep_out;
|
||||||
|
|
||||||
// Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
|
// Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
|
||||||
uint8_t line_state;
|
uint8_t line_state;
|
||||||
|
|
||||||
/*------------- From this point, data is not cleared by bus reset -------------*/
|
/*------------- From this point, data is not cleared by bus reset -------------*/
|
||||||
char wanted_char;
|
char wanted_char;
|
||||||
cdc_line_coding_t line_coding;
|
cdc_line_coding_t line_coding;
|
||||||
|
|
||||||
// FIFO
|
// FIFO
|
||||||
tu_fifo_t rx_ff;
|
tu_fifo_t rx_ff;
|
||||||
tu_fifo_t tx_ff;
|
tu_fifo_t tx_ff;
|
||||||
|
|
||||||
uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||||
uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
osal_mutex_def_t rx_ff_mutex;
|
osal_mutex_def_t rx_ff_mutex;
|
||||||
osal_mutex_def_t tx_ff_mutex;
|
osal_mutex_def_t tx_ff_mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Endpoint Transfer buffer
|
// Endpoint Transfer buffer
|
||||||
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EPSIZE];
|
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EPSIZE];
|
||||||
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EPSIZE];
|
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EPSIZE];
|
||||||
|
|
||||||
}cdcd_interface_t;
|
}cdcd_interface_t;
|
||||||
|
|
||||||
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)
|
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
|
CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
|
||||||
|
|
||||||
static void _prep_out_transaction (uint8_t itf)
|
static void _prep_out_transaction (uint8_t itf)
|
||||||
{
|
{
|
||||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
||||||
|
|
||||||
// skip if previous transfer not complete
|
// skip if previous transfer not complete
|
||||||
if ( usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_out) ) return;
|
if ( usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_out) ) return;
|
||||||
|
|
||||||
// Prepare for incoming data but only allow what we can store in the ring buffer.
|
// Prepare for incoming data but only allow what we can store in the ring buffer.
|
||||||
uint16_t max_read = tu_fifo_remaining(&p_cdc->rx_ff);
|
uint16_t max_read = tu_fifo_remaining(&p_cdc->rx_ff);
|
||||||
if ( max_read >= CFG_TUD_CDC_EPSIZE )
|
if ( max_read >= CFG_TUD_CDC_EPSIZE )
|
||||||
{
|
{
|
||||||
usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE);
|
usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// APPLICATION API
|
// APPLICATION API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool tud_cdc_n_connected(uint8_t itf)
|
bool tud_cdc_n_connected(uint8_t itf)
|
||||||
{
|
{
|
||||||
// DTR (bit 0) active is considered as connected
|
// DTR (bit 0) active is considered as connected
|
||||||
return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0);
|
return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tud_cdc_n_get_line_state (uint8_t itf)
|
uint8_t tud_cdc_n_get_line_state (uint8_t itf)
|
||||||
{
|
{
|
||||||
return _cdcd_itf[itf].line_state;
|
return _cdcd_itf[itf].line_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding)
|
void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding)
|
||||||
{
|
{
|
||||||
(*coding) = _cdcd_itf[itf].line_coding;
|
(*coding) = _cdcd_itf[itf].line_coding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted)
|
void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted)
|
||||||
{
|
{
|
||||||
_cdcd_itf[itf].wanted_char = wanted;
|
_cdcd_itf[itf].wanted_char = wanted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// READ API
|
// READ API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
uint32_t tud_cdc_n_available(uint8_t itf)
|
uint32_t tud_cdc_n_available(uint8_t itf)
|
||||||
{
|
{
|
||||||
return tu_fifo_count(&_cdcd_itf[itf].rx_ff);
|
return tu_fifo_count(&_cdcd_itf[itf].rx_ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize)
|
uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
uint32_t num_read = tu_fifo_read_n(&_cdcd_itf[itf].rx_ff, buffer, bufsize);
|
uint32_t num_read = tu_fifo_read_n(&_cdcd_itf[itf].rx_ff, buffer, bufsize);
|
||||||
_prep_out_transaction(itf);
|
_prep_out_transaction(itf);
|
||||||
return num_read;
|
return num_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_cdc_n_peek(uint8_t itf, int pos, uint8_t* chr)
|
bool tud_cdc_n_peek(uint8_t itf, int pos, uint8_t* chr)
|
||||||
{
|
{
|
||||||
return tu_fifo_peek_at(&_cdcd_itf[itf].rx_ff, pos, chr);
|
return tu_fifo_peek_at(&_cdcd_itf[itf].rx_ff, pos, chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_cdc_n_read_flush (uint8_t itf)
|
void tud_cdc_n_read_flush (uint8_t itf)
|
||||||
{
|
{
|
||||||
tu_fifo_clear(&_cdcd_itf[itf].rx_ff);
|
tu_fifo_clear(&_cdcd_itf[itf].rx_ff);
|
||||||
_prep_out_transaction(itf);
|
_prep_out_transaction(itf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// WRITE API
|
// WRITE API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize)
|
uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
uint16_t ret = tu_fifo_write_n(&_cdcd_itf[itf].tx_ff, buffer, bufsize);
|
uint16_t ret = tu_fifo_write_n(&_cdcd_itf[itf].tx_ff, buffer, bufsize);
|
||||||
|
|
||||||
#if 0 // TODO issue with circuitpython's REPL
|
#if 0 // TODO issue with circuitpython's REPL
|
||||||
// flush if queue more than endpoint size
|
// flush if queue more than endpoint size
|
||||||
if ( tu_fifo_count(&_cdcd_itf[itf].tx_ff) >= CFG_TUD_CDC_EPSIZE )
|
if ( tu_fifo_count(&_cdcd_itf[itf].tx_ff) >= CFG_TUD_CDC_EPSIZE )
|
||||||
{
|
{
|
||||||
tud_cdc_n_write_flush(itf);
|
tud_cdc_n_write_flush(itf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_cdc_n_write_flush (uint8_t itf)
|
bool tud_cdc_n_write_flush (uint8_t itf)
|
||||||
{
|
{
|
||||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
||||||
TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in) ); // skip if previous transfer not complete
|
TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in) ); // skip if previous transfer not complete
|
||||||
|
|
||||||
uint16_t count = tu_fifo_read_n(&_cdcd_itf[itf].tx_ff, p_cdc->epin_buf, CFG_TUD_CDC_EPSIZE);
|
uint16_t count = tu_fifo_read_n(&_cdcd_itf[itf].tx_ff, p_cdc->epin_buf, CFG_TUD_CDC_EPSIZE);
|
||||||
if ( count )
|
if ( count )
|
||||||
{
|
{
|
||||||
TU_VERIFY( tud_cdc_n_connected(itf) ); // fifo is empty if not connected
|
TU_VERIFY( tud_cdc_n_connected(itf) ); // fifo is empty if not connected
|
||||||
TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_in, p_cdc->epin_buf, count) );
|
TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_in, p_cdc->epin_buf, count) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tud_cdc_n_write_available (uint8_t itf)
|
uint32_t tud_cdc_n_write_available (uint8_t itf)
|
||||||
{
|
{
|
||||||
return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff);
|
return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBD Driver API
|
// USBD Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void cdcd_init(void)
|
void cdcd_init(void)
|
||||||
{
|
{
|
||||||
tu_memclr(_cdcd_itf, sizeof(_cdcd_itf));
|
tu_memclr(_cdcd_itf, sizeof(_cdcd_itf));
|
||||||
|
|
||||||
for(uint8_t i=0; i<CFG_TUD_CDC; i++)
|
for(uint8_t i=0; i<CFG_TUD_CDC; i++)
|
||||||
{
|
{
|
||||||
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
|
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
|
||||||
|
|
||||||
p_cdc->wanted_char = -1;
|
p_cdc->wanted_char = -1;
|
||||||
|
|
||||||
// default line coding is : stop bit = 1, parity = none, data bits = 8
|
// default line coding is : stop bit = 1, parity = none, data bits = 8
|
||||||
p_cdc->line_coding.bit_rate = 115200;
|
p_cdc->line_coding.bit_rate = 115200;
|
||||||
p_cdc->line_coding.stop_bits = 0;
|
p_cdc->line_coding.stop_bits = 0;
|
||||||
p_cdc->line_coding.parity = 0;
|
p_cdc->line_coding.parity = 0;
|
||||||
p_cdc->line_coding.data_bits = 8;
|
p_cdc->line_coding.data_bits = 8;
|
||||||
|
|
||||||
// config fifo
|
// config fifo
|
||||||
tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, 1, false);
|
tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, 1, false);
|
||||||
tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, 1, false);
|
tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, 1, false);
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
tu_fifo_config_mutex(&p_cdc->rx_ff, osal_mutex_create(&p_cdc->rx_ff_mutex));
|
tu_fifo_config_mutex(&p_cdc->rx_ff, osal_mutex_create(&p_cdc->rx_ff_mutex));
|
||||||
tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex));
|
tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdcd_reset(uint8_t rhport)
|
void cdcd_reset(uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
for(uint8_t i=0; i<CFG_TUD_CDC; i++)
|
for(uint8_t i=0; i<CFG_TUD_CDC; i++)
|
||||||
{
|
{
|
||||||
tu_memclr(&_cdcd_itf[i], ITF_MEM_RESET_SIZE);
|
tu_memclr(&_cdcd_itf[i], ITF_MEM_RESET_SIZE);
|
||||||
tu_fifo_clear(&_cdcd_itf[i].rx_ff);
|
tu_fifo_clear(&_cdcd_itf[i].rx_ff);
|
||||||
tu_fifo_clear(&_cdcd_itf[i].tx_ff);
|
tu_fifo_clear(&_cdcd_itf[i].tx_ff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
|
bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
// Only support ACM subclass
|
// Only support ACM subclass
|
||||||
TU_ASSERT ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
|
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.
|
||||||
TU_ASSERT(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
|
TU_ASSERT(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
|
||||||
itf_desc->bInterfaceProtocol == 0xff);
|
itf_desc->bInterfaceProtocol == 0xff);
|
||||||
|
|
||||||
// Find available interface
|
// Find available interface
|
||||||
cdcd_interface_t * p_cdc = NULL;
|
cdcd_interface_t * p_cdc = NULL;
|
||||||
uint8_t cdc_id;
|
uint8_t cdc_id;
|
||||||
for(cdc_id=0; cdc_id<CFG_TUD_CDC; cdc_id++)
|
for(cdc_id=0; cdc_id<CFG_TUD_CDC; cdc_id++)
|
||||||
{
|
{
|
||||||
if ( _cdcd_itf[cdc_id].ep_in == 0 )
|
if ( _cdcd_itf[cdc_id].ep_in == 0 )
|
||||||
{
|
{
|
||||||
p_cdc = &_cdcd_itf[cdc_id];
|
p_cdc = &_cdcd_itf[cdc_id];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TU_ASSERT(p_cdc);
|
TU_ASSERT(p_cdc);
|
||||||
|
|
||||||
//------------- Control Interface -------------//
|
//------------- Control Interface -------------//
|
||||||
p_cdc->itf_num = itf_desc->bInterfaceNumber;
|
p_cdc->itf_num = itf_desc->bInterfaceNumber;
|
||||||
|
|
||||||
uint8_t const * p_desc = tu_desc_next( itf_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_CS_INTERFACE == tu_desc_type(p_desc) )
|
while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
(*p_length) += tu_desc_len(p_desc);
|
(*p_length) += tu_desc_len(p_desc);
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
|
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
|
||||||
{
|
{
|
||||||
// notification endpoint if any
|
// notification endpoint if any
|
||||||
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc) );
|
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 = tu_desc_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 descriptor
|
// next to endpoint descriptor
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
|
|
||||||
// Open endpoint pair
|
// Open endpoint pair
|
||||||
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
|
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
|
||||||
|
|
||||||
(*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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for incoming data
|
// Prepare for incoming data
|
||||||
_prep_out_transaction(cdc_id);
|
_prep_out_transaction(cdc_id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when class request DATA stage is finished.
|
// Invoked when class request DATA stage is finished.
|
||||||
// return false to stall control endpoint (e.g Host send non-sense DATA)
|
// return false to stall control endpoint (e.g Host send non-sense DATA)
|
||||||
bool cdcd_control_complete(uint8_t rhport, tusb_control_request_t const * request)
|
bool cdcd_control_complete(uint8_t rhport, tusb_control_request_t const * request)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
//------------- Class Specific Request -------------//
|
//------------- Class Specific Request -------------//
|
||||||
TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
|
TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
|
||||||
|
|
||||||
// TODO Support multiple interfaces
|
uint8_t itf = 0;
|
||||||
uint8_t const itf = 0;
|
cdcd_interface_t* p_cdc = _cdcd_itf;
|
||||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
|
||||||
|
// Identify which interface to use
|
||||||
// Invoke callback
|
for ( ; ; itf++, p_cdc++)
|
||||||
if ( CDC_REQUEST_SET_LINE_CODING == request->bRequest )
|
{
|
||||||
{
|
if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false;
|
||||||
if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding);
|
|
||||||
}
|
if ( p_cdc->itf_num == request->wIndex ) break;
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
// Invoke callback
|
||||||
|
if ( CDC_REQUEST_SET_LINE_CODING == request->bRequest )
|
||||||
// Handle class control request
|
{
|
||||||
// return false to stall control endpoint (e.g unsupported request)
|
if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding);
|
||||||
bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request)
|
}
|
||||||
{
|
|
||||||
// Handle class request only
|
return true;
|
||||||
TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
|
}
|
||||||
|
|
||||||
// TODO Support multiple interfaces
|
// Handle class control request
|
||||||
uint8_t const itf = 0;
|
// return false to stall control endpoint (e.g unsupported request)
|
||||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request)
|
||||||
|
{
|
||||||
switch ( request->bRequest )
|
// Handle class request only
|
||||||
{
|
TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
|
||||||
case CDC_REQUEST_SET_LINE_CODING:
|
|
||||||
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
|
uint8_t itf = 0;
|
||||||
break;
|
cdcd_interface_t* p_cdc = _cdcd_itf;
|
||||||
|
|
||||||
case CDC_REQUEST_GET_LINE_CODING:
|
// Identify which interface to use
|
||||||
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
|
for ( ; ; itf++, p_cdc++)
|
||||||
break;
|
{
|
||||||
|
if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false;
|
||||||
case CDC_REQUEST_SET_CONTROL_LINE_STATE:
|
|
||||||
// CDC PSTN v1.2 section 6.3.12
|
if ( p_cdc->itf_num == request->wIndex ) break;
|
||||||
// Bit 0: Indicates if DTE is present or not.
|
}
|
||||||
// This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready)
|
|
||||||
// Bit 1: Carrier control for half-duplex modems.
|
switch ( request->bRequest )
|
||||||
// This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
|
{
|
||||||
p_cdc->line_state = (uint8_t) request->wValue;
|
case CDC_REQUEST_SET_LINE_CODING:
|
||||||
|
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
|
||||||
tud_control_status(rhport, request);
|
break;
|
||||||
|
|
||||||
// Invoke callback
|
case CDC_REQUEST_GET_LINE_CODING:
|
||||||
if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, tu_bit_test(request->wValue, 0), tu_bit_test(request->wValue, 1));
|
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: return false; // stall unsupported request
|
case CDC_REQUEST_SET_CONTROL_LINE_STATE:
|
||||||
}
|
// CDC PSTN v1.2 section 6.3.12
|
||||||
|
// Bit 0: Indicates if DTE is present or not.
|
||||||
return true;
|
// This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready)
|
||||||
}
|
// Bit 1: Carrier control for half-duplex modems.
|
||||||
|
// This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
|
||||||
bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
p_cdc->line_state = (uint8_t) request->wValue;
|
||||||
{
|
|
||||||
(void) rhport;
|
tud_control_status(rhport, request);
|
||||||
(void) result;
|
|
||||||
|
// Invoke callback
|
||||||
// TODO Support multiple interfaces
|
if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, tu_bit_test(request->wValue, 0), tu_bit_test(request->wValue, 1));
|
||||||
uint8_t const itf = 0;
|
break;
|
||||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
|
||||||
|
default: return false; // stall unsupported request
|
||||||
// Received new data
|
}
|
||||||
if ( ep_addr == p_cdc->ep_out )
|
|
||||||
{
|
return true;
|
||||||
for(uint32_t i=0; i<xferred_bytes; i++)
|
}
|
||||||
{
|
|
||||||
tu_fifo_write(&p_cdc->rx_ff, &p_cdc->epout_buf[i]);
|
bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||||
|
{
|
||||||
// Check for wanted char and invoke callback if needed
|
(void) rhport;
|
||||||
if ( tud_cdc_rx_wanted_cb && ( ((signed char) p_cdc->wanted_char) != -1 ) && ( p_cdc->wanted_char == p_cdc->epout_buf[i] ) )
|
(void) result;
|
||||||
{
|
|
||||||
tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char);
|
uint8_t itf = 0;
|
||||||
}
|
cdcd_interface_t* p_cdc = _cdcd_itf;
|
||||||
}
|
|
||||||
|
// Identify which interface to use
|
||||||
// invoke receive callback (if there is still data)
|
for ( ; ; itf++, p_cdc++)
|
||||||
if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
|
{
|
||||||
|
if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false;
|
||||||
// prepare for OUT transaction
|
|
||||||
_prep_out_transaction(itf);
|
if ( ( ep_addr == p_cdc->ep_out ) || ( ep_addr == p_cdc->ep_in ) ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data sent to host, we could continue to fetch data tx fifo to send.
|
// Received new data
|
||||||
// But it will cause incorrect baudrate set in line coding.
|
if ( ep_addr == p_cdc->ep_out )
|
||||||
// Though maybe the baudrate is not really important !!!
|
{
|
||||||
// if ( ep_addr == p_cdc->ep_in )
|
for(uint32_t i=0; i<xferred_bytes; i++)
|
||||||
// {
|
{
|
||||||
//
|
tu_fifo_write(&p_cdc->rx_ff, &p_cdc->epout_buf[i]);
|
||||||
// }
|
|
||||||
|
// Check for wanted char and invoke callback if needed
|
||||||
// nothing to do with notif endpoint for now
|
if ( tud_cdc_rx_wanted_cb && ( ((signed char) p_cdc->wanted_char) != -1 ) && ( p_cdc->wanted_char == p_cdc->epout_buf[i] ) )
|
||||||
|
{
|
||||||
return true;
|
tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// prepare for OUT transaction
|
||||||
|
_prep_out_transaction(itf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data sent to host, we could continue to fetch data tx fifo to send.
|
||||||
|
// But it will cause incorrect baudrate set in line coding.
|
||||||
|
// Though maybe the baudrate is not really important !!!
|
||||||
|
// if ( ep_addr == p_cdc->ep_in )
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
// nothing to do with notif endpoint for now
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,213 +1,213 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_CDC_DEVICE_H_
|
#ifndef _TUSB_CDC_DEVICE_H_
|
||||||
#define _TUSB_CDC_DEVICE_H_
|
#define _TUSB_CDC_DEVICE_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "device/usbd.h"
|
#include "device/usbd.h"
|
||||||
#include "cdc.h"
|
#include "cdc.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Class Driver Configuration
|
// Class Driver Configuration
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#ifndef CFG_TUD_CDC_EPSIZE
|
#ifndef CFG_TUD_CDC_EPSIZE
|
||||||
#define CFG_TUD_CDC_EPSIZE 64
|
#define CFG_TUD_CDC_EPSIZE 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \addtogroup CDC_Serial Serial
|
/** \addtogroup CDC_Serial Serial
|
||||||
* @{
|
* @{
|
||||||
* \defgroup CDC_Serial_Device Device
|
* \defgroup CDC_Serial_Device Device
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API (Multiple Interfaces)
|
// Application API (Multiple Interfaces)
|
||||||
// CFG_TUD_CDC > 1
|
// CFG_TUD_CDC > 1
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool tud_cdc_n_connected (uint8_t itf);
|
bool tud_cdc_n_connected (uint8_t itf);
|
||||||
uint8_t tud_cdc_n_get_line_state (uint8_t itf);
|
uint8_t tud_cdc_n_get_line_state (uint8_t itf);
|
||||||
void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding);
|
void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding);
|
||||||
void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted);
|
void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted);
|
||||||
|
|
||||||
uint32_t tud_cdc_n_available (uint8_t itf);
|
uint32_t tud_cdc_n_available (uint8_t itf);
|
||||||
uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize);
|
uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize);
|
||||||
void tud_cdc_n_read_flush (uint8_t itf);
|
void tud_cdc_n_read_flush (uint8_t itf);
|
||||||
bool tud_cdc_n_peek (uint8_t itf, int pos, uint8_t* u8);
|
bool tud_cdc_n_peek (uint8_t itf, int pos, uint8_t* u8);
|
||||||
static inline int32_t tud_cdc_n_read_char (uint8_t itf);
|
static inline int32_t tud_cdc_n_read_char (uint8_t itf);
|
||||||
|
|
||||||
uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
|
uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
|
||||||
bool tud_cdc_n_write_flush (uint8_t itf);
|
bool tud_cdc_n_write_flush (uint8_t itf);
|
||||||
uint32_t tud_cdc_n_write_available (uint8_t itf);
|
uint32_t tud_cdc_n_write_available (uint8_t itf);
|
||||||
static inline uint32_t tud_cdc_n_write_char (uint8_t itf, char ch);
|
static inline uint32_t tud_cdc_n_write_char (uint8_t itf, char ch);
|
||||||
static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str);
|
static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API (Interface0)
|
// Application API (Interface0)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline bool tud_cdc_connected (void);
|
static inline bool tud_cdc_connected (void);
|
||||||
static inline uint8_t tud_cdc_get_line_state (void);
|
static inline uint8_t tud_cdc_get_line_state (void);
|
||||||
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding);
|
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding);
|
||||||
static inline void tud_cdc_set_wanted_char (char wanted);
|
static inline void tud_cdc_set_wanted_char (char wanted);
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_available (void);
|
static inline uint32_t tud_cdc_available (void);
|
||||||
static inline int32_t tud_cdc_read_char (void);
|
static inline int32_t tud_cdc_read_char (void);
|
||||||
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize);
|
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize);
|
||||||
static inline void tud_cdc_read_flush (void);
|
static inline void tud_cdc_read_flush (void);
|
||||||
static inline bool tud_cdc_peek (int pos, uint8_t* u8);
|
static inline bool tud_cdc_peek (int pos, uint8_t* u8);
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_write_char (char ch);
|
static inline uint32_t tud_cdc_write_char (char ch);
|
||||||
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize);
|
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize);
|
||||||
static inline uint32_t tud_cdc_write_str (char const* str);
|
static inline uint32_t tud_cdc_write_str (char const* str);
|
||||||
static inline bool tud_cdc_write_flush (void);
|
static inline bool tud_cdc_write_flush (void);
|
||||||
static inline uint32_t tud_cdc_write_available (void);
|
static inline uint32_t tud_cdc_write_available (void);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application Callback API (weak is optional)
|
// Application Callback API (weak is optional)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when received new data
|
// Invoked when received new data
|
||||||
TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf);
|
TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf);
|
||||||
|
|
||||||
// Invoked when received `wanted_char`
|
// Invoked when received `wanted_char`
|
||||||
TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char);
|
TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char);
|
||||||
|
|
||||||
// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE
|
// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE
|
||||||
TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
|
TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
|
||||||
|
|
||||||
// Invoked when line coding is change via SET_LINE_CODING
|
// Invoked when line coding is change via SET_LINE_CODING
|
||||||
TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding);
|
TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Inline Functions
|
// Inline Functions
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline int32_t tud_cdc_n_read_char (uint8_t itf)
|
static inline int32_t tud_cdc_n_read_char (uint8_t itf)
|
||||||
{
|
{
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1;
|
return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch)
|
static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write(itf, &ch, 1);
|
return tud_cdc_n_write(itf, &ch, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str)
|
static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write(itf, str, strlen(str));
|
return tud_cdc_n_write(itf, str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tud_cdc_connected (void)
|
static inline bool tud_cdc_connected (void)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_connected(0);
|
return tud_cdc_n_connected(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t tud_cdc_get_line_state (void)
|
static inline uint8_t tud_cdc_get_line_state (void)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_get_line_state(0);
|
return tud_cdc_n_get_line_state(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding)
|
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding)
|
||||||
{
|
{
|
||||||
tud_cdc_n_get_line_coding(0, coding);
|
tud_cdc_n_get_line_coding(0, coding);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tud_cdc_set_wanted_char (char wanted)
|
static inline void tud_cdc_set_wanted_char (char wanted)
|
||||||
{
|
{
|
||||||
tud_cdc_n_set_wanted_char(0, wanted);
|
tud_cdc_n_set_wanted_char(0, wanted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_available (void)
|
static inline uint32_t tud_cdc_available (void)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_available(0);
|
return tud_cdc_n_available(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t tud_cdc_read_char (void)
|
static inline int32_t tud_cdc_read_char (void)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_read_char(0);
|
return tud_cdc_n_read_char(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize)
|
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_read(0, buffer, bufsize);
|
return tud_cdc_n_read(0, buffer, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tud_cdc_read_flush (void)
|
static inline void tud_cdc_read_flush (void)
|
||||||
{
|
{
|
||||||
tud_cdc_n_read_flush(0);
|
tud_cdc_n_read_flush(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tud_cdc_peek (int pos, uint8_t* u8)
|
static inline bool tud_cdc_peek (int pos, uint8_t* u8)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_peek(0, pos, u8);
|
return tud_cdc_n_peek(0, pos, u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_write_char (char ch)
|
static inline uint32_t tud_cdc_write_char (char ch)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write_char(0, ch);
|
return tud_cdc_n_write_char(0, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize)
|
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write(0, buffer, bufsize);
|
return tud_cdc_n_write(0, buffer, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_write_str (char const* str)
|
static inline uint32_t tud_cdc_write_str (char const* str)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write_str(0, str);
|
return tud_cdc_n_write_str(0, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tud_cdc_write_flush (void)
|
static inline bool tud_cdc_write_flush (void)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write_flush(0);
|
return tud_cdc_n_write_flush(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_cdc_write_available(void)
|
static inline uint32_t tud_cdc_write_available(void)
|
||||||
{
|
{
|
||||||
return tud_cdc_n_write_available(0);
|
return tud_cdc_n_write_available(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL USBD-CLASS DRIVER API
|
// INTERNAL USBD-CLASS DRIVER API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void cdcd_init (void);
|
void cdcd_init (void);
|
||||||
void cdcd_reset (uint8_t rhport);
|
void cdcd_reset (uint8_t rhport);
|
||||||
bool cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
bool cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||||
bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool cdcd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
bool cdcd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool 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);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_CDC_DEVICE_H_ */
|
#endif /* _TUSB_CDC_DEVICE_H_ */
|
||||||
|
@ -1,225 +1,225 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC)
|
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC)
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "cdc_host.h"
|
#include "cdc_host.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t itf_num;
|
uint8_t itf_num;
|
||||||
uint8_t itf_protocol;
|
uint8_t itf_protocol;
|
||||||
|
|
||||||
uint8_t ep_notif;
|
uint8_t ep_notif;
|
||||||
uint8_t ep_in;
|
uint8_t ep_in;
|
||||||
uint8_t ep_out;
|
uint8_t ep_out;
|
||||||
|
|
||||||
cdc_acm_capability_t acm_capability;
|
cdc_acm_capability_t acm_capability;
|
||||||
|
|
||||||
} cdch_data_t;
|
} cdch_data_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
static cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||||
|
|
||||||
bool tuh_cdc_mounted(uint8_t dev_addr)
|
bool tuh_cdc_mounted(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
cdch_data_t* cdc = &cdch_data[dev_addr-1];
|
cdch_data_t* cdc = &cdch_data[dev_addr-1];
|
||||||
return cdc->ep_in && cdc->ep_out;
|
return cdc->ep_in && cdc->ep_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid)
|
bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid)
|
||||||
{
|
{
|
||||||
if ( !tuh_cdc_mounted(dev_addr) ) return false;
|
if ( !tuh_cdc_mounted(dev_addr) ) return false;
|
||||||
|
|
||||||
cdch_data_t const * p_cdc = &cdch_data[dev_addr-1];
|
cdch_data_t const * p_cdc = &cdch_data[dev_addr-1];
|
||||||
|
|
||||||
switch (pipeid)
|
switch (pipeid)
|
||||||
{
|
{
|
||||||
case CDC_PIPE_NOTIFICATION:
|
case CDC_PIPE_NOTIFICATION:
|
||||||
return hcd_edpt_busy(dev_addr, p_cdc->ep_notif );
|
return hcd_edpt_busy(dev_addr, p_cdc->ep_notif );
|
||||||
|
|
||||||
case CDC_PIPE_DATA_IN:
|
case CDC_PIPE_DATA_IN:
|
||||||
return hcd_edpt_busy(dev_addr, p_cdc->ep_in );
|
return hcd_edpt_busy(dev_addr, p_cdc->ep_in );
|
||||||
|
|
||||||
case CDC_PIPE_DATA_OUT:
|
case CDC_PIPE_DATA_OUT:
|
||||||
return hcd_edpt_busy(dev_addr, p_cdc->ep_out );
|
return hcd_edpt_busy(dev_addr, p_cdc->ep_out );
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// APPLICATION API (parameter validation needed)
|
// APPLICATION API (parameter validation needed)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool tuh_cdc_serial_is_mounted(uint8_t dev_addr)
|
bool tuh_cdc_serial_is_mounted(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
// TODO consider all AT Command as serial candidate
|
// TODO consider all AT Command as serial candidate
|
||||||
return tuh_cdc_mounted(dev_addr) &&
|
return tuh_cdc_mounted(dev_addr) &&
|
||||||
(CDC_COMM_PROTOCOL_ATCOMMAND <= cdch_data[dev_addr-1].itf_protocol) &&
|
(CDC_COMM_PROTOCOL_ATCOMMAND <= cdch_data[dev_addr-1].itf_protocol) &&
|
||||||
(cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA);
|
(cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify)
|
bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify)
|
||||||
{
|
{
|
||||||
TU_VERIFY( tuh_cdc_mounted(dev_addr) );
|
TU_VERIFY( tuh_cdc_mounted(dev_addr) );
|
||||||
TU_VERIFY( p_data != NULL && length, TUSB_ERROR_INVALID_PARA);
|
TU_VERIFY( p_data != NULL && length, TUSB_ERROR_INVALID_PARA);
|
||||||
|
|
||||||
uint8_t const ep_out = cdch_data[dev_addr-1].ep_out;
|
uint8_t const ep_out = cdch_data[dev_addr-1].ep_out;
|
||||||
if ( hcd_edpt_busy(dev_addr, ep_out) ) return false;
|
if ( hcd_edpt_busy(dev_addr, ep_out) ) return false;
|
||||||
|
|
||||||
return hcd_pipe_xfer(dev_addr, ep_out, (void *) p_data, length, is_notify);
|
return hcd_pipe_xfer(dev_addr, ep_out, (void *) p_data, length, is_notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify)
|
bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify)
|
||||||
{
|
{
|
||||||
TU_VERIFY( tuh_cdc_mounted(dev_addr) );
|
TU_VERIFY( tuh_cdc_mounted(dev_addr) );
|
||||||
TU_VERIFY( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA);
|
TU_VERIFY( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA);
|
||||||
|
|
||||||
uint8_t const ep_in = cdch_data[dev_addr-1].ep_in;
|
uint8_t const ep_in = cdch_data[dev_addr-1].ep_in;
|
||||||
if ( hcd_edpt_busy(dev_addr, ep_in) ) return false;
|
if ( hcd_edpt_busy(dev_addr, ep_in) ) return false;
|
||||||
|
|
||||||
return hcd_pipe_xfer(dev_addr, ep_in, p_buffer, length, is_notify);
|
return hcd_pipe_xfer(dev_addr, ep_in, p_buffer, length, is_notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBH-CLASS DRIVER API
|
// USBH-CLASS DRIVER API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void cdch_init(void)
|
void cdch_init(void)
|
||||||
{
|
{
|
||||||
tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
|
bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
// Only support ACM
|
// Only support ACM
|
||||||
TU_VERIFY( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
|
TU_VERIFY( 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.
|
||||||
TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
|
TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
|
||||||
0xff == itf_desc->bInterfaceProtocol);
|
0xff == itf_desc->bInterfaceProtocol);
|
||||||
|
|
||||||
uint8_t const * p_desc;
|
uint8_t const * p_desc;
|
||||||
cdch_data_t * p_cdc;
|
cdch_data_t * p_cdc;
|
||||||
|
|
||||||
p_desc = tu_desc_next(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;
|
||||||
p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; // TODO 0xff is consider as rndis candidate, other is virtual Com
|
p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; // TODO 0xff is consider as rndis candidate, other is virtual Com
|
||||||
|
|
||||||
//------------- Communication Interface -------------//
|
//------------- Communication Interface -------------//
|
||||||
(*p_length) = sizeof(tusb_desc_interface_t);
|
(*p_length) = sizeof(tusb_desc_interface_t);
|
||||||
|
|
||||||
// Communication Functional Descriptors
|
// Communication Functional Descriptors
|
||||||
while( TUSB_DESC_CS_INTERFACE == p_desc[DESC_OFFSET_TYPE] )
|
while( TUSB_DESC_CS_INTERFACE == p_desc[DESC_OFFSET_TYPE] )
|
||||||
{
|
{
|
||||||
if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) )
|
if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) )
|
||||||
{
|
{
|
||||||
// save ACM bmCapabilities
|
// save ACM bmCapabilities
|
||||||
p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities;
|
p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = tu_desc_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])
|
||||||
{
|
{
|
||||||
// notification endpoint
|
// notification endpoint
|
||||||
tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) p_desc;
|
tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) p_desc;
|
||||||
|
|
||||||
TU_ASSERT( hcd_edpt_open(rhport, dev_addr, ep_desc) );
|
TU_ASSERT( hcd_edpt_open(rhport, dev_addr, ep_desc) );
|
||||||
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 = tu_desc_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) )
|
||||||
{
|
{
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = tu_desc_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++)
|
||||||
{
|
{
|
||||||
tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *) p_desc;
|
tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *) p_desc;
|
||||||
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
|
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
|
||||||
TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
|
TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
|
||||||
|
|
||||||
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
||||||
|
|
||||||
if ( tu_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
|
||||||
{
|
{
|
||||||
p_cdc->ep_out = ep_desc->bEndpointAddress;
|
p_cdc->ep_out = ep_desc->bEndpointAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = tu_desc_next( p_desc );
|
p_desc = tu_desc_next( p_desc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME move to seperate API : connect
|
// FIXME move to seperate API : connect
|
||||||
tusb_control_request_t request =
|
tusb_control_request_t request =
|
||||||
{
|
{
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE,
|
.bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE,
|
||||||
.wValue = 0x03, // dtr on, cst on
|
.wValue = 0x03, // dtr on, cst on
|
||||||
.wIndex = p_cdc->itf_num,
|
.wIndex = p_cdc->itf_num,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT( usbh_control_xfer(dev_addr, &request, NULL) );
|
TU_ASSERT( usbh_control_xfer(dev_addr, &request, NULL) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
(void) ep_addr;
|
(void) ep_addr;
|
||||||
tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes );
|
tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdch_close(uint8_t dev_addr)
|
void cdch_close(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
cdch_data_t * p_cdc = &cdch_data[dev_addr-1];
|
cdch_data_t * p_cdc = &cdch_data[dev_addr-1];
|
||||||
tu_memclr(p_cdc, sizeof(cdch_data_t));
|
tu_memclr(p_cdc, sizeof(cdch_data_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,123 +1,123 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_CDC_HOST_H_
|
#ifndef _TUSB_CDC_HOST_H_
|
||||||
#define _TUSB_CDC_HOST_H_
|
#define _TUSB_CDC_HOST_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "host/usbh.h"
|
#include "host/usbh.h"
|
||||||
#include "cdc.h"
|
#include "cdc.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CDC APPLICATION PUBLIC API
|
// CDC APPLICATION PUBLIC API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/** \ingroup ClassDriver_CDC Communication Device Class (CDC)
|
/** \ingroup ClassDriver_CDC Communication Device Class (CDC)
|
||||||
* \addtogroup CDC_Serial Serial
|
* \addtogroup CDC_Serial Serial
|
||||||
* @{
|
* @{
|
||||||
* \defgroup CDC_Serial_Host Host
|
* \defgroup CDC_Serial_Host Host
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** \brief Check if device support CDC Serial interface or not
|
/** \brief Check if device support CDC Serial interface or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if device supports
|
* \retval true if device supports
|
||||||
* \retval false if device does not support or is not mounted
|
* \retval false if device does not support or is not mounted
|
||||||
*/
|
*/
|
||||||
bool tuh_cdc_serial_is_mounted(uint8_t dev_addr);
|
bool tuh_cdc_serial_is_mounted(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Check if the interface is currently busy or not
|
/** \brief Check if the interface is currently busy or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] pipeid value from \ref cdc_pipeid_t to indicate target pipe.
|
* \param[in] pipeid value from \ref cdc_pipeid_t to indicate target pipe.
|
||||||
* \retval true if the interface is busy, meaning the stack is still transferring/waiting data from/to device
|
* \retval true if the interface is busy, meaning the stack is still transferring/waiting data from/to device
|
||||||
* \retval false if the interface is not busy, meaning the stack successfully transferred data from/to device
|
* \retval false if the interface is not busy, meaning the stack successfully transferred data from/to device
|
||||||
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
|
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
|
||||||
* can be scheduled. User needs to make sure the corresponding interface is mounted
|
* can be scheduled. User needs to make sure the corresponding interface is mounted
|
||||||
* (by \ref tuh_cdc_serial_is_mounted) before calling this function.
|
* (by \ref tuh_cdc_serial_is_mounted) before calling this function.
|
||||||
*/
|
*/
|
||||||
bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid);
|
bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid);
|
||||||
|
|
||||||
/** \brief Perform USB OUT transfer to device
|
/** \brief Perform USB OUT transfer to device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] p_data Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[in] p_data Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \param[in] length Number of bytes to be transferred via USB bus
|
* \param[in] length Number of bytes to be transferred via USB bus
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
|
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
|
||||||
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
|
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
|
||||||
*/
|
*/
|
||||||
bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify);
|
bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify);
|
||||||
|
|
||||||
/** \brief Perform USB IN transfer to get data from device
|
/** \brief Perform USB IN transfer to get data from device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] p_buffer Buffer containing received data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[in] p_buffer Buffer containing received data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \param[in] length Number of bytes to be transferred via USB bus
|
* \param[in] length Number of bytes to be transferred via USB bus
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
|
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
|
||||||
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
|
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
|
||||||
*/
|
*/
|
||||||
bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify);
|
bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CDC APPLICATION CALLBACKS
|
// CDC APPLICATION CALLBACKS
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/** \brief Callback function that is invoked when an transferring event occurred
|
/** \brief Callback function that is invoked when an transferring event occurred
|
||||||
* \param[in] dev_addr Address of device
|
* \param[in] dev_addr Address of device
|
||||||
* \param[in] event an value from \ref xfer_result_t
|
* \param[in] event an value from \ref xfer_result_t
|
||||||
* \param[in] pipe_id value from \ref cdc_pipeid_t indicate the pipe
|
* \param[in] pipe_id value from \ref cdc_pipeid_t indicate the pipe
|
||||||
* \param[in] xferred_bytes Number of bytes transferred via USB bus
|
* \param[in] xferred_bytes Number of bytes transferred via USB bus
|
||||||
* \note event can be one of following
|
* \note event can be one of following
|
||||||
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
||||||
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
||||||
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
||||||
* \note
|
* \note
|
||||||
*/
|
*/
|
||||||
void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes);
|
void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes);
|
||||||
|
|
||||||
/// @} // group CDC_Serial_Host
|
/// @} // group CDC_Serial_Host
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void cdch_init(void);
|
void cdch_init(void);
|
||||||
bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
|
bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
|
||||||
void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void cdch_close(uint8_t dev_addr);
|
void cdch_close(uint8_t dev_addr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_CDC_HOST_H_ */
|
#endif /* _TUSB_CDC_HOST_H_ */
|
||||||
|
1746
src/class/hid/hid.h
1746
src/class/hid/hid.h
File diff suppressed because it is too large
Load Diff
@ -162,9 +162,18 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t
|
|||||||
{
|
{
|
||||||
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
||||||
|
|
||||||
// TODO support multiple HID interface
|
// Find available interface
|
||||||
uint8_t const itf = 0;
|
hidd_interface_t * p_hid = NULL;
|
||||||
hidd_interface_t * p_hid = &_hidd_itf[itf];
|
uint8_t hid_id;
|
||||||
|
for(hid_id=0; hid_id<CFG_TUD_HID; hid_id++)
|
||||||
|
{
|
||||||
|
if ( _hidd_itf[hid_id].ep_in == 0 )
|
||||||
|
{
|
||||||
|
p_hid = &_hidd_itf[hid_id];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TU_ASSERT(p_hid);
|
||||||
|
|
||||||
//------------- HID descriptor -------------//
|
//------------- HID descriptor -------------//
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
@ -309,9 +318,15 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
|
|||||||
{
|
{
|
||||||
(void) result;
|
(void) result;
|
||||||
|
|
||||||
// TODO support multiple HID interface
|
uint8_t itf = 0;
|
||||||
uint8_t const itf = 0;
|
hidd_interface_t * p_hid = _hidd_itf;
|
||||||
hidd_interface_t * p_hid = &_hidd_itf[itf];
|
|
||||||
|
for ( ; ; itf++, p_hid++)
|
||||||
|
{
|
||||||
|
if (itf >= TU_ARRAY_SIZE(_hidd_itf)) return false;
|
||||||
|
|
||||||
|
if ( ep_addr == p_hid->ep_out ) break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ep_addr == p_hid->ep_out)
|
if (ep_addr == p_hid->ep_out)
|
||||||
{
|
{
|
||||||
|
@ -1,315 +1,315 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_HID_DEVICE_H_
|
#ifndef _TUSB_HID_DEVICE_H_
|
||||||
#define _TUSB_HID_DEVICE_H_
|
#define _TUSB_HID_DEVICE_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "device/usbd.h"
|
#include "device/usbd.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Class Driver Default Configure & Validation
|
// Class Driver Default Configure & Validation
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#ifndef CFG_TUD_HID_BUFSIZE
|
#ifndef CFG_TUD_HID_BUFSIZE
|
||||||
#define CFG_TUD_HID_BUFSIZE 16
|
#define CFG_TUD_HID_BUFSIZE 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API
|
// Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Check if the interface is ready to use
|
// Check if the interface is ready to use
|
||||||
bool tud_hid_ready(void);
|
bool tud_hid_ready(void);
|
||||||
|
|
||||||
// Check if current mode is Boot (true) or Report (false)
|
// Check if current mode is Boot (true) or Report (false)
|
||||||
bool tud_hid_boot_mode(void);
|
bool tud_hid_boot_mode(void);
|
||||||
|
|
||||||
// Send report to host
|
// Send report to host
|
||||||
bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len);
|
bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len);
|
||||||
|
|
||||||
// KEYBOARD: convenient helper to send keyboard report if application
|
// KEYBOARD: convenient helper to send keyboard report if application
|
||||||
// use template layout report as defined by hid_keyboard_report_t
|
// use template layout report as defined by hid_keyboard_report_t
|
||||||
bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
|
bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
|
||||||
|
|
||||||
// MOUSE: convenient helper to send mouse report if application
|
// MOUSE: convenient helper to send mouse report if application
|
||||||
// use template layout report as defined by hid_mouse_report_t
|
// use template layout report as defined by hid_mouse_report_t
|
||||||
bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
|
bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Callbacks (Weak is optional)
|
// Callbacks (Weak is optional)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when received GET HID REPORT DESCRIPTOR request
|
// Invoked when received GET HID REPORT DESCRIPTOR request
|
||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
uint8_t const * tud_hid_descriptor_report_cb(void);
|
uint8_t const * tud_hid_descriptor_report_cb(void);
|
||||||
|
|
||||||
// Invoked when received GET_REPORT control request
|
// Invoked when received GET_REPORT control request
|
||||||
// Application must fill buffer report's content and return its length.
|
// Application must fill buffer report's content and return its length.
|
||||||
// Return zero will cause the stack to STALL request
|
// Return zero will cause the stack to STALL request
|
||||||
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
|
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
|
||||||
|
|
||||||
// Invoked when received SET_REPORT control request or
|
// Invoked when received SET_REPORT control request or
|
||||||
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
||||||
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
|
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
|
||||||
|
|
||||||
// Invoked when received SET_PROTOCOL request ( mode switch Boot <-> Report )
|
// Invoked when received SET_PROTOCOL request ( mode switch Boot <-> Report )
|
||||||
TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t boot_mode);
|
TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t boot_mode);
|
||||||
|
|
||||||
// Invoked when received SET_IDLE request. return false will stall the request
|
// Invoked when received SET_IDLE request. return false will stall the request
|
||||||
// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication
|
// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication
|
||||||
// - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
|
// - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
|
||||||
TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate);
|
TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------+
|
/* --------------------------------------------------------------------+
|
||||||
* HID Report Descriptor Template
|
* HID Report Descriptor Template
|
||||||
*
|
*
|
||||||
* Convenient for declaring popular HID device (keyboard, mouse, consumer,
|
* Convenient for declaring popular HID device (keyboard, mouse, consumer,
|
||||||
* gamepad etc...). Templates take "HID_REPORT_ID(n)," as input, leave
|
* gamepad etc...). Templates take "HID_REPORT_ID(n)," as input, leave
|
||||||
* empty if multiple reports is not used
|
* empty if multiple reports is not used
|
||||||
*
|
*
|
||||||
* - Only 1 report: no parameter
|
* - Only 1 report: no parameter
|
||||||
* uint8_t const report_desc[] = { TUD_HID_REPORT_DESC_KEYBOARD() };
|
* uint8_t const report_desc[] = { TUD_HID_REPORT_DESC_KEYBOARD() };
|
||||||
*
|
*
|
||||||
* - Multiple Reports: "HID_REPORT_ID(ID)," must be passed to template
|
* - Multiple Reports: "HID_REPORT_ID(ID)," must be passed to template
|
||||||
* uint8_t const report_desc[] =
|
* uint8_t const report_desc[] =
|
||||||
* {
|
* {
|
||||||
* TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1), ) ,
|
* TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1), ) ,
|
||||||
* TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2), )
|
* TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2), )
|
||||||
* };
|
* };
|
||||||
*--------------------------------------------------------------------*/
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
// Keyboard Report Descriptor Template
|
// Keyboard Report Descriptor Template
|
||||||
#define TUD_HID_REPORT_DESC_KEYBOARD(...) \
|
#define TUD_HID_REPORT_DESC_KEYBOARD(...) \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\
|
||||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||||
/* Report ID if any */\
|
/* Report ID if any */\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
/* 8 bits Modifier Keys (Shfit, Control, Alt) */ \
|
/* 8 bits Modifier Keys (Shfit, Control, Alt) */ \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
|
||||||
HID_USAGE_MIN ( 224 ) ,\
|
HID_USAGE_MIN ( 224 ) ,\
|
||||||
HID_USAGE_MAX ( 231 ) ,\
|
HID_USAGE_MAX ( 231 ) ,\
|
||||||
HID_LOGICAL_MIN ( 0 ) ,\
|
HID_LOGICAL_MIN ( 0 ) ,\
|
||||||
HID_LOGICAL_MAX ( 1 ) ,\
|
HID_LOGICAL_MAX ( 1 ) ,\
|
||||||
HID_REPORT_COUNT ( 8 ) ,\
|
HID_REPORT_COUNT ( 8 ) ,\
|
||||||
HID_REPORT_SIZE ( 1 ) ,\
|
HID_REPORT_SIZE ( 1 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||||
/* 8 bit reserved */ \
|
/* 8 bit reserved */ \
|
||||||
HID_REPORT_COUNT ( 1 ) ,\
|
HID_REPORT_COUNT ( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 8 ) ,\
|
HID_REPORT_SIZE ( 8 ) ,\
|
||||||
HID_INPUT ( HID_CONSTANT ) ,\
|
HID_INPUT ( HID_CONSTANT ) ,\
|
||||||
/* 6-byte Keycodes */ \
|
/* 6-byte Keycodes */ \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
|
||||||
HID_USAGE_MIN ( 0 ) ,\
|
HID_USAGE_MIN ( 0 ) ,\
|
||||||
HID_USAGE_MAX ( 255 ) ,\
|
HID_USAGE_MAX ( 255 ) ,\
|
||||||
HID_LOGICAL_MIN ( 0 ) ,\
|
HID_LOGICAL_MIN ( 0 ) ,\
|
||||||
HID_LOGICAL_MAX ( 255 ) ,\
|
HID_LOGICAL_MAX ( 255 ) ,\
|
||||||
HID_REPORT_COUNT ( 6 ) ,\
|
HID_REPORT_COUNT ( 6 ) ,\
|
||||||
HID_REPORT_SIZE ( 8 ) ,\
|
HID_REPORT_SIZE ( 8 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
||||||
/* 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \
|
/* 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\
|
||||||
HID_USAGE_MIN ( 1 ) ,\
|
HID_USAGE_MIN ( 1 ) ,\
|
||||||
HID_USAGE_MAX ( 5 ) ,\
|
HID_USAGE_MAX ( 5 ) ,\
|
||||||
HID_REPORT_COUNT ( 5 ) ,\
|
HID_REPORT_COUNT ( 5 ) ,\
|
||||||
HID_REPORT_SIZE ( 1 ) ,\
|
HID_REPORT_SIZE ( 1 ) ,\
|
||||||
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||||
/* led padding */ \
|
/* led padding */ \
|
||||||
HID_REPORT_COUNT ( 1 ) ,\
|
HID_REPORT_COUNT ( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 3 ) ,\
|
HID_REPORT_SIZE ( 3 ) ,\
|
||||||
HID_OUTPUT ( HID_CONSTANT ) ,\
|
HID_OUTPUT ( HID_CONSTANT ) ,\
|
||||||
HID_COLLECTION_END \
|
HID_COLLECTION_END \
|
||||||
|
|
||||||
// Mouse Report Descriptor Template
|
// Mouse Report Descriptor Template
|
||||||
#define TUD_HID_REPORT_DESC_MOUSE(...) \
|
#define TUD_HID_REPORT_DESC_MOUSE(...) \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
|
||||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||||
/* Report ID if any */\
|
/* Report ID if any */\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
|
||||||
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
|
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||||
HID_USAGE_MIN ( 1 ) ,\
|
HID_USAGE_MIN ( 1 ) ,\
|
||||||
HID_USAGE_MAX ( 5 ) ,\
|
HID_USAGE_MAX ( 5 ) ,\
|
||||||
HID_LOGICAL_MIN ( 0 ) ,\
|
HID_LOGICAL_MIN ( 0 ) ,\
|
||||||
HID_LOGICAL_MAX ( 1 ) ,\
|
HID_LOGICAL_MAX ( 1 ) ,\
|
||||||
/* Left, Right, Middle, Backward, Forward buttons */ \
|
/* Left, Right, Middle, Backward, Forward buttons */ \
|
||||||
HID_REPORT_COUNT( 5 ) ,\
|
HID_REPORT_COUNT( 5 ) ,\
|
||||||
HID_REPORT_SIZE ( 1 ) ,\
|
HID_REPORT_SIZE ( 1 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||||
/* 3 bit padding */ \
|
/* 3 bit padding */ \
|
||||||
HID_REPORT_COUNT( 1 ) ,\
|
HID_REPORT_COUNT( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 3 ) ,\
|
HID_REPORT_SIZE ( 3 ) ,\
|
||||||
HID_INPUT ( HID_CONSTANT ) ,\
|
HID_INPUT ( HID_CONSTANT ) ,\
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||||
/* X, Y position [-127, 127] */ \
|
/* X, Y position [-127, 127] */ \
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||||
HID_REPORT_COUNT( 2 ) ,\
|
HID_REPORT_COUNT( 2 ) ,\
|
||||||
HID_REPORT_SIZE ( 8 ) ,\
|
HID_REPORT_SIZE ( 8 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||||
/* Verital wheel scroll [-127, 127] */ \
|
/* Verital wheel scroll [-127, 127] */ \
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
|
||||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||||
HID_REPORT_COUNT( 1 ) ,\
|
HID_REPORT_COUNT( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 8 ) ,\
|
HID_REPORT_SIZE ( 8 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
|
||||||
/* Horizontal wheel scroll [-127, 127] */ \
|
/* Horizontal wheel scroll [-127, 127] */ \
|
||||||
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
|
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
|
||||||
HID_LOGICAL_MIN ( 0x81 ), \
|
HID_LOGICAL_MIN ( 0x81 ), \
|
||||||
HID_LOGICAL_MAX ( 0x7f ), \
|
HID_LOGICAL_MAX ( 0x7f ), \
|
||||||
HID_REPORT_COUNT( 1 ), \
|
HID_REPORT_COUNT( 1 ), \
|
||||||
HID_REPORT_SIZE ( 8 ), \
|
HID_REPORT_SIZE ( 8 ), \
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
|
||||||
HID_COLLECTION_END , \
|
HID_COLLECTION_END , \
|
||||||
HID_COLLECTION_END \
|
HID_COLLECTION_END \
|
||||||
|
|
||||||
// Consumer Control Report Descriptor Template
|
// Consumer Control Report Descriptor Template
|
||||||
#define TUD_HID_REPORT_DESC_CONSUMER(...) \
|
#define TUD_HID_REPORT_DESC_CONSUMER(...) \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\
|
||||||
HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\
|
HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\
|
||||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||||
/* Report ID if any */\
|
/* Report ID if any */\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
HID_LOGICAL_MIN ( 0x00 ) ,\
|
HID_LOGICAL_MIN ( 0x00 ) ,\
|
||||||
HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\
|
HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\
|
||||||
HID_USAGE_MIN ( 0x00 ) ,\
|
HID_USAGE_MIN ( 0x00 ) ,\
|
||||||
HID_USAGE_MAX_N ( 0x03FF, 2 ) ,\
|
HID_USAGE_MAX_N ( 0x03FF, 2 ) ,\
|
||||||
HID_REPORT_COUNT ( 1 ) ,\
|
HID_REPORT_COUNT ( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 16 ) ,\
|
HID_REPORT_SIZE ( 16 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
||||||
HID_COLLECTION_END \
|
HID_COLLECTION_END \
|
||||||
|
|
||||||
/* System Control Report Descriptor Template
|
/* System Control Report Descriptor Template
|
||||||
* 0x00 - do nothing
|
* 0x00 - do nothing
|
||||||
* 0x01 - Power Off
|
* 0x01 - Power Off
|
||||||
* 0x02 - Standby
|
* 0x02 - Standby
|
||||||
* 0x04 - Wake Host
|
* 0x04 - Wake Host
|
||||||
*/
|
*/
|
||||||
#define TUD_HID_REPORT_DESC_SYSTEM_CONTROL(...) \
|
#define TUD_HID_REPORT_DESC_SYSTEM_CONTROL(...) \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\
|
||||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||||
/* Report ID if any */\
|
/* Report ID if any */\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
/* 2 bit system power control */ \
|
/* 2 bit system power control */ \
|
||||||
HID_LOGICAL_MIN ( 1 ) ,\
|
HID_LOGICAL_MIN ( 1 ) ,\
|
||||||
HID_LOGICAL_MAX ( 3 ) ,\
|
HID_LOGICAL_MAX ( 3 ) ,\
|
||||||
HID_REPORT_COUNT ( 1 ) ,\
|
HID_REPORT_COUNT ( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 2 ) ,\
|
HID_REPORT_SIZE ( 2 ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_SLEEP ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_SLEEP ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_WAKE_UP ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_WAKE_UP ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
||||||
/* 6 bit padding */ \
|
/* 6 bit padding */ \
|
||||||
HID_REPORT_COUNT ( 1 ) ,\
|
HID_REPORT_COUNT ( 1 ) ,\
|
||||||
HID_REPORT_SIZE ( 6 ) ,\
|
HID_REPORT_SIZE ( 6 ) ,\
|
||||||
HID_INPUT ( HID_CONSTANT ) ,\
|
HID_INPUT ( HID_CONSTANT ) ,\
|
||||||
HID_COLLECTION_END \
|
HID_COLLECTION_END \
|
||||||
|
|
||||||
// Gamepad Report Descriptor Template
|
// Gamepad Report Descriptor Template
|
||||||
// with 16 buttons and 2 joysticks with following layout
|
// with 16 buttons and 2 joysticks with following layout
|
||||||
// | Button Map (2 bytes) | X | Y | Z | Rz
|
// | Button Map (2 bytes) | X | Y | Z | Rz
|
||||||
#define TUD_HID_REPORT_DESC_GAMEPAD(...) \
|
#define TUD_HID_REPORT_DESC_GAMEPAD(...) \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
|
||||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||||
/* Report ID if any */\
|
/* Report ID if any */\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
/* 16 bit Button Map */ \
|
/* 16 bit Button Map */ \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||||
HID_USAGE_MIN ( 1 ) ,\
|
HID_USAGE_MIN ( 1 ) ,\
|
||||||
HID_USAGE_MAX ( 16 ) ,\
|
HID_USAGE_MAX ( 16 ) ,\
|
||||||
HID_LOGICAL_MIN ( 0 ) ,\
|
HID_LOGICAL_MIN ( 0 ) ,\
|
||||||
HID_LOGICAL_MAX ( 1 ) ,\
|
HID_LOGICAL_MAX ( 1 ) ,\
|
||||||
HID_REPORT_COUNT ( 16 ) ,\
|
HID_REPORT_COUNT ( 16 ) ,\
|
||||||
HID_REPORT_SIZE ( 1 ) ,\
|
HID_REPORT_SIZE ( 1 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
|
||||||
/* X, Y, Z, Rz (min -127, max 127 ) */ \
|
/* X, Y, Z, Rz (min -127, max 127 ) */ \
|
||||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
|
||||||
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
|
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
|
||||||
HID_REPORT_COUNT ( 4 ) ,\
|
HID_REPORT_COUNT ( 4 ) ,\
|
||||||
HID_REPORT_SIZE ( 8 ) ,\
|
HID_REPORT_SIZE ( 8 ) ,\
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||||
HID_COLLECTION_END \
|
HID_COLLECTION_END \
|
||||||
|
|
||||||
// HID Generic Input & Output
|
// HID Generic Input & Output
|
||||||
// - 1st parameter is report size (mandatory)
|
// - 1st parameter is report size (mandatory)
|
||||||
// - 2nd parameter is report id HID_REPORT_ID(n) (optional)
|
// - 2nd parameter is report id HID_REPORT_ID(n) (optional)
|
||||||
#define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \
|
#define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \
|
||||||
HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\
|
HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\
|
||||||
HID_USAGE ( 0x01 ),\
|
HID_USAGE ( 0x01 ),\
|
||||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\
|
||||||
/* Report ID if any */\
|
/* Report ID if any */\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
/* Input */ \
|
/* Input */ \
|
||||||
HID_USAGE ( 0x02 ),\
|
HID_USAGE ( 0x02 ),\
|
||||||
HID_LOGICAL_MIN ( 0x00 ),\
|
HID_LOGICAL_MIN ( 0x00 ),\
|
||||||
HID_LOGICAL_MAX ( 0xff ),\
|
HID_LOGICAL_MAX ( 0xff ),\
|
||||||
HID_REPORT_SIZE ( 8 ),\
|
HID_REPORT_SIZE ( 8 ),\
|
||||||
HID_REPORT_COUNT( report_size ),\
|
HID_REPORT_COUNT( report_size ),\
|
||||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
||||||
/* Output */ \
|
/* Output */ \
|
||||||
HID_USAGE ( 0x03 ),\
|
HID_USAGE ( 0x03 ),\
|
||||||
HID_LOGICAL_MIN ( 0x00 ),\
|
HID_LOGICAL_MIN ( 0x00 ),\
|
||||||
HID_LOGICAL_MAX ( 0xff ),\
|
HID_LOGICAL_MAX ( 0xff ),\
|
||||||
HID_REPORT_SIZE ( 8 ),\
|
HID_REPORT_SIZE ( 8 ),\
|
||||||
HID_REPORT_COUNT( report_size ),\
|
HID_REPORT_COUNT( report_size ),\
|
||||||
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
||||||
HID_COLLECTION_END \
|
HID_COLLECTION_END \
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void hidd_init (void);
|
void hidd_init (void);
|
||||||
void hidd_reset (uint8_t rhport);
|
void hidd_reset (uint8_t rhport);
|
||||||
bool hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_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 * request);
|
bool hidd_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool hidd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
bool hidd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_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);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_HID_DEVICE_H_ */
|
#endif /* _TUSB_HID_DEVICE_H_ */
|
||||||
|
|
||||||
|
@ -1,289 +1,289 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if (TUSB_OPT_HOST_ENABLED && HOST_CLASS_HID)
|
#if (TUSB_OPT_HOST_ENABLED && HOST_CLASS_HID)
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "hid_host.h"
|
#include "hid_host.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// HID Interface common functions
|
// HID Interface common functions
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline bool hidh_interface_open(uint8_t dev_addr, uint8_t interface_number, tusb_desc_endpoint_t const *p_endpoint_desc, hidh_interface_info_t *p_hid)
|
static inline bool hidh_interface_open(uint8_t dev_addr, uint8_t interface_number, tusb_desc_endpoint_t const *p_endpoint_desc, hidh_interface_info_t *p_hid)
|
||||||
{
|
{
|
||||||
p_hid->pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID);
|
p_hid->pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID);
|
||||||
p_hid->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor
|
p_hid->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor
|
||||||
p_hid->interface_number = interface_number;
|
p_hid->interface_number = interface_number;
|
||||||
|
|
||||||
TU_ASSERT (pipehandle_is_valid(p_hid->pipe_hdl));
|
TU_ASSERT (pipehandle_is_valid(p_hid->pipe_hdl));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void hidh_interface_close(hidh_interface_info_t *p_hid)
|
static inline void hidh_interface_close(hidh_interface_info_t *p_hid)
|
||||||
{
|
{
|
||||||
tu_memclr(p_hid, sizeof(hidh_interface_info_t));
|
tu_memclr(p_hid, sizeof(hidh_interface_info_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from public API need to validate parameters
|
// called from public API need to validate parameters
|
||||||
tusb_error_t hidh_interface_get_report(uint8_t dev_addr, void * report, hidh_interface_info_t *p_hid)
|
tusb_error_t hidh_interface_get_report(uint8_t dev_addr, void * report, hidh_interface_info_t *p_hid)
|
||||||
{
|
{
|
||||||
//------------- parameters validation -------------//
|
//------------- parameters validation -------------//
|
||||||
// TODO change to use is configured function
|
// TODO change to use is configured function
|
||||||
TU_ASSERT (TUSB_DEVICE_STATE_CONFIGURED == tuh_device_get_state(dev_addr), TUSB_ERROR_DEVICE_NOT_READY);
|
TU_ASSERT (TUSB_DEVICE_STATE_CONFIGURED == tuh_device_get_state(dev_addr), TUSB_ERROR_DEVICE_NOT_READY);
|
||||||
TU_VERIFY (report, TUSB_ERROR_INVALID_PARA);
|
TU_VERIFY (report, TUSB_ERROR_INVALID_PARA);
|
||||||
TU_ASSERT (!hcd_edpt_busy(p_hid->pipe_hdl), TUSB_ERROR_INTERFACE_IS_BUSY);
|
TU_ASSERT (!hcd_edpt_busy(p_hid->pipe_hdl), TUSB_ERROR_INTERFACE_IS_BUSY);
|
||||||
|
|
||||||
TU_ASSERT_ERR( hcd_pipe_xfer(p_hid->pipe_hdl, report, p_hid->report_size, true) ) ;
|
TU_ASSERT_ERR( hcd_pipe_xfer(p_hid->pipe_hdl, report, p_hid->report_size, true) ) ;
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// KEYBOARD
|
// KEYBOARD
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#if CFG_TUH_HID_KEYBOARD
|
#if CFG_TUH_HID_KEYBOARD
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define EXPAND_KEYCODE_TO_ASCII(keycode, ascii, shift_modified) \
|
#define EXPAND_KEYCODE_TO_ASCII(keycode, ascii, shift_modified) \
|
||||||
[0][keycode] = ascii,\
|
[0][keycode] = ascii,\
|
||||||
[1][keycode] = shift_modified,\
|
[1][keycode] = shift_modified,\
|
||||||
|
|
||||||
// TODO size of table should be a macro for application to check boundary
|
// TODO size of table should be a macro for application to check boundary
|
||||||
uint8_t const hid_keycode_to_ascii_tbl[2][128] =
|
uint8_t const hid_keycode_to_ascii_tbl[2][128] =
|
||||||
{
|
{
|
||||||
HID_KEYCODE_TABLE(EXPAND_KEYCODE_TO_ASCII)
|
HID_KEYCODE_TABLE(EXPAND_KEYCODE_TO_ASCII)
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
|
static hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
|
||||||
|
|
||||||
//------------- KEYBOARD PUBLIC API (parameter validation required) -------------//
|
//------------- KEYBOARD PUBLIC API (parameter validation required) -------------//
|
||||||
bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr)
|
bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return tuh_device_is_configured(dev_addr) && pipehandle_is_valid(keyboardh_data[dev_addr-1].pipe_hdl);
|
return tuh_device_is_configured(dev_addr) && pipehandle_is_valid(keyboardh_data[dev_addr-1].pipe_hdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void* p_report)
|
tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void* p_report)
|
||||||
{
|
{
|
||||||
return hidh_interface_get_report(dev_addr, p_report, &keyboardh_data[dev_addr-1]);
|
return hidh_interface_get_report(dev_addr, p_report, &keyboardh_data[dev_addr-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuh_hid_keyboard_is_busy(uint8_t dev_addr)
|
bool tuh_hid_keyboard_is_busy(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return tuh_hid_keyboard_is_mounted(dev_addr) &&
|
return tuh_hid_keyboard_is_mounted(dev_addr) &&
|
||||||
hcd_edpt_busy( keyboardh_data[dev_addr-1].pipe_hdl );
|
hcd_edpt_busy( keyboardh_data[dev_addr-1].pipe_hdl );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MOUSE
|
// MOUSE
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#if CFG_TUH_HID_MOUSE
|
#if CFG_TUH_HID_MOUSE
|
||||||
|
|
||||||
static hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
|
static hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
|
||||||
|
|
||||||
//------------- Public API -------------//
|
//------------- Public API -------------//
|
||||||
bool tuh_hid_mouse_is_mounted(uint8_t dev_addr)
|
bool tuh_hid_mouse_is_mounted(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return tuh_device_is_configured(dev_addr) && pipehandle_is_valid(mouseh_data[dev_addr-1].pipe_hdl);
|
return tuh_device_is_configured(dev_addr) && pipehandle_is_valid(mouseh_data[dev_addr-1].pipe_hdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuh_hid_mouse_is_busy(uint8_t dev_addr)
|
bool tuh_hid_mouse_is_busy(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return tuh_hid_mouse_is_mounted(dev_addr) &&
|
return tuh_hid_mouse_is_mounted(dev_addr) &&
|
||||||
hcd_edpt_busy( mouseh_data[dev_addr-1].pipe_hdl );
|
hcd_edpt_busy( mouseh_data[dev_addr-1].pipe_hdl );
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void * report)
|
tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void * report)
|
||||||
{
|
{
|
||||||
return hidh_interface_get_report(dev_addr, report, &mouseh_data[dev_addr-1]);
|
return hidh_interface_get_report(dev_addr, report, &mouseh_data[dev_addr-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// GENERIC
|
// GENERIC
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#if CFG_TUSB_HOST_HID_GENERIC
|
#if CFG_TUSB_HOST_HID_GENERIC
|
||||||
|
|
||||||
//STATIC_ struct {
|
//STATIC_ struct {
|
||||||
// hidh_interface_info_t
|
// hidh_interface_info_t
|
||||||
//} generic_data[CFG_TUSB_HOST_DEVICE_MAX];
|
//} generic_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CLASS-USBH API (don't require to verify parameters)
|
// CLASS-USBH API (don't require to verify parameters)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void hidh_init(void)
|
void hidh_init(void)
|
||||||
{
|
{
|
||||||
#if CFG_TUH_HID_KEYBOARD
|
#if CFG_TUH_HID_KEYBOARD
|
||||||
tu_memclr(&keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
tu_memclr(&keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_HID_MOUSE
|
#if CFG_TUH_HID_MOUSE
|
||||||
tu_memclr(&mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
tu_memclr(&mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUSB_HOST_HID_GENERIC
|
#if CFG_TUSB_HOST_HID_GENERIC
|
||||||
hidh_generic_init();
|
hidh_generic_init();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
CFG_TUSB_MEM_SECTION uint8_t report_descriptor[256];
|
CFG_TUSB_MEM_SECTION uint8_t report_descriptor[256];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
|
bool hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
|
uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
|
||||||
|
|
||||||
//------------- HID descriptor -------------//
|
//------------- HID descriptor -------------//
|
||||||
p_desc += p_desc[DESC_OFFSET_LEN];
|
p_desc += p_desc[DESC_OFFSET_LEN];
|
||||||
tusb_hid_descriptor_hid_t const *p_desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
|
tusb_hid_descriptor_hid_t const *p_desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
|
||||||
TU_ASSERT(HID_DESC_TYPE_HID == p_desc_hid->bDescriptorType, TUSB_ERROR_INVALID_PARA);
|
TU_ASSERT(HID_DESC_TYPE_HID == p_desc_hid->bDescriptorType, TUSB_ERROR_INVALID_PARA);
|
||||||
|
|
||||||
//------------- Endpoint Descriptor -------------//
|
//------------- Endpoint Descriptor -------------//
|
||||||
p_desc += p_desc[DESC_OFFSET_LEN];
|
p_desc += p_desc[DESC_OFFSET_LEN];
|
||||||
tusb_desc_endpoint_t const * p_endpoint_desc = (tusb_desc_endpoint_t const *) p_desc;
|
tusb_desc_endpoint_t const * p_endpoint_desc = (tusb_desc_endpoint_t const *) p_desc;
|
||||||
TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint_desc->bDescriptorType, TUSB_ERROR_INVALID_PARA);
|
TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint_desc->bDescriptorType, TUSB_ERROR_INVALID_PARA);
|
||||||
|
|
||||||
//------------- SET IDLE (0) request -------------//
|
//------------- SET IDLE (0) request -------------//
|
||||||
tusb_control_request_t request = {
|
tusb_control_request_t request = {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = HID_REQ_CONTROL_SET_IDLE,
|
.bRequest = HID_REQ_CONTROL_SET_IDLE,
|
||||||
.wValue = 0, // idle_rate = 0
|
.wValue = 0, // idle_rate = 0
|
||||||
.wIndex = p_interface_desc->bInterfaceNumber,
|
.wIndex = p_interface_desc->bInterfaceNumber,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
|
TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
//------------- Get Report Descriptor TODO HID parser -------------//
|
//------------- Get Report Descriptor TODO HID parser -------------//
|
||||||
if ( p_desc_hid->bNumDescriptors )
|
if ( p_desc_hid->bNumDescriptors )
|
||||||
{
|
{
|
||||||
STASK_INVOKE(
|
STASK_INVOKE(
|
||||||
usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_STANDARD, TUSB_REQ_RCPT_INTERFACE),
|
usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_STANDARD, TUSB_REQ_RCPT_INTERFACE),
|
||||||
TUSB_REQ_GET_DESCRIPTOR, (p_desc_hid->bReportType << 8), 0,
|
TUSB_REQ_GET_DESCRIPTOR, (p_desc_hid->bReportType << 8), 0,
|
||||||
p_desc_hid->wReportLength, report_descriptor ),
|
p_desc_hid->wReportLength, report_descriptor ),
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
(void) error; // if error in getting report descriptor --> treating like there is none
|
(void) error; // if error in getting report descriptor --> treating like there is none
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( HID_SUBCLASS_BOOT == p_interface_desc->bInterfaceSubClass )
|
if ( HID_SUBCLASS_BOOT == p_interface_desc->bInterfaceSubClass )
|
||||||
{
|
{
|
||||||
#if CFG_TUH_HID_KEYBOARD
|
#if CFG_TUH_HID_KEYBOARD
|
||||||
if ( HID_PROTOCOL_KEYBOARD == p_interface_desc->bInterfaceProtocol)
|
if ( HID_PROTOCOL_KEYBOARD == p_interface_desc->bInterfaceProtocol)
|
||||||
{
|
{
|
||||||
TU_ASSERT( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &keyboardh_data[dev_addr-1]) );
|
TU_ASSERT( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &keyboardh_data[dev_addr-1]) );
|
||||||
tuh_hid_keyboard_mounted_cb(dev_addr);
|
tuh_hid_keyboard_mounted_cb(dev_addr);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_HID_MOUSE
|
#if CFG_TUH_HID_MOUSE
|
||||||
if ( HID_PROTOCOL_MOUSE == p_interface_desc->bInterfaceProtocol)
|
if ( HID_PROTOCOL_MOUSE == p_interface_desc->bInterfaceProtocol)
|
||||||
{
|
{
|
||||||
TU_ASSERT ( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &mouseh_data[dev_addr-1]) );
|
TU_ASSERT ( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &mouseh_data[dev_addr-1]) );
|
||||||
tuh_hid_mouse_mounted_cb(dev_addr);
|
tuh_hid_mouse_mounted_cb(dev_addr);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
// Not supported protocol
|
// Not supported protocol
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
// Not supported subclass
|
// Not supported subclass
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t);
|
*p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)
|
void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
(void) xferred_bytes; // TODO may need to use this para later
|
(void) xferred_bytes; // TODO may need to use this para later
|
||||||
|
|
||||||
#if CFG_TUH_HID_KEYBOARD
|
#if CFG_TUH_HID_KEYBOARD
|
||||||
if ( pipehandle_is_equal(pipe_hdl, keyboardh_data[pipe_hdl.dev_addr-1].pipe_hdl) )
|
if ( pipehandle_is_equal(pipe_hdl, keyboardh_data[pipe_hdl.dev_addr-1].pipe_hdl) )
|
||||||
{
|
{
|
||||||
tuh_hid_keyboard_isr(pipe_hdl.dev_addr, event);
|
tuh_hid_keyboard_isr(pipe_hdl.dev_addr, event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_HID_MOUSE
|
#if CFG_TUH_HID_MOUSE
|
||||||
if ( pipehandle_is_equal(pipe_hdl, mouseh_data[pipe_hdl.dev_addr-1].pipe_hdl) )
|
if ( pipehandle_is_equal(pipe_hdl, mouseh_data[pipe_hdl.dev_addr-1].pipe_hdl) )
|
||||||
{
|
{
|
||||||
tuh_hid_mouse_isr(pipe_hdl.dev_addr, event);
|
tuh_hid_mouse_isr(pipe_hdl.dev_addr, event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUSB_HOST_HID_GENERIC
|
#if CFG_TUSB_HOST_HID_GENERIC
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidh_close(uint8_t dev_addr)
|
void hidh_close(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
#if CFG_TUH_HID_KEYBOARD
|
#if CFG_TUH_HID_KEYBOARD
|
||||||
if ( pipehandle_is_valid( keyboardh_data[dev_addr-1].pipe_hdl ) )
|
if ( pipehandle_is_valid( keyboardh_data[dev_addr-1].pipe_hdl ) )
|
||||||
{
|
{
|
||||||
hidh_interface_close(&keyboardh_data[dev_addr-1]);
|
hidh_interface_close(&keyboardh_data[dev_addr-1]);
|
||||||
tuh_hid_keyboard_unmounted_cb(dev_addr);
|
tuh_hid_keyboard_unmounted_cb(dev_addr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_HID_MOUSE
|
#if CFG_TUH_HID_MOUSE
|
||||||
if( pipehandle_is_valid( mouseh_data[dev_addr-1].pipe_hdl ) )
|
if( pipehandle_is_valid( mouseh_data[dev_addr-1].pipe_hdl ) )
|
||||||
{
|
{
|
||||||
hidh_interface_close(&mouseh_data[dev_addr-1]);
|
hidh_interface_close(&mouseh_data[dev_addr-1]);
|
||||||
tuh_hid_mouse_unmounted_cb( dev_addr );
|
tuh_hid_mouse_unmounted_cb( dev_addr );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUSB_HOST_HID_GENERIC
|
#if CFG_TUSB_HOST_HID_GENERIC
|
||||||
hidh_generic_close(dev_addr);
|
hidh_generic_close(dev_addr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,215 +1,215 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \addtogroup ClassDriver_HID
|
/** \addtogroup ClassDriver_HID
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_HID_HOST_H_
|
#ifndef _TUSB_HID_HOST_H_
|
||||||
#define _TUSB_HID_HOST_H_
|
#define _TUSB_HID_HOST_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "host/usbh.h"
|
#include "host/usbh.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// KEYBOARD Application API
|
// KEYBOARD Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/** \addtogroup ClassDriver_HID_Keyboard Keyboard
|
/** \addtogroup ClassDriver_HID_Keyboard Keyboard
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** \defgroup Keyboard_Host Host
|
/** \defgroup Keyboard_Host Host
|
||||||
* The interface API includes status checking function, data transferring function and callback functions
|
* The interface API includes status checking function, data transferring function and callback functions
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
extern uint8_t const hid_keycode_to_ascii_tbl[2][128]; // TODO used weak attr if build failed without KEYBOARD enabled
|
extern uint8_t const hid_keycode_to_ascii_tbl[2][128]; // TODO used weak attr if build failed without KEYBOARD enabled
|
||||||
|
|
||||||
/** \brief Check if device supports Keyboard interface or not
|
/** \brief Check if device supports Keyboard interface or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if device supports Keyboard interface
|
* \retval true if device supports Keyboard interface
|
||||||
* \retval false if device does not support Keyboard interface or is not mounted
|
* \retval false if device does not support Keyboard interface or is not mounted
|
||||||
*/
|
*/
|
||||||
bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr);
|
bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Check if the interface is currently busy or not
|
/** \brief Check if the interface is currently busy or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
||||||
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
||||||
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_keyboard_get_report.
|
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_keyboard_get_report.
|
||||||
* Alternatively, asynchronous event API can be used
|
* Alternatively, asynchronous event API can be used
|
||||||
*/
|
*/
|
||||||
bool tuh_hid_keyboard_is_busy(uint8_t dev_addr);
|
bool tuh_hid_keyboard_is_busy(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Perform a get report from Keyboard interface
|
/** \brief Perform a get report from Keyboard interface
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \returns \ref tusb_error_t type to indicate success or error condition.
|
* \returns \ref tusb_error_t type to indicate success or error condition.
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
|
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void * p_report);
|
tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void * p_report);
|
||||||
|
|
||||||
//------------- Application Callback -------------//
|
//------------- Application Callback -------------//
|
||||||
/** \brief Callback function that is invoked when an transferring event occurred
|
/** \brief Callback function that is invoked when an transferring event occurred
|
||||||
* \param[in] dev_addr Address of device
|
* \param[in] dev_addr Address of device
|
||||||
* \param[in] event an value from \ref xfer_result_t
|
* \param[in] event an value from \ref xfer_result_t
|
||||||
* \note event can be one of following
|
* \note event can be one of following
|
||||||
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
||||||
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
||||||
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
||||||
* \note Application should schedule the next report by calling \ref tuh_hid_keyboard_get_report within this callback
|
* \note Application should schedule the next report by calling \ref tuh_hid_keyboard_get_report within this callback
|
||||||
*/
|
*/
|
||||||
void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event);
|
void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event);
|
||||||
|
|
||||||
/** \brief Callback function that will be invoked when a device with Keyboard interface is mounted
|
/** \brief Callback function that will be invoked when a device with Keyboard interface is mounted
|
||||||
* \param[in] dev_addr Address of newly mounted device
|
* \param[in] dev_addr Address of newly mounted device
|
||||||
* \note This callback should be used by Application to set-up interface-related data
|
* \note This callback should be used by Application to set-up interface-related data
|
||||||
*/
|
*/
|
||||||
void tuh_hid_keyboard_mounted_cb(uint8_t dev_addr);
|
void tuh_hid_keyboard_mounted_cb(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Callback function that will be invoked when a device with Keyboard interface is unmounted
|
/** \brief Callback function that will be invoked when a device with Keyboard interface is unmounted
|
||||||
* \param[in] dev_addr Address of newly unmounted device
|
* \param[in] dev_addr Address of newly unmounted device
|
||||||
* \note This callback should be used by Application to tear-down interface-related data
|
* \note This callback should be used by Application to tear-down interface-related data
|
||||||
*/
|
*/
|
||||||
void tuh_hid_keyboard_unmounted_cb(uint8_t dev_addr);
|
void tuh_hid_keyboard_unmounted_cb(uint8_t dev_addr);
|
||||||
|
|
||||||
/** @} */ // Keyboard_Host
|
/** @} */ // Keyboard_Host
|
||||||
/** @} */ // ClassDriver_HID_Keyboard
|
/** @} */ // ClassDriver_HID_Keyboard
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MOUSE Application API
|
// MOUSE Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/** \addtogroup ClassDriver_HID_Mouse Mouse
|
/** \addtogroup ClassDriver_HID_Mouse Mouse
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** \defgroup Mouse_Host Host
|
/** \defgroup Mouse_Host Host
|
||||||
* The interface API includes status checking function, data transferring function and callback functions
|
* The interface API includes status checking function, data transferring function and callback functions
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** \brief Check if device supports Mouse interface or not
|
/** \brief Check if device supports Mouse interface or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if device supports Mouse interface
|
* \retval true if device supports Mouse interface
|
||||||
* \retval false if device does not support Mouse interface or is not mounted
|
* \retval false if device does not support Mouse interface or is not mounted
|
||||||
*/
|
*/
|
||||||
bool tuh_hid_mouse_is_mounted(uint8_t dev_addr);
|
bool tuh_hid_mouse_is_mounted(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Check if the interface is currently busy or not
|
/** \brief Check if the interface is currently busy or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
||||||
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
||||||
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_mouse_get_report.
|
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_mouse_get_report.
|
||||||
* Alternatively, asynchronous event API can be used
|
* Alternatively, asynchronous event API can be used
|
||||||
*/
|
*/
|
||||||
bool tuh_hid_mouse_is_busy(uint8_t dev_addr);
|
bool tuh_hid_mouse_is_busy(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Perform a get report from Mouse interface
|
/** \brief Perform a get report from Mouse interface
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \returns \ref tusb_error_t type to indicate success or error condition.
|
* \returns \ref tusb_error_t type to indicate success or error condition.
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
|
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void* p_report);
|
tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void* p_report);
|
||||||
|
|
||||||
//------------- Application Callback -------------//
|
//------------- Application Callback -------------//
|
||||||
/** \brief Callback function that is invoked when an transferring event occurred
|
/** \brief Callback function that is invoked when an transferring event occurred
|
||||||
* \param[in] dev_addr Address of device
|
* \param[in] dev_addr Address of device
|
||||||
* \param[in] event an value from \ref xfer_result_t
|
* \param[in] event an value from \ref xfer_result_t
|
||||||
* \note event can be one of following
|
* \note event can be one of following
|
||||||
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
||||||
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
||||||
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
||||||
* \note Application should schedule the next report by calling \ref tuh_hid_mouse_get_report within this callback
|
* \note Application should schedule the next report by calling \ref tuh_hid_mouse_get_report within this callback
|
||||||
*/
|
*/
|
||||||
void tuh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event);
|
void tuh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event);
|
||||||
|
|
||||||
/** \brief Callback function that will be invoked when a device with Mouse interface is mounted
|
/** \brief Callback function that will be invoked when a device with Mouse interface is mounted
|
||||||
* \param[in] dev_addr Address of newly mounted device
|
* \param[in] dev_addr Address of newly mounted device
|
||||||
* \note This callback should be used by Application to set-up interface-related data
|
* \note This callback should be used by Application to set-up interface-related data
|
||||||
*/
|
*/
|
||||||
void tuh_hid_mouse_mounted_cb(uint8_t dev_addr);
|
void tuh_hid_mouse_mounted_cb(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Callback function that will be invoked when a device with Mouse interface is unmounted
|
/** \brief Callback function that will be invoked when a device with Mouse interface is unmounted
|
||||||
* \param[in] dev_addr Address of newly unmounted device
|
* \param[in] dev_addr Address of newly unmounted device
|
||||||
* \note This callback should be used by Application to tear-down interface-related data
|
* \note This callback should be used by Application to tear-down interface-related data
|
||||||
*/
|
*/
|
||||||
void tuh_hid_mouse_unmounted_cb(uint8_t dev_addr);
|
void tuh_hid_mouse_unmounted_cb(uint8_t dev_addr);
|
||||||
|
|
||||||
/** @} */ // Mouse_Host
|
/** @} */ // Mouse_Host
|
||||||
/** @} */ // ClassDriver_HID_Mouse
|
/** @} */ // ClassDriver_HID_Mouse
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// GENERIC Application API
|
// GENERIC Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/** \addtogroup ClassDriver_HID_Generic Generic (not supported yet)
|
/** \addtogroup ClassDriver_HID_Generic Generic (not supported yet)
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** \defgroup Generic_Host Host
|
/** \defgroup Generic_Host Host
|
||||||
* The interface API includes status checking function, data transferring function and callback functions
|
* The interface API includes status checking function, data transferring function and callback functions
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
bool tuh_hid_generic_is_mounted(uint8_t dev_addr);
|
bool tuh_hid_generic_is_mounted(uint8_t dev_addr);
|
||||||
tusb_error_t tuh_hid_generic_get_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
|
tusb_error_t tuh_hid_generic_get_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
|
||||||
tusb_error_t tuh_hid_generic_set_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
|
tusb_error_t tuh_hid_generic_set_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
|
||||||
tusb_interface_status_t tuh_hid_generic_get_status(uint8_t dev_addr);
|
tusb_interface_status_t tuh_hid_generic_get_status(uint8_t dev_addr);
|
||||||
tusb_interface_status_t tuh_hid_generic_set_status(uint8_t dev_addr);
|
tusb_interface_status_t tuh_hid_generic_set_status(uint8_t dev_addr);
|
||||||
|
|
||||||
//------------- Application Callback -------------//
|
//------------- Application Callback -------------//
|
||||||
void tuh_hid_generic_isr(uint8_t dev_addr, xfer_result_t event);
|
void tuh_hid_generic_isr(uint8_t dev_addr, xfer_result_t event);
|
||||||
|
|
||||||
/** @} */ // Generic_Host
|
/** @} */ // Generic_Host
|
||||||
/** @} */ // ClassDriver_HID_Generic
|
/** @} */ // ClassDriver_HID_Generic
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct {
|
typedef struct {
|
||||||
pipe_handle_t pipe_hdl;
|
pipe_handle_t pipe_hdl;
|
||||||
uint16_t report_size;
|
uint16_t report_size;
|
||||||
uint8_t interface_number;
|
uint8_t interface_number;
|
||||||
}hidh_interface_info_t;
|
}hidh_interface_info_t;
|
||||||
|
|
||||||
void hidh_init(void);
|
void hidh_init(void);
|
||||||
bool hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
|
bool hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
|
||||||
void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
|
void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void hidh_close(uint8_t dev_addr);
|
void hidh_close(uint8_t dev_addr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_HID_HOST_H_ */
|
#endif /* _TUSB_HID_HOST_H_ */
|
||||||
|
|
||||||
/** @} */ // ClassDriver_HID
|
/** @} */ // ClassDriver_HID
|
||||||
|
@ -1,167 +1,167 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_class
|
/** \ingroup group_class
|
||||||
* \defgroup ClassDriver_CDC Communication Device Class (CDC)
|
* \defgroup ClassDriver_CDC Communication Device Class (CDC)
|
||||||
* Currently only Abstract Control Model subclass is supported
|
* Currently only Abstract Control Model subclass is supported
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_MIDI_H__
|
#ifndef _TUSB_MIDI_H__
|
||||||
#define _TUSB_MIDI_H__
|
#define _TUSB_MIDI_H__
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Class Specific Descriptor
|
// Class Specific Descriptor
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MIDI_CS_INTERFACE_HEADER = 0x01,
|
MIDI_CS_INTERFACE_HEADER = 0x01,
|
||||||
MIDI_CS_INTERFACE_IN_JACK = 0x02,
|
MIDI_CS_INTERFACE_IN_JACK = 0x02,
|
||||||
MIDI_CS_INTERFACE_OUT_JACK = 0x03,
|
MIDI_CS_INTERFACE_OUT_JACK = 0x03,
|
||||||
MIDI_CS_INTERFACE_ELEMENT = 0x04,
|
MIDI_CS_INTERFACE_ELEMENT = 0x04,
|
||||||
} midi_cs_interface_subtype_t;
|
} midi_cs_interface_subtype_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MIDI_CS_ENDPOINT_GENERAL = 0x01
|
MIDI_CS_ENDPOINT_GENERAL = 0x01
|
||||||
} midi_cs_endpoint_subtype_t;
|
} midi_cs_endpoint_subtype_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MIDI_JACK_EMBEDDED = 0x01,
|
MIDI_JACK_EMBEDDED = 0x01,
|
||||||
MIDI_JACK_EXTERNAL = 0x02
|
MIDI_JACK_EXTERNAL = 0x02
|
||||||
} midi_jack_type_t;
|
} midi_jack_type_t;
|
||||||
|
|
||||||
/// MIDI Interface Header Descriptor
|
/// MIDI Interface Header Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
||||||
uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal
|
uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal
|
||||||
uint16_t wTotalLength ;
|
uint16_t wTotalLength ;
|
||||||
} midi_desc_header_t;
|
} midi_desc_header_t;
|
||||||
|
|
||||||
/// MIDI In Jack Descriptor
|
/// MIDI In Jack Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
||||||
uint8_t bJackType ; ///< Embedded or External
|
uint8_t bJackType ; ///< Embedded or External
|
||||||
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
|
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
|
||||||
uint8_t iJack ; ///< string descriptor
|
uint8_t iJack ; ///< string descriptor
|
||||||
} midi_desc_in_jack_t;
|
} midi_desc_in_jack_t;
|
||||||
|
|
||||||
|
|
||||||
/// MIDI Out Jack Descriptor with single pin
|
/// MIDI Out Jack Descriptor with single pin
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
||||||
uint8_t bJackType ; ///< Embedded or External
|
uint8_t bJackType ; ///< Embedded or External
|
||||||
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
|
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
|
||||||
uint8_t bNrInputPins;
|
uint8_t bNrInputPins;
|
||||||
|
|
||||||
uint8_t baSourceID;
|
uint8_t baSourceID;
|
||||||
uint8_t baSourcePin;
|
uint8_t baSourcePin;
|
||||||
|
|
||||||
uint8_t iJack ; ///< string descriptor
|
uint8_t iJack ; ///< string descriptor
|
||||||
} midi_desc_out_jack_t ;
|
} midi_desc_out_jack_t ;
|
||||||
|
|
||||||
/// MIDI Out Jack Descriptor with multiple pins
|
/// MIDI Out Jack Descriptor with multiple pins
|
||||||
#define midi_desc_out_jack_n_t(input_num) \
|
#define midi_desc_out_jack_n_t(input_num) \
|
||||||
struct TU_ATTR_PACKED { \
|
struct TU_ATTR_PACKED { \
|
||||||
uint8_t bLength ; \
|
uint8_t bLength ; \
|
||||||
uint8_t bDescriptorType ; \
|
uint8_t bDescriptorType ; \
|
||||||
uint8_t bDescriptorSubType ; \
|
uint8_t bDescriptorSubType ; \
|
||||||
uint8_t bJackType ; \
|
uint8_t bJackType ; \
|
||||||
uint8_t bJackID ; \
|
uint8_t bJackID ; \
|
||||||
uint8_t bNrInputPins ; \
|
uint8_t bNrInputPins ; \
|
||||||
struct TU_ATTR_PACKED { \
|
struct TU_ATTR_PACKED { \
|
||||||
uint8_t baSourceID; \
|
uint8_t baSourceID; \
|
||||||
uint8_t baSourcePin; \
|
uint8_t baSourcePin; \
|
||||||
} pins[input_num]; \
|
} pins[input_num]; \
|
||||||
uint8_t iJack ; \
|
uint8_t iJack ; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MIDI Element Descriptor
|
/// MIDI Element Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
||||||
uint8_t bElementID;
|
uint8_t bElementID;
|
||||||
|
|
||||||
uint8_t bNrInputPins;
|
uint8_t bNrInputPins;
|
||||||
uint8_t baSourceID;
|
uint8_t baSourceID;
|
||||||
uint8_t baSourcePin;
|
uint8_t baSourcePin;
|
||||||
|
|
||||||
uint8_t bNrOutputPins;
|
uint8_t bNrOutputPins;
|
||||||
uint8_t bInTerminalLink;
|
uint8_t bInTerminalLink;
|
||||||
uint8_t bOutTerminalLink;
|
uint8_t bOutTerminalLink;
|
||||||
uint8_t bElCapsSize;
|
uint8_t bElCapsSize;
|
||||||
|
|
||||||
uint16_t bmElementCaps;
|
uint16_t bmElementCaps;
|
||||||
uint8_t iElement;
|
uint8_t iElement;
|
||||||
} midi_desc_element_t;
|
} midi_desc_element_t;
|
||||||
|
|
||||||
/// MIDI Element Descriptor with multiple pins
|
/// MIDI Element Descriptor with multiple pins
|
||||||
#define midi_desc_element_n_t(input_num) \
|
#define midi_desc_element_n_t(input_num) \
|
||||||
struct TU_ATTR_PACKED { \
|
struct TU_ATTR_PACKED { \
|
||||||
uint8_t bLength; \
|
uint8_t bLength; \
|
||||||
uint8_t bDescriptorType; \
|
uint8_t bDescriptorType; \
|
||||||
uint8_t bDescriptorSubType; \
|
uint8_t bDescriptorSubType; \
|
||||||
uint8_t bElementID; \
|
uint8_t bElementID; \
|
||||||
uint8_t bNrInputPins; \
|
uint8_t bNrInputPins; \
|
||||||
struct TU_ATTR_PACKED { \
|
struct TU_ATTR_PACKED { \
|
||||||
uint8_t baSourceID; \
|
uint8_t baSourceID; \
|
||||||
uint8_t baSourcePin; \
|
uint8_t baSourcePin; \
|
||||||
} pins[input_num]; \
|
} pins[input_num]; \
|
||||||
uint8_t bNrOutputPins; \
|
uint8_t bNrOutputPins; \
|
||||||
uint8_t bInTerminalLink; \
|
uint8_t bInTerminalLink; \
|
||||||
uint8_t bOutTerminalLink; \
|
uint8_t bOutTerminalLink; \
|
||||||
uint8_t bElCapsSize; \
|
uint8_t bElCapsSize; \
|
||||||
uint16_t bmElementCaps; \
|
uint16_t bmElementCaps; \
|
||||||
uint8_t iElement; \
|
uint8_t iElement; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,355 +1,361 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_MIDI)
|
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_MIDI)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INCLUDE
|
// INCLUDE
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#include "midi_device.h"
|
#include "midi_device.h"
|
||||||
#include "class/audio/audio.h"
|
#include "class/audio/audio.h"
|
||||||
#include "device/usbd_pvt.h"
|
#include "device/usbd_pvt.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t itf_num;
|
uint8_t itf_num;
|
||||||
uint8_t ep_in;
|
uint8_t ep_in;
|
||||||
uint8_t ep_out;
|
uint8_t ep_out;
|
||||||
|
|
||||||
/*------------- From this point, data is not cleared by bus reset -------------*/
|
/*------------- From this point, data is not cleared by bus reset -------------*/
|
||||||
// FIFO
|
// FIFO
|
||||||
tu_fifo_t rx_ff;
|
tu_fifo_t rx_ff;
|
||||||
tu_fifo_t tx_ff;
|
tu_fifo_t tx_ff;
|
||||||
uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE];
|
uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE];
|
||||||
uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE];
|
uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE];
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
osal_mutex_def_t rx_ff_mutex;
|
osal_mutex_def_t rx_ff_mutex;
|
||||||
osal_mutex_def_t tx_ff_mutex;
|
osal_mutex_def_t tx_ff_mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We need to pack messages into words before queueing their transmission so buffer across write
|
// We need to pack messages into words before queueing their transmission so buffer across write
|
||||||
// calls.
|
// calls.
|
||||||
uint8_t message_buffer[4];
|
uint8_t message_buffer[4];
|
||||||
uint8_t message_buffer_length;
|
uint8_t message_buffer_length;
|
||||||
uint8_t message_target_length;
|
uint8_t message_target_length;
|
||||||
|
|
||||||
// Endpoint Transfer buffer
|
// Endpoint Transfer buffer
|
||||||
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EPSIZE];
|
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EPSIZE];
|
||||||
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EPSIZE];
|
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EPSIZE];
|
||||||
|
|
||||||
} midid_interface_t;
|
} midid_interface_t;
|
||||||
|
|
||||||
#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff)
|
#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
CFG_TUSB_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
|
CFG_TUSB_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
|
||||||
|
|
||||||
bool tud_midi_n_mounted (uint8_t itf)
|
bool tud_midi_n_mounted (uint8_t itf)
|
||||||
{
|
{
|
||||||
midid_interface_t* midi = &_midid_itf[itf];
|
midid_interface_t* midi = &_midid_itf[itf];
|
||||||
return midi->ep_in && midi->ep_out;
|
return midi->ep_in && midi->ep_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// READ API
|
// READ API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
uint32_t tud_midi_n_available(uint8_t itf, uint8_t jack_id)
|
uint32_t tud_midi_n_available(uint8_t itf, uint8_t jack_id)
|
||||||
{
|
{
|
||||||
(void) jack_id;
|
(void) jack_id;
|
||||||
return tu_fifo_count(&_midid_itf[itf].rx_ff);
|
return tu_fifo_count(&_midid_itf[itf].rx_ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tud_midi_n_read(uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize)
|
uint32_t tud_midi_n_read(uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
(void) jack_id;
|
(void) jack_id;
|
||||||
return tu_fifo_read_n(&_midid_itf[itf].rx_ff, buffer, bufsize);
|
return tu_fifo_read_n(&_midid_itf[itf].rx_ff, buffer, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id)
|
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id)
|
||||||
{
|
{
|
||||||
(void) jack_id;
|
(void) jack_id;
|
||||||
tu_fifo_clear(&_midid_itf[itf].rx_ff);
|
tu_fifo_clear(&_midid_itf[itf].rx_ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
|
void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
|
||||||
if (bufsize % 4 != 0) {
|
if (bufsize % 4 != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint32_t i=0; i<bufsize; i += 4) {
|
for(uint32_t i=0; i<bufsize; i += 4) {
|
||||||
uint8_t header = buffer[i];
|
uint8_t header = buffer[i];
|
||||||
// uint8_t cable_number = (header & 0xf0) >> 4;
|
// uint8_t cable_number = (header & 0xf0) >> 4;
|
||||||
uint8_t code_index = header & 0x0f;
|
uint8_t code_index = header & 0x0f;
|
||||||
// We always copy over the first byte.
|
// We always copy over the first byte.
|
||||||
uint8_t count = 1;
|
uint8_t count = 1;
|
||||||
// Ignore subsequent bytes based on the code.
|
// Ignore subsequent bytes based on the code.
|
||||||
if (code_index != 0x5 && code_index != 0xf) {
|
if (code_index != 0x5 && code_index != 0xf) {
|
||||||
count = 2;
|
count = 2;
|
||||||
if (code_index != 0x2 && code_index != 0x6 && code_index != 0xc && code_index != 0xd) {
|
if (code_index != 0x2 && code_index != 0x6 && code_index != 0xc && code_index != 0xd) {
|
||||||
count = 3;
|
count = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tu_fifo_write_n(&midi->rx_ff, &buffer[i + 1], count);
|
tu_fifo_write_n(&midi->rx_ff, &buffer[i + 1], count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// WRITE API
|
// WRITE API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
static bool maybe_transmit(midid_interface_t* midi, uint8_t itf_index)
|
static bool maybe_transmit(midid_interface_t* midi, uint8_t itf_index)
|
||||||
{
|
{
|
||||||
(void) itf_index;
|
(void) itf_index;
|
||||||
|
|
||||||
// skip if previous transfer not complete
|
// skip if previous transfer not complete
|
||||||
TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, midi->ep_in) );
|
TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, midi->ep_in) );
|
||||||
|
|
||||||
uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EPSIZE);
|
uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EPSIZE);
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, midi->ep_in, midi->epin_buf, count) );
|
TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, midi->ep_in, midi->epin_buf, count) );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tud_midi_n_write(uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize)
|
uint32_t tud_midi_n_write(uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
midid_interface_t* midi = &_midid_itf[itf];
|
midid_interface_t* midi = &_midid_itf[itf];
|
||||||
if (midi->itf_num == 0) {
|
if (midi->itf_num == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while (i < bufsize) {
|
while (i < bufsize) {
|
||||||
uint8_t data = buffer[i];
|
uint8_t data = buffer[i];
|
||||||
if (midi->message_buffer_length == 0) {
|
if (midi->message_buffer_length == 0) {
|
||||||
uint8_t msg = data >> 4;
|
uint8_t msg = data >> 4;
|
||||||
midi->message_buffer[1] = data;
|
midi->message_buffer[1] = data;
|
||||||
midi->message_buffer_length = 2;
|
midi->message_buffer_length = 2;
|
||||||
// Check to see if we're still in a SysEx transmit.
|
// Check to see if we're still in a SysEx transmit.
|
||||||
if (midi->message_buffer[0] == 0x4) {
|
if (midi->message_buffer[0] == 0x4) {
|
||||||
if (data == 0xf7) {
|
if (data == 0xf7) {
|
||||||
midi->message_buffer[0] = 0x5;
|
midi->message_buffer[0] = 0x5;
|
||||||
} else {
|
} else {
|
||||||
midi->message_buffer_length = 4;
|
midi->message_buffer_length = 4;
|
||||||
}
|
}
|
||||||
} else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) {
|
} else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) {
|
||||||
midi->message_buffer[0] = jack_id << 4 | msg;
|
midi->message_buffer[0] = jack_id << 4 | msg;
|
||||||
midi->message_target_length = 4;
|
midi->message_target_length = 4;
|
||||||
} else if (msg == 0xC || msg == 0xD) {
|
} else if (msg == 0xC || msg == 0xD) {
|
||||||
midi->message_buffer[0] = jack_id << 4 | msg;
|
midi->message_buffer[0] = jack_id << 4 | msg;
|
||||||
midi->message_target_length = 3;
|
midi->message_target_length = 3;
|
||||||
} else if (msg == 0xf) {
|
} else if (msg == 0xf) {
|
||||||
if (data == 0xf0) {
|
if (data == 0xf0) {
|
||||||
midi->message_buffer[0] = 0x4;
|
midi->message_buffer[0] = 0x4;
|
||||||
midi->message_target_length = 4;
|
midi->message_target_length = 4;
|
||||||
} else if (data == 0xf1 || data == 0xf3) {
|
} else if (data == 0xf1 || data == 0xf3) {
|
||||||
midi->message_buffer[0] = 0x2;
|
midi->message_buffer[0] = 0x2;
|
||||||
midi->message_target_length = 3;
|
midi->message_target_length = 3;
|
||||||
} else if (data == 0xf2) {
|
} else if (data == 0xf2) {
|
||||||
midi->message_buffer[0] = 0x3;
|
midi->message_buffer[0] = 0x3;
|
||||||
midi->message_target_length = 4;
|
midi->message_target_length = 4;
|
||||||
} else {
|
} else {
|
||||||
midi->message_buffer[0] = 0x5;
|
midi->message_buffer[0] = 0x5;
|
||||||
midi->message_target_length = 2;
|
midi->message_target_length = 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Pack individual bytes if we don't support packing them into words.
|
// Pack individual bytes if we don't support packing them into words.
|
||||||
midi->message_buffer[0] = jack_id << 4 | 0xf;
|
midi->message_buffer[0] = jack_id << 4 | 0xf;
|
||||||
midi->message_buffer[2] = 0;
|
midi->message_buffer[2] = 0;
|
||||||
midi->message_buffer[3] = 0;
|
midi->message_buffer[3] = 0;
|
||||||
midi->message_buffer_length = 2;
|
midi->message_buffer_length = 2;
|
||||||
midi->message_target_length = 2;
|
midi->message_target_length = 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
midi->message_buffer[midi->message_buffer_length] = data;
|
midi->message_buffer[midi->message_buffer_length] = data;
|
||||||
midi->message_buffer_length += 1;
|
midi->message_buffer_length += 1;
|
||||||
// See if this byte ends a SysEx.
|
// See if this byte ends a SysEx.
|
||||||
if (midi->message_buffer[0] == 0x4 && data == 0xf7) {
|
if (midi->message_buffer[0] == 0x4 && data == 0xf7) {
|
||||||
midi->message_buffer[0] = 0x4 + (midi->message_buffer_length - 1);
|
midi->message_buffer[0] = 0x4 + (midi->message_buffer_length - 1);
|
||||||
midi->message_target_length = midi->message_buffer_length;
|
midi->message_target_length = midi->message_buffer_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (midi->message_buffer_length == midi->message_target_length) {
|
if (midi->message_buffer_length == midi->message_target_length) {
|
||||||
uint16_t written = tu_fifo_write_n(&midi->tx_ff, midi->message_buffer, 4);
|
uint16_t written = tu_fifo_write_n(&midi->tx_ff, midi->message_buffer, 4);
|
||||||
if (written < 4) {
|
if (written < 4) {
|
||||||
TU_ASSERT( written == 0 );
|
TU_ASSERT( written == 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
midi->message_buffer_length = 0;
|
midi->message_buffer_length = 0;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
maybe_transmit(midi, itf);
|
maybe_transmit(midi, itf);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBD Driver API
|
// USBD Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void midid_init(void)
|
void midid_init(void)
|
||||||
{
|
{
|
||||||
tu_memclr(_midid_itf, sizeof(_midid_itf));
|
tu_memclr(_midid_itf, sizeof(_midid_itf));
|
||||||
|
|
||||||
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
||||||
{
|
{
|
||||||
midid_interface_t* midi = &_midid_itf[i];
|
midid_interface_t* midi = &_midid_itf[i];
|
||||||
|
|
||||||
// config fifo
|
// config fifo
|
||||||
tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, true);
|
tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, true);
|
||||||
tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, true);
|
tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, true);
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
tu_fifo_config_mutex(&midi->rx_ff, osal_mutex_create(&midi->rx_ff_mutex));
|
tu_fifo_config_mutex(&midi->rx_ff, osal_mutex_create(&midi->rx_ff_mutex));
|
||||||
tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex));
|
tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void midid_reset(uint8_t rhport)
|
void midid_reset(uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
||||||
{
|
{
|
||||||
midid_interface_t* midi = &_midid_itf[i];
|
midid_interface_t* midi = &_midid_itf[i];
|
||||||
tu_memclr(midi, ITF_MEM_RESET_SIZE);
|
tu_memclr(midi, ITF_MEM_RESET_SIZE);
|
||||||
tu_fifo_clear(&midi->rx_ff);
|
tu_fifo_clear(&midi->rx_ff);
|
||||||
tu_fifo_clear(&midi->tx_ff);
|
tu_fifo_clear(&midi->tx_ff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
|
bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
// For now handle the audio control interface as well.
|
// For now handle the audio control interface as well.
|
||||||
if ( AUDIO_SUBCLASS_CONTROL == p_interface_desc->bInterfaceSubClass) {
|
if ( AUDIO_SUBCLASS_CONTROL == p_interface_desc->bInterfaceSubClass) {
|
||||||
uint8_t const * p_desc = tu_desc_next ( (uint8_t const *) p_interface_desc );
|
uint8_t const * p_desc = tu_desc_next ( (uint8_t const *) p_interface_desc );
|
||||||
(*p_length) = sizeof(tusb_desc_interface_t);
|
(*p_length) = sizeof(tusb_desc_interface_t);
|
||||||
|
|
||||||
// Skip over the class specific descriptor.
|
// Skip over the class specific descriptor.
|
||||||
(*p_length) += tu_desc_len(p_desc);
|
(*p_length) += tu_desc_len(p_desc);
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == p_interface_desc->bInterfaceSubClass &&
|
TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == p_interface_desc->bInterfaceSubClass &&
|
||||||
AUDIO_PROTOCOL_V1 == p_interface_desc->bInterfaceProtocol );
|
AUDIO_PROTOCOL_V1 == p_interface_desc->bInterfaceProtocol );
|
||||||
|
|
||||||
// Find available interface
|
// Find available interface
|
||||||
midid_interface_t * p_midi = NULL;
|
midid_interface_t * p_midi = NULL;
|
||||||
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
||||||
{
|
{
|
||||||
if ( _midid_itf[i].ep_in == 0 && _midid_itf[i].ep_out == 0 )
|
if ( _midid_itf[i].ep_in == 0 && _midid_itf[i].ep_out == 0 )
|
||||||
{
|
{
|
||||||
p_midi = &_midid_itf[i];
|
p_midi = &_midid_itf[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p_midi->itf_num = p_interface_desc->bInterfaceNumber;
|
p_midi->itf_num = p_interface_desc->bInterfaceNumber;
|
||||||
|
|
||||||
uint8_t const * p_desc = tu_desc_next( (uint8_t const *) p_interface_desc );
|
uint8_t const * p_desc = tu_desc_next( (uint8_t const *) p_interface_desc );
|
||||||
(*p_length) = sizeof(tusb_desc_interface_t);
|
(*p_length) = sizeof(tusb_desc_interface_t);
|
||||||
|
|
||||||
uint8_t found_endpoints = 0;
|
uint8_t found_endpoints = 0;
|
||||||
while (found_endpoints < p_interface_desc->bNumEndpoints)
|
while (found_endpoints < p_interface_desc->bNumEndpoints)
|
||||||
{
|
{
|
||||||
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
||||||
{
|
{
|
||||||
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), false);
|
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), false);
|
||||||
uint8_t ep_addr = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
uint8_t ep_addr = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
||||||
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
p_midi->ep_in = ep_addr;
|
p_midi->ep_in = ep_addr;
|
||||||
} else {
|
} else {
|
||||||
p_midi->ep_out = ep_addr;
|
p_midi->ep_out = ep_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
found_endpoints += 1;
|
found_endpoints += 1;
|
||||||
}
|
}
|
||||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for incoming data
|
// Prepare for incoming data
|
||||||
TU_ASSERT( usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false);
|
TU_ASSERT( usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool midid_control_complete(uint8_t rhport, tusb_control_request_t const * p_request)
|
bool midid_control_complete(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) p_request;
|
(void) p_request;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool midid_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
|
bool midid_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) p_request;
|
(void) p_request;
|
||||||
|
|
||||||
// driver doesn't support any request yet
|
// driver doesn't support any request yet
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
(void) result;
|
(void) result;
|
||||||
|
|
||||||
// TODO Support multiple interfaces
|
uint8_t itf = 0;
|
||||||
uint8_t const itf = 0;
|
midid_interface_t* p_midi = _midid_itf;
|
||||||
midid_interface_t* p_midi = &_midid_itf[itf];
|
|
||||||
|
for ( ; ; itf++, p_midi++)
|
||||||
// receive new data
|
{
|
||||||
if ( ep_addr == p_midi->ep_out )
|
if (itf >= TU_ARRAY_SIZE(_midid_itf)) return false;
|
||||||
{
|
|
||||||
midi_rx_done_cb(p_midi, p_midi->epout_buf, xferred_bytes);
|
if ( ep_addr == p_midi->ep_out ) break;
|
||||||
|
}
|
||||||
// prepare for next
|
|
||||||
TU_ASSERT( usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false );
|
// receive new data
|
||||||
} else if ( ep_addr == p_midi->ep_in ) {
|
if ( ep_addr == p_midi->ep_out )
|
||||||
maybe_transmit(p_midi, itf);
|
{
|
||||||
}
|
midi_rx_done_cb(p_midi, p_midi->epout_buf, xferred_bytes);
|
||||||
|
|
||||||
// nothing to do with in and notif endpoint
|
// prepare for next
|
||||||
|
TU_ASSERT( usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false );
|
||||||
return TUSB_ERROR_NONE;
|
} else if ( ep_addr == p_midi->ep_in ) {
|
||||||
}
|
maybe_transmit(p_midi, itf);
|
||||||
|
}
|
||||||
#endif
|
|
||||||
|
// nothing to do with in and notif endpoint
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,138 +1,138 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_MIDI_DEVICE_H_
|
#ifndef _TUSB_MIDI_DEVICE_H_
|
||||||
#define _TUSB_MIDI_DEVICE_H_
|
#define _TUSB_MIDI_DEVICE_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "device/usbd.h"
|
#include "device/usbd.h"
|
||||||
|
|
||||||
#include "class/audio/audio.h"
|
#include "class/audio/audio.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Class Driver Configuration
|
// Class Driver Configuration
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#ifndef CFG_TUD_MIDI_EPSIZE
|
#ifndef CFG_TUD_MIDI_EPSIZE
|
||||||
#define CFG_TUD_MIDI_EPSIZE 64
|
#define CFG_TUD_MIDI_EPSIZE 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \addtogroup MIDI_Serial Serial
|
/** \addtogroup MIDI_Serial Serial
|
||||||
* @{
|
* @{
|
||||||
* \defgroup MIDI_Serial_Device Device
|
* \defgroup MIDI_Serial_Device Device
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API (Multiple Interfaces)
|
// Application API (Multiple Interfaces)
|
||||||
// CFG_TUD_MIDI > 1
|
// CFG_TUD_MIDI > 1
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool tud_midi_n_mounted (uint8_t itf);
|
bool tud_midi_n_mounted (uint8_t itf);
|
||||||
uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id);
|
uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id);
|
||||||
uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize);
|
uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize);
|
||||||
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id);
|
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id);
|
||||||
uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize);
|
uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize);
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3);
|
uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API (Interface0)
|
// Application API (Interface0)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline bool tud_midi_mounted (void);
|
static inline bool tud_midi_mounted (void);
|
||||||
static inline uint32_t tud_midi_available (void);
|
static inline uint32_t tud_midi_available (void);
|
||||||
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize);
|
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize);
|
||||||
static inline void tud_midi_read_flush (void);
|
static inline void tud_midi_read_flush (void);
|
||||||
static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize);
|
static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize);
|
||||||
static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3);
|
static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application Callback API (weak is optional)
|
// Application Callback API (weak is optional)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf);
|
TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Inline Functions
|
// Inline Functions
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3)
|
static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3)
|
||||||
{
|
{
|
||||||
uint8_t msg[3] = { b1, b2, b3 };
|
uint8_t msg[3] = { b1, b2, b3 };
|
||||||
return tud_midi_n_write(itf, jack_id, msg, 3);
|
return tud_midi_n_write(itf, jack_id, msg, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tud_midi_mounted (void)
|
static inline bool tud_midi_mounted (void)
|
||||||
{
|
{
|
||||||
return tud_midi_n_mounted(0);
|
return tud_midi_n_mounted(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_midi_available (void)
|
static inline uint32_t tud_midi_available (void)
|
||||||
{
|
{
|
||||||
return tud_midi_n_available(0, 0);
|
return tud_midi_n_available(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize)
|
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
return tud_midi_n_read(0, 0, buffer, bufsize);
|
return tud_midi_n_read(0, 0, buffer, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tud_midi_read_flush (void)
|
static inline void tud_midi_read_flush (void)
|
||||||
{
|
{
|
||||||
tud_midi_n_read_flush(0, 0);
|
tud_midi_n_read_flush(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize)
|
static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
return tud_midi_n_write(0, jack_id, buffer, bufsize);
|
return tud_midi_n_write(0, jack_id, buffer, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3)
|
static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3)
|
||||||
{
|
{
|
||||||
uint8_t msg[3] = { b1, b2, b3 };
|
uint8_t msg[3] = { b1, b2, b3 };
|
||||||
return tud_midi_write(jack_id, msg, 3);
|
return tud_midi_write(jack_id, msg, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void midid_init (void);
|
void midid_init (void);
|
||||||
void midid_reset (uint8_t rhport);
|
void midid_reset (uint8_t rhport);
|
||||||
bool midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
bool midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||||
bool midid_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
bool midid_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool midid_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
bool midid_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
||||||
bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
|
bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_MIDI_DEVICE_H_ */
|
#endif /* _TUSB_MIDI_DEVICE_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,392 +1,392 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_class
|
/** \ingroup group_class
|
||||||
* \defgroup ClassDriver_MSC MassStorage (MSC)
|
* \defgroup ClassDriver_MSC MassStorage (MSC)
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** \defgroup ClassDriver_MSC_Common Common Definitions
|
/** \defgroup ClassDriver_MSC_Common Common Definitions
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_MSC_H_
|
#ifndef _TUSB_MSC_H_
|
||||||
#define _TUSB_MSC_H_
|
#define _TUSB_MSC_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Mass Storage Class Constant
|
// Mass Storage Class Constant
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/// MassStorage Subclass
|
/// MassStorage Subclass
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MSC_SUBCLASS_RBC = 1 , ///< Reduced Block Commands (RBC) T10 Project 1240-D
|
MSC_SUBCLASS_RBC = 1 , ///< Reduced Block Commands (RBC) T10 Project 1240-D
|
||||||
MSC_SUBCLASS_SFF_MMC , ///< SFF-8020i, MMC-2 (ATAPI). Typically used by a CD/DVD device
|
MSC_SUBCLASS_SFF_MMC , ///< SFF-8020i, MMC-2 (ATAPI). Typically used by a CD/DVD device
|
||||||
MSC_SUBCLASS_QIC , ///< QIC-157. Typically used by a tape device
|
MSC_SUBCLASS_QIC , ///< QIC-157. Typically used by a tape device
|
||||||
MSC_SUBCLASS_UFI , ///< UFI. Typically used by Floppy Disk Drive (FDD) device
|
MSC_SUBCLASS_UFI , ///< UFI. Typically used by Floppy Disk Drive (FDD) device
|
||||||
MSC_SUBCLASS_SFF , ///< SFF-8070i. Can be used by Floppy Disk Drive (FDD) device
|
MSC_SUBCLASS_SFF , ///< SFF-8070i. Can be used by Floppy Disk Drive (FDD) device
|
||||||
MSC_SUBCLASS_SCSI ///< SCSI transparent command set
|
MSC_SUBCLASS_SCSI ///< SCSI transparent command set
|
||||||
}msc_subclass_type_t;
|
}msc_subclass_type_t;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MSC_CBW_SIGNATURE = 0x43425355, ///< Constant value of 43425355h (little endian)
|
MSC_CBW_SIGNATURE = 0x43425355, ///< Constant value of 43425355h (little endian)
|
||||||
MSC_CSW_SIGNATURE = 0x53425355 ///< Constant value of 53425355h (little endian)
|
MSC_CSW_SIGNATURE = 0x53425355 ///< Constant value of 53425355h (little endian)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief MassStorage Protocol.
|
/// \brief MassStorage Protocol.
|
||||||
/// \details CBI only approved to use with full-speed floopy disk & should not used with highspeed or device other than floopy
|
/// \details CBI only approved to use with full-speed floopy disk & should not used with highspeed or device other than floopy
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt)
|
MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt)
|
||||||
MSC_PROTOCOL_CBI_NO_INTERRUPT = 1 , ///< Control/Bulk/Interrupt protocol (without command completion interrupt)
|
MSC_PROTOCOL_CBI_NO_INTERRUPT = 1 , ///< Control/Bulk/Interrupt protocol (without command completion interrupt)
|
||||||
MSC_PROTOCOL_BOT = 0x50 ///< Bulk-Only Transport
|
MSC_PROTOCOL_BOT = 0x50 ///< Bulk-Only Transport
|
||||||
}msc_protocol_type_t;
|
}msc_protocol_type_t;
|
||||||
|
|
||||||
/// MassStorage Class-Specific Control Request
|
/// MassStorage Class-Specific Control Request
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MSC_REQ_GET_MAX_LUN = 254, ///< The Get Max LUN device request is used to determine the number of logical units supported by the device. Logical Unit Numbers on the device shall be numbered contiguously starting from LUN 0 to a maximum LUN of 15
|
MSC_REQ_GET_MAX_LUN = 254, ///< The Get Max LUN device request is used to determine the number of logical units supported by the device. Logical Unit Numbers on the device shall be numbered contiguously starting from LUN 0 to a maximum LUN of 15
|
||||||
MSC_REQ_RESET = 255 ///< This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host.
|
MSC_REQ_RESET = 255 ///< This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host.
|
||||||
}msc_request_type_t;
|
}msc_request_type_t;
|
||||||
|
|
||||||
/// \brief Command Block Status Values
|
/// \brief Command Block Status Values
|
||||||
/// \details Indicates the success or failure of the command. The device shall set this byte to zero if the command completed
|
/// \details Indicates the success or failure of the command. The device shall set this byte to zero if the command completed
|
||||||
/// successfully. A non-zero value shall indicate a failure during command execution according to the following
|
/// successfully. A non-zero value shall indicate a failure during command execution according to the following
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MSC_CSW_STATUS_PASSED = 0 , ///< MSC_CSW_STATUS_PASSED
|
MSC_CSW_STATUS_PASSED = 0 , ///< MSC_CSW_STATUS_PASSED
|
||||||
MSC_CSW_STATUS_FAILED , ///< MSC_CSW_STATUS_FAILED
|
MSC_CSW_STATUS_FAILED , ///< MSC_CSW_STATUS_FAILED
|
||||||
MSC_CSW_STATUS_PHASE_ERROR ///< MSC_CSW_STATUS_PHASE_ERROR
|
MSC_CSW_STATUS_PHASE_ERROR ///< MSC_CSW_STATUS_PHASE_ERROR
|
||||||
}msc_csw_status_t;
|
}msc_csw_status_t;
|
||||||
|
|
||||||
/// Command Block Wrapper
|
/// Command Block Wrapper
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint32_t signature; ///< Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW.
|
uint32_t signature; ///< Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW.
|
||||||
uint32_t tag; ///< Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW.
|
uint32_t tag; ///< Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW.
|
||||||
uint32_t total_bytes; ///< The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags.
|
uint32_t total_bytes; ///< The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags.
|
||||||
uint8_t dir; ///< Bit 7 of this field define transfer direction \n - 0 : Data-Out from host to the device. \n - 1 : Data-In from the device to the host.
|
uint8_t dir; ///< Bit 7 of this field define transfer direction \n - 0 : Data-Out from host to the device. \n - 1 : Data-In from the device to the host.
|
||||||
uint8_t lun; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero.
|
uint8_t lun; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero.
|
||||||
uint8_t cmd_len; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16
|
uint8_t cmd_len; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16
|
||||||
uint8_t command[16]; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block
|
uint8_t command[16]; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block
|
||||||
}msc_cbw_t;
|
}msc_cbw_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct");
|
||||||
|
|
||||||
/// Command Status Wrapper
|
/// Command Status Wrapper
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW.
|
uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW.
|
||||||
uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW.
|
uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW.
|
||||||
uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
|
uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
|
||||||
uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t
|
uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t
|
||||||
}msc_csw_t;
|
}msc_csw_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct");
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// SCSI Constant
|
// SCSI Constant
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// SCSI Command Operation Code
|
/// SCSI Command Operation Code
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation.
|
SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation.
|
||||||
SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device.
|
SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device.
|
||||||
SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters.
|
SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters.
|
||||||
SCSI_CMD_MODE_SENSE_6 = 0x1A, ///< provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command.
|
SCSI_CMD_MODE_SENSE_6 = 0x1A, ///< provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command.
|
||||||
SCSI_CMD_START_STOP_UNIT = 0x1B,
|
SCSI_CMD_START_STOP_UNIT = 0x1B,
|
||||||
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
|
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
|
||||||
SCSI_CMD_READ_CAPACITY_10 = 0x25, ///< The SCSI Read Capacity command is used to obtain data capacity information from a target device.
|
SCSI_CMD_READ_CAPACITY_10 = 0x25, ///< The SCSI Read Capacity command is used to obtain data capacity information from a target device.
|
||||||
SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device.
|
SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device.
|
||||||
SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed
|
SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed
|
||||||
SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer.
|
SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer.
|
||||||
SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from the data-out buffer and write them.
|
SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from the data-out buffer and write them.
|
||||||
}scsi_cmd_type_t;
|
}scsi_cmd_type_t;
|
||||||
|
|
||||||
/// SCSI Sense Key
|
/// SCSI Sense Key
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command
|
SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command
|
||||||
SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< ndicates the last command completed successfully with some recovery action performed by the disc drive.
|
SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< ndicates the last command completed successfully with some recovery action performed by the disc drive.
|
||||||
SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed.
|
SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed.
|
||||||
SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition.
|
SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition.
|
||||||
SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test.
|
SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test.
|
||||||
SCSI_SENSE_ILLEGAL_REQUEST = 0x05, ///< Indicates an illegal parameter in the command descriptor block or in the additional parameters
|
SCSI_SENSE_ILLEGAL_REQUEST = 0x05, ///< Indicates an illegal parameter in the command descriptor block or in the additional parameters
|
||||||
SCSI_SENSE_UNIT_ATTENTION = 0x06, ///< Indicates the disc drive may have been reset.
|
SCSI_SENSE_UNIT_ATTENTION = 0x06, ///< Indicates the disc drive may have been reset.
|
||||||
SCSI_SENSE_DATA_PROTECT = 0x07, ///< Indicates that a command that reads or writes the medium was attempted on a block that is protected from this operation. The read or write operation is not performed.
|
SCSI_SENSE_DATA_PROTECT = 0x07, ///< Indicates that a command that reads or writes the medium was attempted on a block that is protected from this operation. The read or write operation is not performed.
|
||||||
SCSI_SENSE_FIRMWARE_ERROR = 0x08, ///< Vendor specific sense key.
|
SCSI_SENSE_FIRMWARE_ERROR = 0x08, ///< Vendor specific sense key.
|
||||||
SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command.
|
SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command.
|
||||||
SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison.
|
SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison.
|
||||||
SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium.
|
SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium.
|
||||||
SCSI_SENSE_MISCOMPARE = 0x0e ///< ndicates that the source data did not match the data read from the medium.
|
SCSI_SENSE_MISCOMPARE = 0x0e ///< ndicates that the source data did not match the data read from the medium.
|
||||||
}scsi_sense_key_type_t;
|
}scsi_sense_key_type_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// SCSI Primary Command (SPC-4)
|
// SCSI Primary Command (SPC-4)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// SCSI Test Unit Ready Command
|
/// SCSI Test Unit Ready Command
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY
|
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY
|
||||||
uint8_t lun ; ///< Logical Unit
|
uint8_t lun ; ///< Logical Unit
|
||||||
uint8_t reserved[3] ;
|
uint8_t reserved[3] ;
|
||||||
uint8_t control ;
|
uint8_t control ;
|
||||||
} scsi_test_unit_ready_t;
|
} scsi_test_unit_ready_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct");
|
||||||
|
|
||||||
/// SCSI Inquiry Command
|
/// SCSI Inquiry Command
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY
|
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY
|
||||||
uint8_t reserved1 ;
|
uint8_t reserved1 ;
|
||||||
uint8_t page_code ;
|
uint8_t page_code ;
|
||||||
uint8_t reserved2 ;
|
uint8_t reserved2 ;
|
||||||
uint8_t alloc_length ; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred.
|
uint8_t alloc_length ; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred.
|
||||||
uint8_t control ;
|
uint8_t control ;
|
||||||
} scsi_inquiry_t, scsi_request_sense_t;
|
} scsi_inquiry_t, scsi_request_sense_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct");
|
||||||
|
|
||||||
/// SCSI Inquiry Response Data
|
/// SCSI Inquiry Response Data
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t peripheral_device_type : 5;
|
uint8_t peripheral_device_type : 5;
|
||||||
uint8_t peripheral_qualifier : 3;
|
uint8_t peripheral_qualifier : 3;
|
||||||
|
|
||||||
uint8_t : 7;
|
uint8_t : 7;
|
||||||
uint8_t is_removable : 1;
|
uint8_t is_removable : 1;
|
||||||
|
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
|
||||||
uint8_t response_data_format : 4;
|
uint8_t response_data_format : 4;
|
||||||
uint8_t hierarchical_support : 1;
|
uint8_t hierarchical_support : 1;
|
||||||
uint8_t normal_aca : 1;
|
uint8_t normal_aca : 1;
|
||||||
uint8_t : 2;
|
uint8_t : 2;
|
||||||
|
|
||||||
uint8_t additional_length;
|
uint8_t additional_length;
|
||||||
|
|
||||||
uint8_t protect : 1;
|
uint8_t protect : 1;
|
||||||
uint8_t : 2;
|
uint8_t : 2;
|
||||||
uint8_t third_party_copy : 1;
|
uint8_t third_party_copy : 1;
|
||||||
uint8_t target_port_group_support : 2;
|
uint8_t target_port_group_support : 2;
|
||||||
uint8_t access_control_coordinator : 1;
|
uint8_t access_control_coordinator : 1;
|
||||||
uint8_t scc_support : 1;
|
uint8_t scc_support : 1;
|
||||||
|
|
||||||
uint8_t addr16 : 1;
|
uint8_t addr16 : 1;
|
||||||
uint8_t : 3;
|
uint8_t : 3;
|
||||||
uint8_t multi_port : 1;
|
uint8_t multi_port : 1;
|
||||||
uint8_t : 1; // vendor specific
|
uint8_t : 1; // vendor specific
|
||||||
uint8_t enclosure_service : 1;
|
uint8_t enclosure_service : 1;
|
||||||
uint8_t : 1;
|
uint8_t : 1;
|
||||||
|
|
||||||
uint8_t : 1; // vendor specific
|
uint8_t : 1; // vendor specific
|
||||||
uint8_t cmd_que : 1;
|
uint8_t cmd_que : 1;
|
||||||
uint8_t : 2;
|
uint8_t : 2;
|
||||||
uint8_t sync : 1;
|
uint8_t sync : 1;
|
||||||
uint8_t wbus16 : 1;
|
uint8_t wbus16 : 1;
|
||||||
uint8_t : 2;
|
uint8_t : 2;
|
||||||
|
|
||||||
uint8_t vendor_id[8] ; ///< 8 bytes of ASCII data identifying the vendor of the product.
|
uint8_t vendor_id[8] ; ///< 8 bytes of ASCII data identifying the vendor of the product.
|
||||||
uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor.
|
uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor.
|
||||||
uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor.
|
uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor.
|
||||||
} scsi_inquiry_resp_t;
|
} scsi_inquiry_resp_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct");
|
||||||
|
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format
|
uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format
|
||||||
uint8_t valid : 1;
|
uint8_t valid : 1;
|
||||||
|
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
|
|
||||||
uint8_t sense_key : 4;
|
uint8_t sense_key : 4;
|
||||||
uint8_t : 1;
|
uint8_t : 1;
|
||||||
uint8_t ili : 1; ///< Incorrect length indicator
|
uint8_t ili : 1; ///< Incorrect length indicator
|
||||||
uint8_t end_of_medium : 1;
|
uint8_t end_of_medium : 1;
|
||||||
uint8_t filemark : 1;
|
uint8_t filemark : 1;
|
||||||
|
|
||||||
uint32_t information;
|
uint32_t information;
|
||||||
uint8_t add_sense_len;
|
uint8_t add_sense_len;
|
||||||
uint32_t command_specific_info;
|
uint32_t command_specific_info;
|
||||||
uint8_t add_sense_code;
|
uint8_t add_sense_code;
|
||||||
uint8_t add_sense_qualifier;
|
uint8_t add_sense_qualifier;
|
||||||
uint8_t field_replaceable_unit_code;
|
uint8_t field_replaceable_unit_code;
|
||||||
|
|
||||||
uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout
|
uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout
|
||||||
|
|
||||||
} scsi_sense_fixed_resp_t;
|
} scsi_sense_fixed_resp_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct");
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6
|
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6
|
||||||
|
|
||||||
uint8_t : 3;
|
uint8_t : 3;
|
||||||
uint8_t disable_block_descriptor : 1;
|
uint8_t disable_block_descriptor : 1;
|
||||||
uint8_t : 0;
|
uint8_t : 0;
|
||||||
|
|
||||||
uint8_t page_code : 6;
|
uint8_t page_code : 6;
|
||||||
uint8_t page_control : 2;
|
uint8_t page_control : 2;
|
||||||
|
|
||||||
uint8_t subpage_code;
|
uint8_t subpage_code;
|
||||||
uint8_t alloc_length;
|
uint8_t alloc_length;
|
||||||
uint8_t control;
|
uint8_t control;
|
||||||
} scsi_mode_sense6_t;
|
} scsi_mode_sense6_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct");
|
||||||
|
|
||||||
// This is only a Mode parameter header(6).
|
// This is only a Mode parameter header(6).
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t data_len;
|
uint8_t data_len;
|
||||||
uint8_t medium_type;
|
uint8_t medium_type;
|
||||||
|
|
||||||
uint8_t reserved : 7;
|
uint8_t reserved : 7;
|
||||||
bool write_protected : 1;
|
bool write_protected : 1;
|
||||||
|
|
||||||
uint8_t block_descriptor_len;
|
uint8_t block_descriptor_len;
|
||||||
} scsi_mode_sense6_resp_t;
|
} scsi_mode_sense6_resp_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct");
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
|
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
uint8_t prohibit_removal;
|
uint8_t prohibit_removal;
|
||||||
uint8_t control;
|
uint8_t control;
|
||||||
} scsi_prevent_allow_medium_removal_t;
|
} scsi_prevent_allow_medium_removal_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct");
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code;
|
uint8_t cmd_code;
|
||||||
|
|
||||||
uint8_t immded : 1;
|
uint8_t immded : 1;
|
||||||
uint8_t : 7;
|
uint8_t : 7;
|
||||||
|
|
||||||
uint8_t TU_RESERVED;
|
uint8_t TU_RESERVED;
|
||||||
|
|
||||||
uint8_t power_condition_mod : 4;
|
uint8_t power_condition_mod : 4;
|
||||||
uint8_t : 4;
|
uint8_t : 4;
|
||||||
|
|
||||||
uint8_t start : 1;
|
uint8_t start : 1;
|
||||||
uint8_t load_eject : 1;
|
uint8_t load_eject : 1;
|
||||||
uint8_t no_flush : 1;
|
uint8_t no_flush : 1;
|
||||||
uint8_t : 1;
|
uint8_t : 1;
|
||||||
uint8_t power_condition : 4;
|
uint8_t power_condition : 4;
|
||||||
|
|
||||||
uint8_t control;
|
uint8_t control;
|
||||||
} scsi_start_stop_unit_t;
|
} scsi_start_stop_unit_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct");
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// SCSI MMC
|
// SCSI MMC
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/// SCSI Read Format Capacity: Write Capacity
|
/// SCSI Read Format Capacity: Write Capacity
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code;
|
uint8_t cmd_code;
|
||||||
uint8_t reserved[6];
|
uint8_t reserved[6];
|
||||||
uint16_t alloc_length;
|
uint16_t alloc_length;
|
||||||
uint8_t control;
|
uint8_t control;
|
||||||
} scsi_read_format_capacity_t;
|
} scsi_read_format_capacity_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct");
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED{
|
typedef struct TU_ATTR_PACKED{
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it.
|
uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it.
|
||||||
|
|
||||||
uint32_t block_num; /// Number of Logical Blocks
|
uint32_t block_num; /// Number of Logical Blocks
|
||||||
uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present
|
uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present
|
||||||
|
|
||||||
uint8_t reserved2;
|
uint8_t reserved2;
|
||||||
uint16_t block_size_u16;
|
uint16_t block_size_u16;
|
||||||
|
|
||||||
} scsi_read_format_capacity_data_t;
|
} scsi_read_format_capacity_data_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct");
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// SCSI Block Command (SBC-3)
|
// SCSI Block Command (SBC-3)
|
||||||
// NOTE: All data in SCSI command are in Big Endian
|
// NOTE: All data in SCSI command are in Big Endian
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// SCSI Read Capacity 10 Command: Read Capacity
|
/// SCSI Read Capacity 10 Command: Read Capacity
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10
|
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10
|
||||||
uint8_t reserved1 ;
|
uint8_t reserved1 ;
|
||||||
uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
|
uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
|
||||||
uint16_t reserved2 ;
|
uint16_t reserved2 ;
|
||||||
uint8_t partial_medium_indicator ;
|
uint8_t partial_medium_indicator ;
|
||||||
uint8_t control ;
|
uint8_t control ;
|
||||||
} scsi_read_capacity10_t;
|
} scsi_read_capacity10_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct");
|
||||||
|
|
||||||
/// SCSI Read Capacity 10 Response Data
|
/// SCSI Read Capacity 10 Response Data
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t last_lba ; ///< The last Logical Block Address of the device
|
uint32_t last_lba ; ///< The last Logical Block Address of the device
|
||||||
uint32_t block_size ; ///< Block size in bytes
|
uint32_t block_size ; ///< Block size in bytes
|
||||||
} scsi_read_capacity10_resp_t;
|
} scsi_read_capacity10_resp_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct");
|
||||||
|
|
||||||
/// SCSI Read 10 Command
|
/// SCSI Read 10 Command
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t cmd_code ; ///< SCSI OpCode
|
uint8_t cmd_code ; ///< SCSI OpCode
|
||||||
uint8_t reserved ; // has LUN according to wiki
|
uint8_t reserved ; // has LUN according to wiki
|
||||||
uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
|
uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
|
||||||
uint8_t reserved2 ;
|
uint8_t reserved2 ;
|
||||||
uint16_t block_count ; ///< Number of Blocks used by this command
|
uint16_t block_count ; ///< Number of Blocks used by this command
|
||||||
uint8_t control ;
|
uint8_t control ;
|
||||||
} scsi_read10_t, scsi_write10_t;
|
} scsi_read10_t, scsi_write10_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct");
|
||||||
TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct");
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_MSC_H_ */
|
#endif /* _TUSB_MSC_H_ */
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @}
|
/// @}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,165 +1,165 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_MSC_DEVICE_H_
|
#ifndef _TUSB_MSC_DEVICE_H_
|
||||||
#define _TUSB_MSC_DEVICE_H_
|
#define _TUSB_MSC_DEVICE_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "device/usbd.h"
|
#include "device/usbd.h"
|
||||||
#include "msc.h"
|
#include "msc.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Class Driver Configuration
|
// Class Driver Configuration
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
|
TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
|
||||||
|
|
||||||
#ifndef CFG_TUD_MSC_BUFSIZE
|
#ifndef CFG_TUD_MSC_BUFSIZE
|
||||||
#error CFG_TUD_MSC_BUFSIZE must be defined, value of a block size should work well, the more the better
|
#error CFG_TUD_MSC_BUFSIZE must be defined, value of a block size should work well, the more the better
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \addtogroup ClassDriver_MSC
|
/** \addtogroup ClassDriver_MSC
|
||||||
* @{
|
* @{
|
||||||
* \defgroup MSC_Device Device
|
* \defgroup MSC_Device Device
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
|
bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application Callbacks (WEAK is optional)
|
// Application Callbacks (WEAK is optional)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when received \ref SCSI_CMD_READ_10 command
|
* Invoked when received \ref SCSI_CMD_READ_10 command
|
||||||
* \param[in] lun Logical unit number
|
* \param[in] lun Logical unit number
|
||||||
* \param[in] lba Logical Block Address to be read
|
* \param[in] lba Logical Block Address to be read
|
||||||
* \param[in] offset Byte offset from LBA
|
* \param[in] offset Byte offset from LBA
|
||||||
* \param[out] buffer Buffer which application need to update with the response data.
|
* \param[out] buffer Buffer which application need to update with the response data.
|
||||||
* \param[in] bufsize Requested bytes
|
* \param[in] bufsize Requested bytes
|
||||||
*
|
*
|
||||||
* \return Number of byte read, if it is less than requested bytes by \a \b bufsize. Tinyusb will transfer
|
* \return Number of byte read, if it is less than requested bytes by \a \b bufsize. Tinyusb will transfer
|
||||||
* this amount first and invoked this again for remaining data.
|
* this amount first and invoked this again for remaining data.
|
||||||
*
|
*
|
||||||
* \retval zero Indicate application is not ready yet to response e.g disk I/O is not complete.
|
* \retval zero Indicate application is not ready yet to response e.g disk I/O is not complete.
|
||||||
* tinyusb will invoke this callback with the same parameters again some time later.
|
* tinyusb will invoke this callback with the same parameters again some time later.
|
||||||
*
|
*
|
||||||
* \retval negative Indicate error e.g reading disk I/O. tinyusb will \b STALL the corresponding
|
* \retval negative Indicate error e.g reading disk I/O. tinyusb will \b STALL the corresponding
|
||||||
* endpoint and return failed status in command status wrapper phase.
|
* endpoint and return failed status in command status wrapper phase.
|
||||||
*/
|
*/
|
||||||
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
|
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when received \ref SCSI_CMD_WRITE_10 command
|
* Invoked when received \ref SCSI_CMD_WRITE_10 command
|
||||||
* \param[in] lun Logical unit number
|
* \param[in] lun Logical unit number
|
||||||
* \param[in] lba Logical Block Address to be write
|
* \param[in] lba Logical Block Address to be write
|
||||||
* \param[in] offset Byte offset from LBA
|
* \param[in] offset Byte offset from LBA
|
||||||
* \param[out] buffer Buffer which holds written data.
|
* \param[out] buffer Buffer which holds written data.
|
||||||
* \param[in] bufsize Requested bytes
|
* \param[in] bufsize Requested bytes
|
||||||
*
|
*
|
||||||
* \return Number of byte written, if it is less than requested bytes by \a \b bufsize. Tinyusb will proceed with
|
* \return Number of byte written, if it is less than requested bytes by \a \b bufsize. Tinyusb will proceed with
|
||||||
* other work and invoked this again with adjusted parameters.
|
* other work and invoked this again with adjusted parameters.
|
||||||
*
|
*
|
||||||
* \retval zero Indicate application is not ready yet e.g disk I/O is not complete.
|
* \retval zero Indicate application is not ready yet e.g disk I/O is not complete.
|
||||||
* Tinyusb will invoke this callback with the same parameters again some time later.
|
* Tinyusb will invoke this callback with the same parameters again some time later.
|
||||||
*
|
*
|
||||||
* \retval negative Indicate error writing disk I/O. Tinyusb will \b STALL the corresponding
|
* \retval negative Indicate error writing disk I/O. Tinyusb will \b STALL the corresponding
|
||||||
* endpoint and return failed status in command status wrapper phase.
|
* endpoint and return failed status in command status wrapper phase.
|
||||||
*/
|
*/
|
||||||
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
||||||
|
|
||||||
// Invoked when received SCSI_CMD_INQUIRY
|
// Invoked when received SCSI_CMD_INQUIRY
|
||||||
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||||
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
|
||||||
|
|
||||||
// Invoked when received Test Unit Ready command.
|
// Invoked when received Test Unit Ready command.
|
||||||
// return true allowing host to read/write this LUN e.g SD card inserted
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
bool tud_msc_test_unit_ready_cb(uint8_t lun);
|
bool tud_msc_test_unit_ready_cb(uint8_t lun);
|
||||||
|
|
||||||
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
// Application update block count and block size
|
// Application update block count and block size
|
||||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when received an SCSI command not in built-in list below.
|
* Invoked when received an SCSI command not in built-in list below.
|
||||||
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
|
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
|
||||||
* - READ10 and WRITE10 has their own callbacks
|
* - READ10 and WRITE10 has their own callbacks
|
||||||
*
|
*
|
||||||
* \param[in] lun Logical unit number
|
* \param[in] lun Logical unit number
|
||||||
* \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
|
* \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
|
||||||
* \param[out] buffer Buffer for SCSI Data Stage.
|
* \param[out] buffer Buffer for SCSI Data Stage.
|
||||||
* - For INPUT: application must fill this with response.
|
* - For INPUT: application must fill this with response.
|
||||||
* - For OUTPUT it holds the Data from host
|
* - For OUTPUT it holds the Data from host
|
||||||
* \param[in] bufsize Buffer's length.
|
* \param[in] bufsize Buffer's length.
|
||||||
*
|
*
|
||||||
* \return Actual bytes processed, can be zero for no-data command.
|
* \return Actual bytes processed, can be zero for no-data command.
|
||||||
* \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
|
* \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
|
||||||
* endpoint and return failed status in command status wrapper phase.
|
* endpoint and return failed status in command status wrapper phase.
|
||||||
*/
|
*/
|
||||||
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
|
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
|
||||||
|
|
||||||
/*------------- Optional callbacks -------------*/
|
/*------------- Optional callbacks -------------*/
|
||||||
|
|
||||||
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
|
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
|
||||||
TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
|
TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
|
||||||
|
|
||||||
// Invoked when received Start Stop Unit command
|
// Invoked when received Start Stop Unit command
|
||||||
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||||
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||||
TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
|
TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
|
||||||
|
|
||||||
// Invoked when Read10 command is complete
|
// Invoked when Read10 command is complete
|
||||||
TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
|
TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
|
||||||
|
|
||||||
// Invoke when Write10 command is complete, can be used to flush flash caching
|
// Invoke when Write10 command is complete, can be used to flush flash caching
|
||||||
TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun);
|
TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun);
|
||||||
|
|
||||||
// Invoked when command in tud_msc_scsi_cb is complete
|
// Invoked when command in tud_msc_scsi_cb is complete
|
||||||
TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]);
|
TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]);
|
||||||
|
|
||||||
// Hook to make a mass storage device read-only. TODO remove
|
// Hook to make a mass storage device read-only. TODO remove
|
||||||
TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
|
TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void mscd_init (void);
|
void mscd_init (void);
|
||||||
void mscd_reset (uint8_t rhport);
|
void mscd_reset (uint8_t rhport);
|
||||||
bool mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_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_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
bool mscd_control_complete (uint8_t rhport, tusb_control_request_t const * p_request);
|
||||||
bool 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);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_MSC_DEVICE_H_ */
|
#endif /* _TUSB_MSC_DEVICE_H_ */
|
||||||
|
@ -1,413 +1,413 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if TUSB_OPT_HOST_ENABLED & CFG_TUH_MSC
|
#if TUSB_OPT_HOST_ENABLED & CFG_TUH_MSC
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INCLUDE
|
// INCLUDE
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "msc_host.h"
|
#include "msc_host.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
CFG_TUSB_MEM_SECTION static msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
CFG_TUSB_MEM_SECTION static msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||||
|
|
||||||
//------------- Initalization Data -------------//
|
//------------- Initalization Data -------------//
|
||||||
static osal_semaphore_def_t msch_sem_def;
|
static osal_semaphore_def_t msch_sem_def;
|
||||||
static osal_semaphore_t msch_sem_hdl;
|
static osal_semaphore_t msch_sem_hdl;
|
||||||
|
|
||||||
// buffer used to read scsi information when mounted, largest response data currently is inquiry
|
// buffer used to read scsi information when mounted, largest response data currently is inquiry
|
||||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t msch_buffer[sizeof(scsi_inquiry_resp_t)];
|
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t msch_buffer[sizeof(scsi_inquiry_resp_t)];
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// PUBLIC API
|
// PUBLIC API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool tuh_msc_is_mounted(uint8_t dev_addr)
|
bool tuh_msc_is_mounted(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return tuh_device_is_configured(dev_addr) && // is configured can be omitted
|
return tuh_device_is_configured(dev_addr) && // is configured can be omitted
|
||||||
msch_data[dev_addr-1].is_initialized;
|
msch_data[dev_addr-1].is_initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuh_msc_is_busy(uint8_t dev_addr)
|
bool tuh_msc_is_busy(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return msch_data[dev_addr-1].is_initialized &&
|
return msch_data[dev_addr-1].is_initialized &&
|
||||||
hcd_edpt_busy(dev_addr, msch_data[dev_addr-1].ep_in);
|
hcd_edpt_busy(dev_addr, msch_data[dev_addr-1].ep_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t const* tuh_msc_get_vendor_name(uint8_t dev_addr)
|
uint8_t const* tuh_msc_get_vendor_name(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return msch_data[dev_addr-1].is_initialized ? msch_data[dev_addr-1].vendor_id : NULL;
|
return msch_data[dev_addr-1].is_initialized ? msch_data[dev_addr-1].vendor_id : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t const* tuh_msc_get_product_name(uint8_t dev_addr)
|
uint8_t const* tuh_msc_get_product_name(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return msch_data[dev_addr-1].is_initialized ? msch_data[dev_addr-1].product_id : NULL;
|
return msch_data[dev_addr-1].is_initialized ? msch_data[dev_addr-1].product_id : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint32_t* p_block_size)
|
tusb_error_t tuh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint32_t* p_block_size)
|
||||||
{
|
{
|
||||||
if ( !msch_data[dev_addr-1].is_initialized ) return TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED;
|
if ( !msch_data[dev_addr-1].is_initialized ) return TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED;
|
||||||
TU_ASSERT(p_last_lba != NULL && p_block_size != NULL, TUSB_ERROR_INVALID_PARA);
|
TU_ASSERT(p_last_lba != NULL && p_block_size != NULL, TUSB_ERROR_INVALID_PARA);
|
||||||
|
|
||||||
(*p_last_lba) = msch_data[dev_addr-1].last_lba;
|
(*p_last_lba) = msch_data[dev_addr-1].last_lba;
|
||||||
(*p_block_size) = (uint32_t) msch_data[dev_addr-1].block_size;
|
(*p_block_size) = (uint32_t) msch_data[dev_addr-1].block_size;
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// PUBLIC API: SCSI COMMAND
|
// PUBLIC API: SCSI COMMAND
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline void msc_cbw_add_signature(msc_cbw_t *p_cbw, uint8_t lun)
|
static inline void msc_cbw_add_signature(msc_cbw_t *p_cbw, uint8_t lun)
|
||||||
{
|
{
|
||||||
p_cbw->signature = MSC_CBW_SIGNATURE;
|
p_cbw->signature = MSC_CBW_SIGNATURE;
|
||||||
p_cbw->tag = 0xCAFECAFE;
|
p_cbw->tag = 0xCAFECAFE;
|
||||||
p_cbw->lun = lun;
|
p_cbw->lun = lun;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tusb_error_t msch_command_xfer(uint8_t dev_addr, msch_interface_t * p_msch, void* p_buffer)
|
static tusb_error_t msch_command_xfer(uint8_t dev_addr, msch_interface_t * p_msch, void* p_buffer)
|
||||||
{
|
{
|
||||||
if ( NULL != p_buffer)
|
if ( NULL != p_buffer)
|
||||||
{ // there is data phase
|
{ // there is data phase
|
||||||
if (p_msch->cbw.dir & TUSB_DIR_IN_MASK)
|
if (p_msch->cbw.dir & TUSB_DIR_IN_MASK)
|
||||||
{
|
{
|
||||||
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false), TUSB_ERROR_FAILED );
|
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false), TUSB_ERROR_FAILED );
|
||||||
TU_ASSERT( hcd_pipe_queue_xfer(dev_addr, p_msch->ep_in , p_buffer, p_msch->cbw.total_bytes), TUSB_ERROR_FAILED );
|
TU_ASSERT( hcd_pipe_queue_xfer(dev_addr, p_msch->ep_in , p_buffer, p_msch->cbw.total_bytes), TUSB_ERROR_FAILED );
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
TU_ASSERT( hcd_pipe_queue_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_FAILED );
|
TU_ASSERT( hcd_pipe_queue_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_FAILED );
|
||||||
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out , p_buffer, p_msch->cbw.total_bytes, false), TUSB_ERROR_FAILED );
|
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out , p_buffer, p_msch->cbw.total_bytes, false), TUSB_ERROR_FAILED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_in , (uint8_t*) &p_msch->csw, sizeof(msc_csw_t), true), TUSB_ERROR_FAILED);
|
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_in , (uint8_t*) &p_msch->csw, sizeof(msc_csw_t), true), TUSB_ERROR_FAILED);
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tusbh_msc_inquiry(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
|
tusb_error_t tusbh_msc_inquiry(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
|
||||||
{
|
{
|
||||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Command Block Wrapper -------------//
|
//------------- Command Block Wrapper -------------//
|
||||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||||
p_msch->cbw.total_bytes = sizeof(scsi_inquiry_resp_t);
|
p_msch->cbw.total_bytes = sizeof(scsi_inquiry_resp_t);
|
||||||
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
||||||
p_msch->cbw.cmd_len = sizeof(scsi_inquiry_t);
|
p_msch->cbw.cmd_len = sizeof(scsi_inquiry_t);
|
||||||
|
|
||||||
//------------- SCSI command -------------//
|
//------------- SCSI command -------------//
|
||||||
scsi_inquiry_t cmd_inquiry =
|
scsi_inquiry_t cmd_inquiry =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_INQUIRY,
|
.cmd_code = SCSI_CMD_INQUIRY,
|
||||||
.alloc_length = sizeof(scsi_inquiry_resp_t)
|
.alloc_length = sizeof(scsi_inquiry_resp_t)
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(p_msch->cbw.command, &cmd_inquiry, p_msch->cbw.cmd_len);
|
memcpy(p_msch->cbw.command, &cmd_inquiry, p_msch->cbw.cmd_len);
|
||||||
|
|
||||||
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
|
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tusbh_msc_read_capacity10(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
|
tusb_error_t tusbh_msc_read_capacity10(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
|
||||||
{
|
{
|
||||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Command Block Wrapper -------------//
|
//------------- Command Block Wrapper -------------//
|
||||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||||
p_msch->cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t);
|
p_msch->cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t);
|
||||||
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
||||||
p_msch->cbw.cmd_len = sizeof(scsi_read_capacity10_t);
|
p_msch->cbw.cmd_len = sizeof(scsi_read_capacity10_t);
|
||||||
|
|
||||||
//------------- SCSI command -------------//
|
//------------- SCSI command -------------//
|
||||||
scsi_read_capacity10_t cmd_read_capacity10 =
|
scsi_read_capacity10_t cmd_read_capacity10 =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_READ_CAPACITY_10,
|
.cmd_code = SCSI_CMD_READ_CAPACITY_10,
|
||||||
.lba = 0,
|
.lba = 0,
|
||||||
.partial_medium_indicator = 0
|
.partial_medium_indicator = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(p_msch->cbw.command, &cmd_read_capacity10, p_msch->cbw.cmd_len);
|
memcpy(p_msch->cbw.command, &cmd_read_capacity10, p_msch->cbw.cmd_len);
|
||||||
|
|
||||||
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
|
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
|
tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
|
||||||
{
|
{
|
||||||
(void) lun; // TODO [MSCH] multiple lun support
|
(void) lun; // TODO [MSCH] multiple lun support
|
||||||
|
|
||||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Command Block Wrapper -------------//
|
//------------- Command Block Wrapper -------------//
|
||||||
p_msch->cbw.total_bytes = 18;
|
p_msch->cbw.total_bytes = 18;
|
||||||
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
||||||
p_msch->cbw.cmd_len = sizeof(scsi_request_sense_t);
|
p_msch->cbw.cmd_len = sizeof(scsi_request_sense_t);
|
||||||
|
|
||||||
//------------- SCSI command -------------//
|
//------------- SCSI command -------------//
|
||||||
scsi_request_sense_t cmd_request_sense =
|
scsi_request_sense_t cmd_request_sense =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_REQUEST_SENSE,
|
.cmd_code = SCSI_CMD_REQUEST_SENSE,
|
||||||
.alloc_length = 18
|
.alloc_length = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(p_msch->cbw.command, &cmd_request_sense, p_msch->cbw.cmd_len);
|
memcpy(p_msch->cbw.command, &cmd_request_sense, p_msch->cbw.cmd_len);
|
||||||
|
|
||||||
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
|
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw)
|
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw)
|
||||||
{
|
{
|
||||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Command Block Wrapper -------------//
|
//------------- Command Block Wrapper -------------//
|
||||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||||
|
|
||||||
p_msch->cbw.total_bytes = 0; // Number of bytes
|
p_msch->cbw.total_bytes = 0; // Number of bytes
|
||||||
p_msch->cbw.dir = TUSB_DIR_OUT;
|
p_msch->cbw.dir = TUSB_DIR_OUT;
|
||||||
p_msch->cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
|
p_msch->cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
|
||||||
|
|
||||||
//------------- SCSI command -------------//
|
//------------- SCSI command -------------//
|
||||||
scsi_test_unit_ready_t cmd_test_unit_ready =
|
scsi_test_unit_ready_t cmd_test_unit_ready =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_TEST_UNIT_READY,
|
.cmd_code = SCSI_CMD_TEST_UNIT_READY,
|
||||||
.lun = lun // according to wiki
|
.lun = lun // according to wiki
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(p_msch->cbw.command, &cmd_test_unit_ready, p_msch->cbw.cmd_len);
|
memcpy(p_msch->cbw.command, &cmd_test_unit_ready, p_msch->cbw.cmd_len);
|
||||||
|
|
||||||
// TODO MSCH refractor test uinit ready
|
// TODO MSCH refractor test uinit ready
|
||||||
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false), TUSB_ERROR_FAILED );
|
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false), TUSB_ERROR_FAILED );
|
||||||
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_in , (uint8_t*) p_csw, sizeof(msc_csw_t), true), TUSB_ERROR_FAILED );
|
TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_in , (uint8_t*) p_csw, sizeof(msc_csw_t), true), TUSB_ERROR_FAILED );
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count)
|
tusb_error_t tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count)
|
||||||
{
|
{
|
||||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Command Block Wrapper -------------//
|
//------------- Command Block Wrapper -------------//
|
||||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||||
|
|
||||||
p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
|
p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
|
||||||
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
||||||
p_msch->cbw.cmd_len = sizeof(scsi_read10_t);
|
p_msch->cbw.cmd_len = sizeof(scsi_read10_t);
|
||||||
|
|
||||||
//------------- SCSI command -------------//
|
//------------- SCSI command -------------//
|
||||||
scsi_read10_t cmd_read10 =
|
scsi_read10_t cmd_read10 =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_READ_10,
|
.cmd_code = SCSI_CMD_READ_10,
|
||||||
.lba = tu_htonl(lba),
|
.lba = tu_htonl(lba),
|
||||||
.block_count = tu_htons(block_count)
|
.block_count = tu_htons(block_count)
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(p_msch->cbw.command, &cmd_read10, p_msch->cbw.cmd_len);
|
memcpy(p_msch->cbw.command, &cmd_read10, p_msch->cbw.cmd_len);
|
||||||
|
|
||||||
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_buffer));
|
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_buffer));
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count)
|
tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count)
|
||||||
{
|
{
|
||||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||||
|
|
||||||
//------------- Command Block Wrapper -------------//
|
//------------- Command Block Wrapper -------------//
|
||||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||||
|
|
||||||
p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
|
p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
|
||||||
p_msch->cbw.dir = TUSB_DIR_OUT;
|
p_msch->cbw.dir = TUSB_DIR_OUT;
|
||||||
p_msch->cbw.cmd_len = sizeof(scsi_write10_t);
|
p_msch->cbw.cmd_len = sizeof(scsi_write10_t);
|
||||||
|
|
||||||
//------------- SCSI command -------------//
|
//------------- SCSI command -------------//
|
||||||
scsi_write10_t cmd_write10 =
|
scsi_write10_t cmd_write10 =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_WRITE_10,
|
.cmd_code = SCSI_CMD_WRITE_10,
|
||||||
.lba = tu_htonl(lba),
|
.lba = tu_htonl(lba),
|
||||||
.block_count = tu_htons(block_count)
|
.block_count = tu_htons(block_count)
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(p_msch->cbw.command, &cmd_write10, p_msch->cbw.cmd_len);
|
memcpy(p_msch->cbw.command, &cmd_write10, p_msch->cbw.cmd_len);
|
||||||
|
|
||||||
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, (void*) p_buffer));
|
TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, (void*) p_buffer));
|
||||||
|
|
||||||
return TUSB_ERROR_NONE;
|
return TUSB_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CLASS-USBH API (don't require to verify parameters)
|
// CLASS-USBH API (don't require to verify parameters)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void msch_init(void)
|
void msch_init(void)
|
||||||
{
|
{
|
||||||
tu_memclr(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
tu_memclr(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||||
msch_sem_hdl = osal_semaphore_create(&msch_sem_def);
|
msch_sem_hdl = osal_semaphore_create(&msch_sem_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
|
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
|
||||||
{
|
{
|
||||||
TU_VERIFY (MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
|
TU_VERIFY (MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
|
||||||
MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol);
|
MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol);
|
||||||
|
|
||||||
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 *) tu_desc_next(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++)
|
||||||
{
|
{
|
||||||
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
|
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
|
||||||
TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
|
TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
|
||||||
|
|
||||||
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
|
||||||
|
|
||||||
if ( tu_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
|
||||||
{
|
{
|
||||||
p_msc->ep_out = ep_desc->bEndpointAddress;
|
p_msc->ep_out = ep_desc->bEndpointAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(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;
|
||||||
(*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);
|
||||||
|
|
||||||
//------------- Get Max Lun -------------//
|
//------------- Get Max Lun -------------//
|
||||||
tusb_control_request_t request = {
|
tusb_control_request_t request = {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
||||||
.bRequest = MSC_REQ_GET_MAX_LUN,
|
.bRequest = MSC_REQ_GET_MAX_LUN,
|
||||||
.wValue = 0,
|
.wValue = 0,
|
||||||
.wIndex = p_msc->itf_numr,
|
.wIndex = p_msc->itf_numr,
|
||||||
.wLength = 1
|
.wLength = 1
|
||||||
};
|
};
|
||||||
// TODO STALL means zero
|
// TODO STALL means zero
|
||||||
TU_ASSERT( usbh_control_xfer( dev_addr, &request, msch_buffer ) );
|
TU_ASSERT( usbh_control_xfer( dev_addr, &request, msch_buffer ) );
|
||||||
p_msc->max_lun = msch_buffer[0];
|
p_msc->max_lun = msch_buffer[0];
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
//------------- Reset -------------//
|
//------------- Reset -------------//
|
||||||
request = (tusb_control_request_t) {
|
request = (tusb_control_request_t) {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = MSC_REQ_RESET,
|
.bRequest = MSC_REQ_RESET,
|
||||||
.wValue = 0,
|
.wValue = 0,
|
||||||
.wIndex = p_msc->itf_numr,
|
.wIndex = p_msc->itf_numr,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
|
TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum { SCSI_XFER_TIMEOUT = 2000 };
|
enum { SCSI_XFER_TIMEOUT = 2000 };
|
||||||
//------------- SCSI Inquiry -------------//
|
//------------- SCSI Inquiry -------------//
|
||||||
tusbh_msc_inquiry(dev_addr, 0, msch_buffer);
|
tusbh_msc_inquiry(dev_addr, 0, msch_buffer);
|
||||||
TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT) );
|
TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT) );
|
||||||
|
|
||||||
memcpy(p_msc->vendor_id , ((scsi_inquiry_resp_t*) msch_buffer)->vendor_id , 8);
|
memcpy(p_msc->vendor_id , ((scsi_inquiry_resp_t*) msch_buffer)->vendor_id , 8);
|
||||||
memcpy(p_msc->product_id, ((scsi_inquiry_resp_t*) msch_buffer)->product_id, 16);
|
memcpy(p_msc->product_id, ((scsi_inquiry_resp_t*) msch_buffer)->product_id, 16);
|
||||||
|
|
||||||
//------------- SCSI Read Capacity 10 -------------//
|
//------------- SCSI Read Capacity 10 -------------//
|
||||||
tusbh_msc_read_capacity10(dev_addr, 0, msch_buffer);
|
tusbh_msc_read_capacity10(dev_addr, 0, msch_buffer);
|
||||||
TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
|
TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
|
||||||
|
|
||||||
// NOTE: my toshiba thumb-drive stall the first Read Capacity and require the sequence
|
// NOTE: my toshiba thumb-drive stall the first Read Capacity and require the sequence
|
||||||
// Read Capacity --> Stalled --> Clear Stall --> Request Sense --> Read Capacity (2) to work
|
// Read Capacity --> Stalled --> Clear Stall --> Request Sense --> Read Capacity (2) to work
|
||||||
if ( hcd_edpt_stalled(dev_addr, p_msc->ep_in) )
|
if ( hcd_edpt_stalled(dev_addr, p_msc->ep_in) )
|
||||||
{
|
{
|
||||||
// clear stall TODO abstract clear stall function
|
// clear stall TODO abstract clear stall function
|
||||||
request = (tusb_control_request_t) {
|
request = (tusb_control_request_t) {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_ENDPOINT, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_ENDPOINT, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = TUSB_REQ_CLEAR_FEATURE,
|
.bRequest = TUSB_REQ_CLEAR_FEATURE,
|
||||||
.wValue = 0,
|
.wValue = 0,
|
||||||
.wIndex = p_msc->ep_in,
|
.wIndex = p_msc->ep_in,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT(usbh_control_xfer( dev_addr, &request, NULL ));
|
TU_ASSERT(usbh_control_xfer( dev_addr, &request, NULL ));
|
||||||
|
|
||||||
hcd_edpt_clear_stall(dev_addr, p_msc->ep_in);
|
hcd_edpt_clear_stall(dev_addr, p_msc->ep_in);
|
||||||
TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT) ); // wait for SCSI status
|
TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT) ); // wait for SCSI status
|
||||||
|
|
||||||
//------------- SCSI Request Sense -------------//
|
//------------- SCSI Request Sense -------------//
|
||||||
(void) tuh_msc_request_sense(dev_addr, 0, msch_buffer);
|
(void) tuh_msc_request_sense(dev_addr, 0, msch_buffer);
|
||||||
TU_ASSERT(osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
|
TU_ASSERT(osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
|
||||||
|
|
||||||
//------------- Re-read SCSI Read Capactity -------------//
|
//------------- Re-read SCSI Read Capactity -------------//
|
||||||
tusbh_msc_read_capacity10(dev_addr, 0, msch_buffer);
|
tusbh_msc_read_capacity10(dev_addr, 0, msch_buffer);
|
||||||
TU_ASSERT(osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
|
TU_ASSERT(osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
p_msc->last_lba = tu_ntohl( ((scsi_read_capacity10_resp_t*)msch_buffer)->last_lba );
|
p_msc->last_lba = tu_ntohl( ((scsi_read_capacity10_resp_t*)msch_buffer)->last_lba );
|
||||||
p_msc->block_size = (uint16_t) tu_ntohl( ((scsi_read_capacity10_resp_t*)msch_buffer)->block_size );
|
p_msc->block_size = (uint16_t) tu_ntohl( ((scsi_read_capacity10_resp_t*)msch_buffer)->block_size );
|
||||||
|
|
||||||
p_msc->is_initialized = true;
|
p_msc->is_initialized = true;
|
||||||
|
|
||||||
tuh_msc_mounted_cb(dev_addr);
|
tuh_msc_mounted_cb(dev_addr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void msch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
void msch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
msch_interface_t* p_msc = &msch_data[dev_addr-1];
|
msch_interface_t* p_msc = &msch_data[dev_addr-1];
|
||||||
if ( ep_addr == p_msc->ep_in )
|
if ( ep_addr == p_msc->ep_in )
|
||||||
{
|
{
|
||||||
if (p_msc->is_initialized)
|
if (p_msc->is_initialized)
|
||||||
{
|
{
|
||||||
tuh_msc_isr(dev_addr, event, xferred_bytes);
|
tuh_msc_isr(dev_addr, event, xferred_bytes);
|
||||||
}else
|
}else
|
||||||
{ // still initializing under open subtask
|
{ // still initializing under open subtask
|
||||||
osal_semaphore_post(msch_sem_hdl, true);
|
osal_semaphore_post(msch_sem_hdl, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void msch_close(uint8_t dev_addr)
|
void msch_close(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
tu_memclr(&msch_data[dev_addr-1], sizeof(msch_interface_t));
|
tu_memclr(&msch_data[dev_addr-1], sizeof(msch_interface_t));
|
||||||
osal_semaphore_reset(msch_sem_hdl);
|
osal_semaphore_reset(msch_sem_hdl);
|
||||||
|
|
||||||
tuh_msc_unmounted_cb(dev_addr); // invoke Application Callback
|
tuh_msc_unmounted_cb(dev_addr); // invoke Application Callback
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL & HELPER
|
// INTERNAL & HELPER
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,206 +1,206 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_MSC_HOST_H_
|
#ifndef _TUSB_MSC_HOST_H_
|
||||||
#define _TUSB_MSC_HOST_H_
|
#define _TUSB_MSC_HOST_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "host/usbh.h"
|
#include "host/usbh.h"
|
||||||
#include "msc.h"
|
#include "msc.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \addtogroup ClassDriver_MSC
|
/** \addtogroup ClassDriver_MSC
|
||||||
* @{
|
* @{
|
||||||
* \defgroup MSC_Host Host
|
* \defgroup MSC_Host Host
|
||||||
* The interface API includes status checking function, data transferring function and callback functions
|
* The interface API includes status checking function, data transferring function and callback functions
|
||||||
* @{ */
|
* @{ */
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MASS STORAGE Application API
|
// MASS STORAGE Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
/** \brief Check if device supports MassStorage interface or not
|
/** \brief Check if device supports MassStorage interface or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if device supports
|
* \retval true if device supports
|
||||||
* \retval false if device does not support or is not mounted
|
* \retval false if device does not support or is not mounted
|
||||||
*/
|
*/
|
||||||
bool tuh_msc_is_mounted(uint8_t dev_addr);
|
bool tuh_msc_is_mounted(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Check if the interface is currently busy or not
|
/** \brief Check if the interface is currently busy or not
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
||||||
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
||||||
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
|
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
|
||||||
* can be scheduled. User needs to make sure the corresponding interface is mounted (by \ref tuh_msc_is_mounted)
|
* can be scheduled. User needs to make sure the corresponding interface is mounted (by \ref tuh_msc_is_mounted)
|
||||||
* before calling this function
|
* before calling this function
|
||||||
*/
|
*/
|
||||||
bool tuh_msc_is_busy(uint8_t dev_addr);
|
bool tuh_msc_is_busy(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Get SCSI vendor's name of MassStorage device
|
/** \brief Get SCSI vendor's name of MassStorage device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \return pointer to vendor's name or NULL if specified device does not support MassStorage
|
* \return pointer to vendor's name or NULL if specified device does not support MassStorage
|
||||||
* \note SCSI vendor's name is 8-byte length field in \ref scsi_inquiry_data_t. During enumeration, the stack has already
|
* \note SCSI vendor's name is 8-byte length field in \ref scsi_inquiry_data_t. During enumeration, the stack has already
|
||||||
* retrieved (via SCSI INQUIRY) and store this information internally. There is no need for application to re-send SCSI INQUIRY
|
* retrieved (via SCSI INQUIRY) and store this information internally. There is no need for application to re-send SCSI INQUIRY
|
||||||
* command or allocate buffer for this.
|
* command or allocate buffer for this.
|
||||||
*/
|
*/
|
||||||
uint8_t const* tuh_msc_get_vendor_name(uint8_t dev_addr);
|
uint8_t const* tuh_msc_get_vendor_name(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Get SCSI product's name of MassStorage device
|
/** \brief Get SCSI product's name of MassStorage device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \return pointer to product's name or NULL if specified device does not support MassStorage
|
* \return pointer to product's name or NULL if specified device does not support MassStorage
|
||||||
* \note SCSI product's name is 16-byte length field in \ref scsi_inquiry_data_t. During enumeration, the stack has already
|
* \note SCSI product's name is 16-byte length field in \ref scsi_inquiry_data_t. During enumeration, the stack has already
|
||||||
* retrieved (via SCSI INQUIRY) and store this information internally. There is no need for application to re-send SCSI INQUIRY
|
* retrieved (via SCSI INQUIRY) and store this information internally. There is no need for application to re-send SCSI INQUIRY
|
||||||
* command or allocate buffer for this.
|
* command or allocate buffer for this.
|
||||||
*/
|
*/
|
||||||
uint8_t const* tuh_msc_get_product_name(uint8_t dev_addr);
|
uint8_t const* tuh_msc_get_product_name(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Get SCSI Capacity of MassStorage device
|
/** \brief Get SCSI Capacity of MassStorage device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[out] p_last_lba Last Logical Block Address of device
|
* \param[out] p_last_lba Last Logical Block Address of device
|
||||||
* \param[out] p_block_size Block Size of device in bytes
|
* \param[out] p_block_size Block Size of device in bytes
|
||||||
* \retval pointer to product's name or NULL if specified device does not support MassStorage
|
* \retval pointer to product's name or NULL if specified device does not support MassStorage
|
||||||
* \note MassStorage's capacity can be computed by last LBA x block size (in bytes). During enumeration, the stack has already
|
* \note MassStorage's capacity can be computed by last LBA x block size (in bytes). During enumeration, the stack has already
|
||||||
* retrieved (via SCSI READ CAPACITY 10) and store this information internally. There is no need for application
|
* retrieved (via SCSI READ CAPACITY 10) and store this information internally. There is no need for application
|
||||||
* to re-send SCSI READ CAPACITY 10 command
|
* to re-send SCSI READ CAPACITY 10 command
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint32_t* p_block_size);
|
tusb_error_t tuh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint32_t* p_block_size);
|
||||||
|
|
||||||
/** \brief Perform SCSI READ 10 command to read data from MassStorage device
|
/** \brief Perform SCSI READ 10 command to read data from MassStorage device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] lun Targeted Logical Unit
|
* \param[in] lun Targeted Logical Unit
|
||||||
* \param[out] p_buffer Buffer used to store data read from device. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[out] p_buffer Buffer used to store data read from device. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \param[in] lba Starting Logical Block Address to be read
|
* \param[in] lba Starting Logical Block Address to be read
|
||||||
* \param[in] block_count Number of Block to be read
|
* \param[in] block_count Number of Block to be read
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count);
|
tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count);
|
||||||
|
|
||||||
/** \brief Perform SCSI WRITE 10 command to write data to MassStorage device
|
/** \brief Perform SCSI WRITE 10 command to write data to MassStorage device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] lun Targeted Logical Unit
|
* \param[in] lun Targeted Logical Unit
|
||||||
* \param[in] p_buffer Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[in] p_buffer Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \param[in] lba Starting Logical Block Address to be written
|
* \param[in] lba Starting Logical Block Address to be written
|
||||||
* \param[in] block_count Number of Block to be written
|
* \param[in] block_count Number of Block to be written
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count);
|
tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count);
|
||||||
|
|
||||||
/** \brief Perform SCSI REQUEST SENSE command, used to retrieve sense data from MassStorage device
|
/** \brief Perform SCSI REQUEST SENSE command, used to retrieve sense data from MassStorage device
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] lun Targeted Logical Unit
|
* \param[in] lun Targeted Logical Unit
|
||||||
* \param[in] p_data Buffer to store response's data from device. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
* \param[in] p_data Buffer to store response's data from device. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_data);
|
tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_data);
|
||||||
|
|
||||||
/** \brief Perform SCSI TEST UNIT READY command to test if MassStorage device is ready
|
/** \brief Perform SCSI TEST UNIT READY command to test if MassStorage device is ready
|
||||||
* \param[in] dev_addr device address
|
* \param[in] dev_addr device address
|
||||||
* \param[in] lun Targeted Logical Unit
|
* \param[in] lun Targeted Logical Unit
|
||||||
* \retval TUSB_ERROR_NONE on success
|
* \retval TUSB_ERROR_NONE on success
|
||||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
||||||
*/
|
*/
|
||||||
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw); // TODO to be refractor
|
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw); // TODO to be refractor
|
||||||
|
|
||||||
//tusb_error_t tusbh_msc_scsi_send(uint8_t dev_addr, uint8_t lun, bool is_direction_in,
|
//tusb_error_t tusbh_msc_scsi_send(uint8_t dev_addr, uint8_t lun, bool is_direction_in,
|
||||||
// uint8_t const * p_command, uint8_t cmd_len,
|
// uint8_t const * p_command, uint8_t cmd_len,
|
||||||
// uint8_t * p_response, uint32_t resp_len);
|
// uint8_t * p_response, uint32_t resp_len);
|
||||||
|
|
||||||
//------------- Application Callback -------------//
|
//------------- Application Callback -------------//
|
||||||
/** \brief Callback function that will be invoked when a device with MassStorage interface is mounted
|
/** \brief Callback function that will be invoked when a device with MassStorage interface is mounted
|
||||||
* \param[in] dev_addr Address of newly mounted device
|
* \param[in] dev_addr Address of newly mounted device
|
||||||
* \note This callback should be used by Application to set-up interface-related data
|
* \note This callback should be used by Application to set-up interface-related data
|
||||||
*/
|
*/
|
||||||
void tuh_msc_mounted_cb(uint8_t dev_addr);
|
void tuh_msc_mounted_cb(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Callback function that will be invoked when a device with MassStorage interface is unmounted
|
/** \brief Callback function that will be invoked when a device with MassStorage interface is unmounted
|
||||||
* \param[in] dev_addr Address of newly unmounted device
|
* \param[in] dev_addr Address of newly unmounted device
|
||||||
* \note This callback should be used by Application to tear-down interface-related data
|
* \note This callback should be used by Application to tear-down interface-related data
|
||||||
*/
|
*/
|
||||||
void tuh_msc_unmounted_cb(uint8_t dev_addr);
|
void tuh_msc_unmounted_cb(uint8_t dev_addr);
|
||||||
|
|
||||||
/** \brief Callback function that is invoked when an transferring event occurred
|
/** \brief Callback function that is invoked when an transferring event occurred
|
||||||
* \param[in] dev_addr Address of device
|
* \param[in] dev_addr Address of device
|
||||||
* \param[in] event an value from \ref xfer_result_t
|
* \param[in] event an value from \ref xfer_result_t
|
||||||
* \param[in] xferred_bytes Number of bytes transferred via USB bus
|
* \param[in] xferred_bytes Number of bytes transferred via USB bus
|
||||||
* \note event can be one of following
|
* \note event can be one of following
|
||||||
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
|
||||||
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
|
||||||
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
|
||||||
* \note
|
* \note
|
||||||
*/
|
*/
|
||||||
void tuh_msc_isr(uint8_t dev_addr, xfer_result_t event, uint32_t xferred_bytes);
|
void tuh_msc_isr(uint8_t dev_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t itf_numr;
|
uint8_t itf_numr;
|
||||||
uint8_t ep_in;
|
uint8_t ep_in;
|
||||||
uint8_t ep_out;
|
uint8_t ep_out;
|
||||||
|
|
||||||
uint8_t max_lun;
|
uint8_t max_lun;
|
||||||
uint16_t block_size;
|
uint16_t block_size;
|
||||||
uint32_t last_lba; // last logical block address
|
uint32_t last_lba; // last logical block address
|
||||||
|
|
||||||
volatile bool is_initialized;
|
volatile bool is_initialized;
|
||||||
uint8_t vendor_id[8];
|
uint8_t vendor_id[8];
|
||||||
uint8_t product_id[16];
|
uint8_t product_id[16];
|
||||||
|
|
||||||
msc_cbw_t cbw;
|
msc_cbw_t cbw;
|
||||||
msc_csw_t csw;
|
msc_csw_t csw;
|
||||||
}msch_interface_t;
|
}msch_interface_t;
|
||||||
|
|
||||||
void msch_init(void);
|
void msch_init(void);
|
||||||
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
|
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
|
||||||
void msch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
void msch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void msch_close(uint8_t dev_addr);
|
void msch_close(uint8_t dev_addr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_MSC_HOST_H_ */
|
#endif /* _TUSB_MSC_HOST_H_ */
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @}
|
/// @}
|
||||||
|
12
src/class/vendor/vendor_device.c
vendored
12
src/class/vendor/vendor_device.c
vendored
@ -197,9 +197,15 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
|
|||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) result;
|
(void) result;
|
||||||
|
|
||||||
// TODO Support multiple interfaces
|
uint8_t itf = 0;
|
||||||
uint8_t const itf = 0;
|
vendord_interface_t* p_itf = _vendord_itf;
|
||||||
vendord_interface_t* p_itf = &_vendord_itf[itf];
|
|
||||||
|
for ( ; ; itf++, p_itf++)
|
||||||
|
{
|
||||||
|
if (itf >= TU_ARRAY_SIZE(_vendord_itf)) return false;
|
||||||
|
|
||||||
|
if ( ( ep_addr == p_itf->ep_out ) || ( ep_addr == p_itf->ep_in ) ) break;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ep_addr == p_itf->ep_out )
|
if ( ep_addr == p_itf->ep_out )
|
||||||
{
|
{
|
||||||
|
@ -1,275 +1,275 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_Common
|
/** \ingroup Group_Common
|
||||||
* \defgroup Group_CommonH common.h
|
* \defgroup Group_CommonH common.h
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_COMMON_H_
|
#ifndef _TUSB_COMMON_H_
|
||||||
#define _TUSB_COMMON_H_
|
#define _TUSB_COMMON_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Macros Helper
|
// Macros Helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
|
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
|
||||||
#define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) )
|
#define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) )
|
||||||
#define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) )
|
#define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) )
|
||||||
|
|
||||||
#define TU_U16_HIGH(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
|
#define TU_U16_HIGH(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
|
||||||
#define TU_U16_LOW(u16) ((uint8_t) ((u16) & 0x00ff))
|
#define TU_U16_LOW(u16) ((uint8_t) ((u16) & 0x00ff))
|
||||||
#define U16_TO_U8S_BE(u16) TU_U16_HIGH(u16), TU_U16_LOW(u16)
|
#define U16_TO_U8S_BE(u16) TU_U16_HIGH(u16), TU_U16_LOW(u16)
|
||||||
#define U16_TO_U8S_LE(u16) TU_U16_LOW(u16), TU_U16_HIGH(u16)
|
#define U16_TO_U8S_LE(u16) TU_U16_LOW(u16), TU_U16_HIGH(u16)
|
||||||
|
|
||||||
#define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
|
#define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
|
||||||
#define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
|
#define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
|
||||||
#define U32_B3_U8(u32) ((uint8_t) (((u32) >> 8) & 0x000000ff))
|
#define U32_B3_U8(u32) ((uint8_t) (((u32) >> 8) & 0x000000ff))
|
||||||
#define U32_B4_U8(u32) ((uint8_t) ((u32) & 0x000000ff)) // LSB
|
#define U32_B4_U8(u32) ((uint8_t) ((u32) & 0x000000ff)) // LSB
|
||||||
|
|
||||||
#define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
|
#define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
|
||||||
#define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
|
#define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
|
||||||
|
|
||||||
#define TU_BIT(n) (1U << (n))
|
#define TU_BIT(n) (1U << (n))
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Includes
|
// Includes
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Standard Headers
|
// Standard Headers
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// Tinyusb Common Headers
|
// Tinyusb Common Headers
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
#include "tusb_compiler.h"
|
#include "tusb_compiler.h"
|
||||||
#include "tusb_verify.h"
|
#include "tusb_verify.h"
|
||||||
#include "tusb_error.h" // TODO remove
|
#include "tusb_error.h" // TODO remove
|
||||||
#include "tusb_timeout.h"
|
#include "tusb_timeout.h"
|
||||||
#include "tusb_types.h"
|
#include "tusb_types.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Inline Functions
|
// Inline Functions
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#define tu_memclr(buffer, size) memset((buffer), 0, (size))
|
#define tu_memclr(buffer, size) memset((buffer), 0, (size))
|
||||||
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
|
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
|
||||||
|
|
||||||
static inline uint32_t tu_u32(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
|
static inline uint32_t tu_u32(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
|
||||||
{
|
{
|
||||||
return ( ((uint32_t) b1) << 24) + ( ((uint32_t) b2) << 16) + ( ((uint32_t) b3) << 8) + b4;
|
return ( ((uint32_t) b1) << 24) + ( ((uint32_t) b2) << 16) + ( ((uint32_t) b3) << 8) + b4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t tu_u16(uint8_t high, uint8_t low)
|
static inline uint16_t tu_u16(uint8_t high, uint8_t low)
|
||||||
{
|
{
|
||||||
return (uint16_t)((((uint16_t) high) << 8) + low);
|
return (uint16_t)((((uint16_t) high) << 8) + low);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t tu_u16_high(uint16_t u16) { return (uint8_t) (((uint16_t) (u16 >> 8)) & 0x00ff); }
|
static inline uint8_t tu_u16_high(uint16_t u16) { return (uint8_t) (((uint16_t) (u16 >> 8)) & 0x00ff); }
|
||||||
static inline uint8_t tu_u16_low (uint16_t u16) { return (uint8_t) (u16 & 0x00ff); }
|
static inline uint8_t tu_u16_low (uint16_t u16) { return (uint8_t) (u16 & 0x00ff); }
|
||||||
|
|
||||||
// Min
|
// Min
|
||||||
static inline uint8_t tu_min8 (uint8_t x, uint8_t y ) { return (x < y) ? x : y; }
|
static inline uint8_t tu_min8 (uint8_t x, uint8_t y ) { return (x < y) ? x : y; }
|
||||||
static inline uint16_t tu_min16 (uint16_t x, uint16_t y) { return (x < y) ? x : y; }
|
static inline uint16_t tu_min16 (uint16_t x, uint16_t y) { return (x < y) ? x : y; }
|
||||||
static inline uint32_t tu_min32 (uint32_t x, uint32_t y) { return (x < y) ? x : y; }
|
static inline uint32_t tu_min32 (uint32_t x, uint32_t y) { return (x < y) ? x : y; }
|
||||||
|
|
||||||
// Max
|
// Max
|
||||||
static inline uint8_t tu_max8 (uint8_t x, uint8_t y ) { return (x > y) ? x : y; }
|
static inline uint8_t tu_max8 (uint8_t x, uint8_t y ) { return (x > y) ? x : y; }
|
||||||
static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { return (x > y) ? x : y; }
|
static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { return (x > y) ? x : y; }
|
||||||
static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; }
|
static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; }
|
||||||
|
|
||||||
// Align
|
// Align
|
||||||
static inline uint32_t tu_align_n(uint32_t value, uint32_t alignment)
|
static inline uint32_t tu_align_n(uint32_t value, uint32_t alignment)
|
||||||
{
|
{
|
||||||
return value & ((uint32_t) ~(alignment-1));
|
return value & ((uint32_t) ~(alignment-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); }
|
static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); }
|
||||||
static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); }
|
static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); }
|
||||||
static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); }
|
static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); }
|
||||||
static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); }
|
static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); }
|
||||||
|
|
||||||
//------------- Mathematics -------------//
|
//------------- Mathematics -------------//
|
||||||
static inline uint32_t tu_abs(int32_t value) { return (uint32_t)((value < 0) ? (-value) : value); }
|
static inline uint32_t tu_abs(int32_t value) { return (uint32_t)((value < 0) ? (-value) : value); }
|
||||||
|
|
||||||
/// inclusive range checking
|
/// inclusive range checking
|
||||||
static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper)
|
static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper)
|
||||||
{
|
{
|
||||||
return (lower <= value) && (value <= upper);
|
return (lower <= value) && (value <= upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// log2 of a value is its MSB's position
|
// log2 of a value is its MSB's position
|
||||||
// TODO use clz TODO remove
|
// TODO use clz TODO remove
|
||||||
static inline uint8_t tu_log2(uint32_t value)
|
static inline uint8_t tu_log2(uint32_t value)
|
||||||
{
|
{
|
||||||
uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
|
|
||||||
while (value >>= 1)
|
while (value >>= 1)
|
||||||
{
|
{
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bit
|
// Bit
|
||||||
static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); }
|
static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); }
|
||||||
static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); }
|
static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); }
|
||||||
static inline bool tu_bit_test (uint32_t value, uint8_t pos) { return (value & TU_BIT(pos)) ? true : false; }
|
static inline bool tu_bit_test (uint32_t value, uint8_t pos) { return (value & TU_BIT(pos)) ? true : false; }
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* Count number of arguments of __VA_ARGS__
|
/* Count number of arguments of __VA_ARGS__
|
||||||
* - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s
|
* - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s
|
||||||
* - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
|
* - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
|
||||||
* - _RSEQ_N() is reverse sequential to N to add padding to have
|
* - _RSEQ_N() is reverse sequential to N to add padding to have
|
||||||
* Nth position is the same as the number of arguments
|
* Nth position is the same as the number of arguments
|
||||||
* - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
|
* - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
#ifndef TU_ARGS_NUM
|
#ifndef TU_ARGS_NUM
|
||||||
|
|
||||||
#define TU_ARGS_NUM(...) NARG_(_0, ##__VA_ARGS__,_RSEQ_N())
|
#define TU_ARGS_NUM(...) NARG_(_0, ##__VA_ARGS__,_RSEQ_N())
|
||||||
|
|
||||||
#define NARG_(...) _GET_NTH_ARG(__VA_ARGS__)
|
#define NARG_(...) _GET_NTH_ARG(__VA_ARGS__)
|
||||||
#define _GET_NTH_ARG( \
|
#define _GET_NTH_ARG( \
|
||||||
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
|
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
|
||||||
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
|
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
|
||||||
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
|
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
|
||||||
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
|
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
|
||||||
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
|
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
|
||||||
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
|
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
|
||||||
_61,_62,_63,N,...) N
|
_61,_62,_63,N,...) N
|
||||||
#define _RSEQ_N() \
|
#define _RSEQ_N() \
|
||||||
62,61,60, \
|
62,61,60, \
|
||||||
59,58,57,56,55,54,53,52,51,50, \
|
59,58,57,56,55,54,53,52,51,50, \
|
||||||
49,48,47,46,45,44,43,42,41,40, \
|
49,48,47,46,45,44,43,42,41,40, \
|
||||||
39,38,37,36,35,34,33,32,31,30, \
|
39,38,37,36,35,34,33,32,31,30, \
|
||||||
29,28,27,26,25,24,23,22,21,20, \
|
29,28,27,26,25,24,23,22,21,20, \
|
||||||
19,18,17,16,15,14,13,12,11,10, \
|
19,18,17,16,15,14,13,12,11,10, \
|
||||||
9,8,7,6,5,4,3,2,1,0
|
9,8,7,6,5,4,3,2,1,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// To be removed
|
// To be removed
|
||||||
//------------- Binary constant -------------//
|
//------------- Binary constant -------------//
|
||||||
#if defined(__GNUC__) && !defined(__CC_ARM)
|
#if defined(__GNUC__) && !defined(__CC_ARM)
|
||||||
|
|
||||||
#define TU_BIN8(x) ((uint8_t) (0b##x))
|
#define TU_BIN8(x) ((uint8_t) (0b##x))
|
||||||
#define TU_BIN16(b1, b2) ((uint16_t) (0b##b1##b2))
|
#define TU_BIN16(b1, b2) ((uint16_t) (0b##b1##b2))
|
||||||
#define TU_BIN32(b1, b2, b3, b4) ((uint32_t) (0b##b1##b2##b3##b4))
|
#define TU_BIN32(b1, b2, b3, b4) ((uint32_t) (0b##b1##b2##b3##b4))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// internal macro of B8, B16, B32
|
// internal macro of B8, B16, B32
|
||||||
#define _B8__(x) (((x&0x0000000FUL)?1:0) \
|
#define _B8__(x) (((x&0x0000000FUL)?1:0) \
|
||||||
+((x&0x000000F0UL)?2:0) \
|
+((x&0x000000F0UL)?2:0) \
|
||||||
+((x&0x00000F00UL)?4:0) \
|
+((x&0x00000F00UL)?4:0) \
|
||||||
+((x&0x0000F000UL)?8:0) \
|
+((x&0x0000F000UL)?8:0) \
|
||||||
+((x&0x000F0000UL)?16:0) \
|
+((x&0x000F0000UL)?16:0) \
|
||||||
+((x&0x00F00000UL)?32:0) \
|
+((x&0x00F00000UL)?32:0) \
|
||||||
+((x&0x0F000000UL)?64:0) \
|
+((x&0x0F000000UL)?64:0) \
|
||||||
+((x&0xF0000000UL)?128:0))
|
+((x&0xF0000000UL)?128:0))
|
||||||
|
|
||||||
#define TU_BIN8(d) ((uint8_t) _B8__(0x##d##UL))
|
#define TU_BIN8(d) ((uint8_t) _B8__(0x##d##UL))
|
||||||
#define TU_BIN16(dmsb,dlsb) (((uint16_t)TU_BIN8(dmsb)<<8) + TU_BIN8(dlsb))
|
#define TU_BIN16(dmsb,dlsb) (((uint16_t)TU_BIN8(dmsb)<<8) + TU_BIN8(dlsb))
|
||||||
#define TU_BIN32(dmsb,db2,db3,dlsb) \
|
#define TU_BIN32(dmsb,db2,db3,dlsb) \
|
||||||
(((uint32_t)TU_BIN8(dmsb)<<24) \
|
(((uint32_t)TU_BIN8(dmsb)<<24) \
|
||||||
+ ((uint32_t)TU_BIN8(db2)<<16) \
|
+ ((uint32_t)TU_BIN8(db2)<<16) \
|
||||||
+ ((uint32_t)TU_BIN8(db3)<<8) \
|
+ ((uint32_t)TU_BIN8(db3)<<8) \
|
||||||
+ TU_BIN8(dlsb))
|
+ TU_BIN8(dlsb))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Debug Function
|
// Debug Function
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// CFG_TUSB_DEBUG for debugging
|
// CFG_TUSB_DEBUG for debugging
|
||||||
// 0 : no debug
|
// 0 : no debug
|
||||||
// 1 : print when there is error
|
// 1 : print when there is error
|
||||||
// 2 : print out log
|
// 2 : print out log
|
||||||
#if CFG_TUSB_DEBUG
|
#if CFG_TUSB_DEBUG
|
||||||
|
|
||||||
void tu_print_mem(void const *buf, uint16_t count, uint8_t indent);
|
void tu_print_mem(void const *buf, uint16_t count, uint8_t indent);
|
||||||
|
|
||||||
#ifndef tu_printf
|
#ifndef tu_printf
|
||||||
#define tu_printf printf
|
#define tu_printf printf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Log with debug level 1
|
// Log with debug level 1
|
||||||
#define TU_LOG1 tu_printf
|
#define TU_LOG1 tu_printf
|
||||||
#define TU_LOG1_MEM tu_print_mem
|
#define TU_LOG1_MEM tu_print_mem
|
||||||
#define TU_LOG1_LOCATION() tu_printf("%s: %d:\n", __PRETTY_FUNCTION__, __LINE__)
|
#define TU_LOG1_LOCATION() tu_printf("%s: %d:\n", __PRETTY_FUNCTION__, __LINE__)
|
||||||
|
|
||||||
// Log with debug level 2
|
// Log with debug level 2
|
||||||
#if CFG_TUSB_DEBUG > 1
|
#if CFG_TUSB_DEBUG > 1
|
||||||
#define TU_LOG2 TU_LOG1
|
#define TU_LOG2 TU_LOG1
|
||||||
#define TU_LOG2_MEM TU_LOG1_MEM
|
#define TU_LOG2_MEM TU_LOG1_MEM
|
||||||
#define TU_LOG2_LOCATION() TU_LOG1_LOCATION()
|
#define TU_LOG2_LOCATION() TU_LOG1_LOCATION()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
char const * data;
|
char const * data;
|
||||||
}lookup_entry_t;
|
}lookup_entry_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t count;
|
uint16_t count;
|
||||||
lookup_entry_t const* items;
|
lookup_entry_t const* items;
|
||||||
} lookup_table_t;
|
} lookup_table_t;
|
||||||
|
|
||||||
static inline char const* lookup_find(lookup_table_t const* p_table, uint32_t key)
|
static inline char const* lookup_find(lookup_table_t const* p_table, uint32_t key)
|
||||||
{
|
{
|
||||||
for(uint16_t i=0; i<p_table->count; i++)
|
for(uint16_t i=0; i<p_table->count; i++)
|
||||||
{
|
{
|
||||||
if (p_table->items[i].key == key) return p_table->items[i].data;
|
if (p_table->items[i].key == key) return p_table->items[i].data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CFG_TUSB_DEBUG
|
#endif // CFG_TUSB_DEBUG
|
||||||
|
|
||||||
#ifndef TU_LOG1
|
#ifndef TU_LOG1
|
||||||
#define TU_LOG1(...)
|
#define TU_LOG1(...)
|
||||||
#define TU_LOG1_MEM(...)
|
#define TU_LOG1_MEM(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TU_LOG2
|
#ifndef TU_LOG2
|
||||||
#define TU_LOG2(...)
|
#define TU_LOG2(...)
|
||||||
#define TU_LOG2_MEM(...)
|
#define TU_LOG2_MEM(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_COMMON_H_ */
|
#endif /* _TUSB_COMMON_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,140 +1,140 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_Common
|
/** \ingroup Group_Common
|
||||||
* \defgroup Group_Compiler Compiler
|
* \defgroup Group_Compiler Compiler
|
||||||
* \brief Group_Compiler brief
|
* \brief Group_Compiler brief
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_COMPILER_H_
|
#ifndef _TUSB_COMPILER_H_
|
||||||
#define _TUSB_COMPILER_H_
|
#define _TUSB_COMPILER_H_
|
||||||
|
|
||||||
#define TU_STRING(x) #x ///< stringify without expand
|
#define TU_STRING(x) #x ///< stringify without expand
|
||||||
#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify
|
#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify
|
||||||
#define TU_STRCAT(a, b) a##b ///< concat without expand
|
#define TU_STRCAT(a, b) a##b ///< concat without expand
|
||||||
#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat
|
#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat
|
||||||
|
|
||||||
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
|
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
|
||||||
#define _TU_COUNTER_ __COUNTER__
|
#define _TU_COUNTER_ __COUNTER__
|
||||||
#else
|
#else
|
||||||
#define _TU_COUNTER_ __LINE__
|
#define _TU_COUNTER_ __LINE__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compile-time Assert
|
// Compile-time Assert
|
||||||
#if __STDC_VERSION__ >= 201112L
|
#if __STDC_VERSION__ >= 201112L
|
||||||
#define TU_VERIFY_STATIC _Static_assert
|
#define TU_VERIFY_STATIC _Static_assert
|
||||||
#else
|
#else
|
||||||
#define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
|
#define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// for declaration of reserved field, make use of _TU_COUNTER_
|
// for declaration of reserved field, make use of _TU_COUNTER_
|
||||||
#define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_)
|
#define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_)
|
||||||
|
|
||||||
#define TU_LITTLE_ENDIAN (0x12u)
|
#define TU_LITTLE_ENDIAN (0x12u)
|
||||||
#define TU_BIG_ENDIAN (0x21u)
|
#define TU_BIG_ENDIAN (0x21u)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Compiler porting with Attribute and Endian
|
// Compiler porting with Attribute and Endian
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
|
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
|
||||||
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
|
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
|
||||||
#define TU_ATTR_PACKED __attribute__ ((packed))
|
#define TU_ATTR_PACKED __attribute__ ((packed))
|
||||||
#define TU_ATTR_PREPACKED
|
#define TU_ATTR_PREPACKED
|
||||||
#define TU_ATTR_WEAK __attribute__ ((weak))
|
#define TU_ATTR_WEAK __attribute__ ((weak))
|
||||||
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
|
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
|
||||||
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
|
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
|
||||||
#define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used
|
#define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used
|
||||||
|
|
||||||
// Endian conversion use well-known host to network (big endian) naming
|
// Endian conversion use well-known host to network (big endian) naming
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
|
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
|
||||||
#else
|
#else
|
||||||
#define TU_BYTE_ORDER TU_BIG_ENDIAN
|
#define TU_BYTE_ORDER TU_BIG_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TU_BSWAP16(u16) (__builtin_bswap16(u16))
|
#define TU_BSWAP16(u16) (__builtin_bswap16(u16))
|
||||||
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
|
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
|
||||||
|
|
||||||
#elif defined(__TI_COMPILER_VERSION__)
|
#elif defined(__TI_COMPILER_VERSION__)
|
||||||
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
|
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
|
||||||
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
|
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
|
||||||
#define TU_ATTR_PACKED __attribute__ ((packed))
|
#define TU_ATTR_PACKED __attribute__ ((packed))
|
||||||
#define TU_ATTR_PREPACKED
|
#define TU_ATTR_PREPACKED
|
||||||
#define TU_ATTR_WEAK __attribute__ ((weak))
|
#define TU_ATTR_WEAK __attribute__ ((weak))
|
||||||
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
|
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
|
||||||
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
|
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
|
||||||
#define TU_ATTR_USED __attribute__ ((used))
|
#define TU_ATTR_USED __attribute__ ((used))
|
||||||
|
|
||||||
// __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian)
|
// __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian)
|
||||||
#if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__)
|
#if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__)
|
||||||
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
|
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
|
||||||
#else
|
#else
|
||||||
#define TU_BYTE_ORDER TU_BIG_ENDIAN
|
#define TU_BYTE_ORDER TU_BIG_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TU_BSWAP16(u16) (__builtin_bswap16(u16))
|
#define TU_BSWAP16(u16) (__builtin_bswap16(u16))
|
||||||
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
|
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Compiler attribute porting is required"
|
#error "Compiler attribute porting is required"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN)
|
#if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN)
|
||||||
|
|
||||||
#define tu_htons(u16) (TU_BSWAP16(u16))
|
#define tu_htons(u16) (TU_BSWAP16(u16))
|
||||||
#define tu_ntohs(u16) (TU_BSWAP16(u16))
|
#define tu_ntohs(u16) (TU_BSWAP16(u16))
|
||||||
|
|
||||||
#define tu_htonl(u32) (TU_BSWAP32(u32))
|
#define tu_htonl(u32) (TU_BSWAP32(u32))
|
||||||
#define tu_ntohl(u32) (TU_BSWAP32(u32))
|
#define tu_ntohl(u32) (TU_BSWAP32(u32))
|
||||||
|
|
||||||
#define tu_htole16(u16) (u16)
|
#define tu_htole16(u16) (u16)
|
||||||
#define tu_le16toh(u16) (u16)
|
#define tu_le16toh(u16) (u16)
|
||||||
|
|
||||||
#define tu_htole32(u32) (u32)
|
#define tu_htole32(u32) (u32)
|
||||||
#define tu_le32toh(u32) (u32)
|
#define tu_le32toh(u32) (u32)
|
||||||
|
|
||||||
#elif (TU_BYTE_ORDER == TU_BIG_ENDIAN)
|
#elif (TU_BYTE_ORDER == TU_BIG_ENDIAN)
|
||||||
|
|
||||||
#define tu_htons(u16) (u16)
|
#define tu_htons(u16) (u16)
|
||||||
#define tu_ntohs(u16) (u16)
|
#define tu_ntohs(u16) (u16)
|
||||||
|
|
||||||
#define tu_htonl(u32) (u32)
|
#define tu_htonl(u32) (u32)
|
||||||
#define tu_ntohl(u32) (u32)
|
#define tu_ntohl(u32) (u32)
|
||||||
|
|
||||||
#define tu_htole16(u16) (tu_bswap16(u16))
|
#define tu_htole16(u16) (tu_bswap16(u16))
|
||||||
#define tu_le16toh(u16) (tu_bswap16(u16))
|
#define tu_le16toh(u16) (tu_bswap16(u16))
|
||||||
|
|
||||||
#define tu_htole32(u32) (tu_bswap32(u32))
|
#define tu_htole32(u32) (tu_bswap32(u32))
|
||||||
#define tu_le32toh(u32) (tu_bswap32(u32))
|
#define tu_le32toh(u32) (tu_bswap32(u32))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error Byte order is undefined
|
#error Byte order is undefined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_COMPILER_H_ */
|
#endif /* _TUSB_COMPILER_H_ */
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -1,74 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_Common
|
/** \ingroup Group_Common
|
||||||
* \defgroup Group_Error Error Codes
|
* \defgroup Group_Error Error Codes
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_ERRORS_H_
|
#ifndef _TUSB_ERRORS_H_
|
||||||
#define _TUSB_ERRORS_H_
|
#define _TUSB_ERRORS_H_
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ERROR_ENUM(x) x,
|
#define ERROR_ENUM(x) x,
|
||||||
#define ERROR_STRING(x) #x,
|
#define ERROR_STRING(x) #x,
|
||||||
|
|
||||||
#define ERROR_TABLE(ENTRY) \
|
#define ERROR_TABLE(ENTRY) \
|
||||||
ENTRY(TUSB_ERROR_NONE )\
|
ENTRY(TUSB_ERROR_NONE )\
|
||||||
ENTRY(TUSB_ERROR_INVALID_PARA )\
|
ENTRY(TUSB_ERROR_INVALID_PARA )\
|
||||||
ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\
|
ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\
|
||||||
ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\
|
ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\
|
||||||
ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\
|
ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\
|
||||||
ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\
|
ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\
|
||||||
ENTRY(TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED )\
|
ENTRY(TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED )\
|
||||||
ENTRY(TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED )\
|
ENTRY(TUSB_ERROR_MSCH_DEVICE_NOT_MOUNTED )\
|
||||||
ENTRY(TUSB_ERROR_NOT_SUPPORTED )\
|
ENTRY(TUSB_ERROR_NOT_SUPPORTED )\
|
||||||
ENTRY(TUSB_ERROR_NOT_ENOUGH_MEMORY )\
|
ENTRY(TUSB_ERROR_NOT_ENOUGH_MEMORY )\
|
||||||
ENTRY(TUSB_ERROR_FAILED )\
|
ENTRY(TUSB_ERROR_FAILED )\
|
||||||
|
|
||||||
/// \brief Error Code returned
|
/// \brief Error Code returned
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
ERROR_TABLE(ERROR_ENUM)
|
ERROR_TABLE(ERROR_ENUM)
|
||||||
TUSB_ERROR_COUNT
|
TUSB_ERROR_COUNT
|
||||||
}tusb_error_t;
|
}tusb_error_t;
|
||||||
|
|
||||||
#if CFG_TUSB_DEBUG
|
#if CFG_TUSB_DEBUG
|
||||||
/// Enum to String for debugging purposes. Only available if \ref CFG_TUSB_DEBUG > 0
|
/// Enum to String for debugging purposes. Only available if \ref CFG_TUSB_DEBUG > 0
|
||||||
extern char const* const tusb_strerr[TUSB_ERROR_COUNT];
|
extern char const* const tusb_strerr[TUSB_ERROR_COUNT];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_ERRORS_H_ */
|
#endif /* _TUSB_ERRORS_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,288 +1,288 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "osal/osal.h"
|
#include "osal/osal.h"
|
||||||
#include "tusb_fifo.h"
|
#include "tusb_fifo.h"
|
||||||
|
|
||||||
// implement mutex lock and unlock
|
// implement mutex lock and unlock
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
|
|
||||||
static void tu_fifo_lock(tu_fifo_t *f)
|
static void tu_fifo_lock(tu_fifo_t *f)
|
||||||
{
|
{
|
||||||
if (f->mutex)
|
if (f->mutex)
|
||||||
{
|
{
|
||||||
osal_mutex_lock(f->mutex, OSAL_TIMEOUT_WAIT_FOREVER);
|
osal_mutex_lock(f->mutex, OSAL_TIMEOUT_WAIT_FOREVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tu_fifo_unlock(tu_fifo_t *f)
|
static void tu_fifo_unlock(tu_fifo_t *f)
|
||||||
{
|
{
|
||||||
if (f->mutex)
|
if (f->mutex)
|
||||||
{
|
{
|
||||||
osal_mutex_unlock(f->mutex);
|
osal_mutex_unlock(f->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define tu_fifo_lock(_ff)
|
#define tu_fifo_lock(_ff)
|
||||||
#define tu_fifo_unlock(_ff)
|
#define tu_fifo_unlock(_ff)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable)
|
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable)
|
||||||
{
|
{
|
||||||
tu_fifo_lock(f);
|
tu_fifo_lock(f);
|
||||||
|
|
||||||
f->buffer = (uint8_t*) buffer;
|
f->buffer = (uint8_t*) buffer;
|
||||||
f->depth = depth;
|
f->depth = depth;
|
||||||
f->item_size = item_size;
|
f->item_size = item_size;
|
||||||
f->overwritable = overwritable;
|
f->overwritable = overwritable;
|
||||||
|
|
||||||
f->rd_idx = f->wr_idx = f->count = 0;
|
f->rd_idx = f->wr_idx = f->count = 0;
|
||||||
|
|
||||||
tu_fifo_unlock(f);
|
tu_fifo_unlock(f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve data from fifo
|
// retrieve data from fifo
|
||||||
static void _tu_ff_pull(tu_fifo_t* f, void * buffer)
|
static void _tu_ff_pull(tu_fifo_t* f, void * buffer)
|
||||||
{
|
{
|
||||||
memcpy(buffer,
|
memcpy(buffer,
|
||||||
f->buffer + (f->rd_idx * f->item_size),
|
f->buffer + (f->rd_idx * f->item_size),
|
||||||
f->item_size);
|
f->item_size);
|
||||||
|
|
||||||
f->rd_idx = (f->rd_idx + 1) % f->depth;
|
f->rd_idx = (f->rd_idx + 1) % f->depth;
|
||||||
f->count--;
|
f->count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send data to fifo
|
// send data to fifo
|
||||||
static void _tu_ff_push(tu_fifo_t* f, void const * data)
|
static void _tu_ff_push(tu_fifo_t* f, void const * data)
|
||||||
{
|
{
|
||||||
memcpy( f->buffer + (f->wr_idx * f->item_size),
|
memcpy( f->buffer + (f->wr_idx * f->item_size),
|
||||||
data,
|
data,
|
||||||
f->item_size);
|
f->item_size);
|
||||||
|
|
||||||
f->wr_idx = (f->wr_idx + 1) % f->depth;
|
f->wr_idx = (f->wr_idx + 1) % f->depth;
|
||||||
|
|
||||||
if (tu_fifo_full(f))
|
if (tu_fifo_full(f))
|
||||||
{
|
{
|
||||||
f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size)
|
f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f->count++;
|
f->count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Read one byte out of the RX buffer.
|
@brief Read one byte out of the RX buffer.
|
||||||
|
|
||||||
This function will return the byte located at the array index of the
|
This function will return the byte located at the array index of the
|
||||||
read pointer, and then increment the read pointer index. If the read
|
read pointer, and then increment the read pointer index. If the read
|
||||||
pointer exceeds the maximum buffer size, it will roll over to zero.
|
pointer exceeds the maximum buffer size, it will roll over to zero.
|
||||||
|
|
||||||
@param[in] f
|
@param[in] f
|
||||||
Pointer to the FIFO buffer to manipulate
|
Pointer to the FIFO buffer to manipulate
|
||||||
@param[in] buffer
|
@param[in] buffer
|
||||||
Pointer to the place holder for data read from the buffer
|
Pointer to the place holder for data read from the buffer
|
||||||
|
|
||||||
@returns TRUE if the queue is not empty
|
@returns TRUE if the queue is not empty
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
bool tu_fifo_read(tu_fifo_t* f, void * buffer)
|
bool tu_fifo_read(tu_fifo_t* f, void * buffer)
|
||||||
{
|
{
|
||||||
if( tu_fifo_empty(f) ) return false;
|
if( tu_fifo_empty(f) ) return false;
|
||||||
|
|
||||||
tu_fifo_lock(f);
|
tu_fifo_lock(f);
|
||||||
|
|
||||||
_tu_ff_pull(f, buffer);
|
_tu_ff_pull(f, buffer);
|
||||||
|
|
||||||
tu_fifo_unlock(f);
|
tu_fifo_unlock(f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief This function will read n elements into the array index specified by
|
@brief This function will read n elements into the array index specified by
|
||||||
the write pointer and increment the write index. If the write index
|
the write pointer and increment the write index. If the write index
|
||||||
exceeds the max buffer size, then it will roll over to zero.
|
exceeds the max buffer size, then it will roll over to zero.
|
||||||
|
|
||||||
@param[in] f
|
@param[in] f
|
||||||
Pointer to the FIFO buffer to manipulate
|
Pointer to the FIFO buffer to manipulate
|
||||||
@param[in] buffer
|
@param[in] buffer
|
||||||
The pointer to data location
|
The pointer to data location
|
||||||
@param[in] count
|
@param[in] count
|
||||||
Number of element that buffer can afford
|
Number of element that buffer can afford
|
||||||
|
|
||||||
@returns number of items read from the FIFO
|
@returns number of items read from the FIFO
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
uint16_t tu_fifo_read_n (tu_fifo_t* f, void * buffer, uint16_t count)
|
uint16_t tu_fifo_read_n (tu_fifo_t* f, void * buffer, uint16_t count)
|
||||||
{
|
{
|
||||||
if( tu_fifo_empty(f) ) return 0;
|
if( tu_fifo_empty(f) ) return 0;
|
||||||
|
|
||||||
tu_fifo_lock(f);
|
tu_fifo_lock(f);
|
||||||
|
|
||||||
/* Limit up to fifo's count */
|
/* Limit up to fifo's count */
|
||||||
if ( count > f->count ) count = f->count;
|
if ( count > f->count ) count = f->count;
|
||||||
|
|
||||||
uint8_t* buf8 = (uint8_t*) buffer;
|
uint8_t* buf8 = (uint8_t*) buffer;
|
||||||
uint16_t len = 0;
|
uint16_t len = 0;
|
||||||
|
|
||||||
while (len < count)
|
while (len < count)
|
||||||
{
|
{
|
||||||
_tu_ff_pull(f, buf8);
|
_tu_ff_pull(f, buf8);
|
||||||
|
|
||||||
len++;
|
len++;
|
||||||
buf8 += f->item_size;
|
buf8 += f->item_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
tu_fifo_unlock(f);
|
tu_fifo_unlock(f);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Reads one item without removing it from the FIFO
|
@brief Reads one item without removing it from the FIFO
|
||||||
|
|
||||||
@param[in] f
|
@param[in] f
|
||||||
Pointer to the FIFO buffer to manipulate
|
Pointer to the FIFO buffer to manipulate
|
||||||
@param[in] pos
|
@param[in] pos
|
||||||
Position to read from in the FIFO buffer
|
Position to read from in the FIFO buffer
|
||||||
@param[in] p_buffer
|
@param[in] p_buffer
|
||||||
Pointer to the place holder for data read from the buffer
|
Pointer to the place holder for data read from the buffer
|
||||||
|
|
||||||
@returns TRUE if the queue is not empty
|
@returns TRUE if the queue is not empty
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t pos, void * p_buffer)
|
bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t pos, void * p_buffer)
|
||||||
{
|
{
|
||||||
if ( pos >= f->count ) return false;
|
if ( pos >= f->count ) return false;
|
||||||
|
|
||||||
// rd_idx is pos=0
|
// rd_idx is pos=0
|
||||||
uint16_t index = (f->rd_idx + pos) % f->depth;
|
uint16_t index = (f->rd_idx + pos) % f->depth;
|
||||||
memcpy(p_buffer,
|
memcpy(p_buffer,
|
||||||
f->buffer + (index * f->item_size),
|
f->buffer + (index * f->item_size),
|
||||||
f->item_size);
|
f->item_size);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Write one element into the RX buffer.
|
@brief Write one element into the RX buffer.
|
||||||
|
|
||||||
This function will write one element into the array index specified by
|
This function will write one element into the array index specified by
|
||||||
the write pointer and increment the write index. If the write index
|
the write pointer and increment the write index. If the write index
|
||||||
exceeds the max buffer size, then it will roll over to zero.
|
exceeds the max buffer size, then it will roll over to zero.
|
||||||
|
|
||||||
@param[in] f
|
@param[in] f
|
||||||
Pointer to the FIFO buffer to manipulate
|
Pointer to the FIFO buffer to manipulate
|
||||||
@param[in] data
|
@param[in] data
|
||||||
The byte to add to the FIFO
|
The byte to add to the FIFO
|
||||||
|
|
||||||
@returns TRUE if the data was written to the FIFO (overwrittable
|
@returns TRUE if the data was written to the FIFO (overwrittable
|
||||||
FIFO will always return TRUE)
|
FIFO will always return TRUE)
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
bool tu_fifo_write (tu_fifo_t* f, const void * data)
|
bool tu_fifo_write (tu_fifo_t* f, const void * data)
|
||||||
{
|
{
|
||||||
if ( tu_fifo_full(f) && !f->overwritable ) return false;
|
if ( tu_fifo_full(f) && !f->overwritable ) return false;
|
||||||
|
|
||||||
tu_fifo_lock(f);
|
tu_fifo_lock(f);
|
||||||
|
|
||||||
_tu_ff_push(f, data);
|
_tu_ff_push(f, data);
|
||||||
|
|
||||||
tu_fifo_unlock(f);
|
tu_fifo_unlock(f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief This function will write n elements into the array index specified by
|
@brief This function will write n elements into the array index specified by
|
||||||
the write pointer and increment the write index. If the write index
|
the write pointer and increment the write index. If the write index
|
||||||
exceeds the max buffer size, then it will roll over to zero.
|
exceeds the max buffer size, then it will roll over to zero.
|
||||||
|
|
||||||
@param[in] f
|
@param[in] f
|
||||||
Pointer to the FIFO buffer to manipulate
|
Pointer to the FIFO buffer to manipulate
|
||||||
@param[in] data
|
@param[in] data
|
||||||
The pointer to data to add to the FIFO
|
The pointer to data to add to the FIFO
|
||||||
@param[in] count
|
@param[in] count
|
||||||
Number of element
|
Number of element
|
||||||
@return Number of written elements
|
@return Number of written elements
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
uint16_t tu_fifo_write_n (tu_fifo_t* f, const void * data, uint16_t count)
|
uint16_t tu_fifo_write_n (tu_fifo_t* f, const void * data, uint16_t count)
|
||||||
{
|
{
|
||||||
if ( count == 0 ) return 0;
|
if ( count == 0 ) return 0;
|
||||||
|
|
||||||
tu_fifo_lock(f);
|
tu_fifo_lock(f);
|
||||||
|
|
||||||
// Not overwritable limit up to full
|
// Not overwritable limit up to full
|
||||||
if (!f->overwritable) count = tu_min16(count, tu_fifo_remaining(f));
|
if (!f->overwritable) count = tu_min16(count, tu_fifo_remaining(f));
|
||||||
|
|
||||||
uint8_t const* buf8 = (uint8_t const*) data;
|
uint8_t const* buf8 = (uint8_t const*) data;
|
||||||
uint16_t len = 0;
|
uint16_t len = 0;
|
||||||
|
|
||||||
while (len < count)
|
while (len < count)
|
||||||
{
|
{
|
||||||
_tu_ff_push(f, buf8);
|
_tu_ff_push(f, buf8);
|
||||||
|
|
||||||
len++;
|
len++;
|
||||||
buf8 += f->item_size;
|
buf8 += f->item_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
tu_fifo_unlock(f);
|
tu_fifo_unlock(f);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Clear the fifo read and write pointers and set length to zero
|
@brief Clear the fifo read and write pointers and set length to zero
|
||||||
|
|
||||||
@param[in] f
|
@param[in] f
|
||||||
Pointer to the FIFO buffer to manipulate
|
Pointer to the FIFO buffer to manipulate
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
bool tu_fifo_clear(tu_fifo_t *f)
|
bool tu_fifo_clear(tu_fifo_t *f)
|
||||||
{
|
{
|
||||||
tu_fifo_lock(f);
|
tu_fifo_lock(f);
|
||||||
|
|
||||||
f->rd_idx = f->wr_idx = f->count = 0;
|
f->rd_idx = f->wr_idx = f->count = 0;
|
||||||
|
|
||||||
tu_fifo_unlock(f);
|
tu_fifo_unlock(f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,131 +1,131 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_Common
|
/** \ingroup Group_Common
|
||||||
* \defgroup group_fifo fifo
|
* \defgroup group_fifo fifo
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_FIFO_H_
|
#ifndef _TUSB_FIFO_H_
|
||||||
#define _TUSB_FIFO_H_
|
#define _TUSB_FIFO_H_
|
||||||
|
|
||||||
// mutex is only needed for RTOS
|
// mutex is only needed for RTOS
|
||||||
// for OS None, we don't get preempted
|
// for OS None, we don't get preempted
|
||||||
#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE)
|
#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
#define tu_fifo_mutex_t osal_mutex_t
|
#define tu_fifo_mutex_t osal_mutex_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** \struct tu_fifo_t
|
/** \struct tu_fifo_t
|
||||||
* \brief Simple Circular FIFO
|
* \brief Simple Circular FIFO
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t* buffer ; ///< buffer pointer
|
uint8_t* buffer ; ///< buffer pointer
|
||||||
uint16_t depth ; ///< max items
|
uint16_t depth ; ///< max items
|
||||||
uint16_t item_size ; ///< size of each item
|
uint16_t item_size ; ///< size of each item
|
||||||
bool overwritable ;
|
bool overwritable ;
|
||||||
|
|
||||||
volatile uint16_t count ; ///< number of items in queue
|
volatile uint16_t count ; ///< number of items in queue
|
||||||
volatile uint16_t wr_idx ; ///< write pointer
|
volatile uint16_t wr_idx ; ///< write pointer
|
||||||
volatile uint16_t rd_idx ; ///< read pointer
|
volatile uint16_t rd_idx ; ///< read pointer
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
tu_fifo_mutex_t mutex;
|
tu_fifo_mutex_t mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} tu_fifo_t;
|
} tu_fifo_t;
|
||||||
|
|
||||||
#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
|
#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
|
||||||
uint8_t _name##_buf[_depth*sizeof(_type)]; \
|
uint8_t _name##_buf[_depth*sizeof(_type)]; \
|
||||||
tu_fifo_t _name = { \
|
tu_fifo_t _name = { \
|
||||||
.buffer = _name##_buf, \
|
.buffer = _name##_buf, \
|
||||||
.depth = _depth, \
|
.depth = _depth, \
|
||||||
.item_size = sizeof(_type), \
|
.item_size = sizeof(_type), \
|
||||||
.overwritable = _overwritable, \
|
.overwritable = _overwritable, \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tu_fifo_clear(tu_fifo_t *f);
|
bool tu_fifo_clear(tu_fifo_t *f);
|
||||||
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
|
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
|
||||||
|
|
||||||
#if CFG_FIFO_MUTEX
|
#if CFG_FIFO_MUTEX
|
||||||
static inline void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t mutex_hdl)
|
static inline void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t mutex_hdl)
|
||||||
{
|
{
|
||||||
f->mutex = mutex_hdl;
|
f->mutex = mutex_hdl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool tu_fifo_write (tu_fifo_t* f, void const * p_data);
|
bool tu_fifo_write (tu_fifo_t* f, void const * p_data);
|
||||||
uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t count);
|
uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t count);
|
||||||
|
|
||||||
bool tu_fifo_read (tu_fifo_t* f, void * p_buffer);
|
bool tu_fifo_read (tu_fifo_t* f, void * p_buffer);
|
||||||
uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t count);
|
uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t count);
|
||||||
|
|
||||||
bool tu_fifo_peek_at (tu_fifo_t* f, uint16_t pos, void * p_buffer);
|
bool tu_fifo_peek_at (tu_fifo_t* f, uint16_t pos, void * p_buffer);
|
||||||
|
|
||||||
static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer)
|
static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer)
|
||||||
{
|
{
|
||||||
return tu_fifo_peek_at(f, 0, p_buffer);
|
return tu_fifo_peek_at(f, 0, p_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tu_fifo_empty(tu_fifo_t* f)
|
static inline bool tu_fifo_empty(tu_fifo_t* f)
|
||||||
{
|
{
|
||||||
return (f->count == 0);
|
return (f->count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tu_fifo_full(tu_fifo_t* f)
|
static inline bool tu_fifo_full(tu_fifo_t* f)
|
||||||
{
|
{
|
||||||
return (f->count == f->depth);
|
return (f->count == f->depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t tu_fifo_count(tu_fifo_t* f)
|
static inline uint16_t tu_fifo_count(tu_fifo_t* f)
|
||||||
{
|
{
|
||||||
return f->count;
|
return f->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t tu_fifo_remaining(tu_fifo_t* f)
|
static inline uint16_t tu_fifo_remaining(tu_fifo_t* f)
|
||||||
{
|
{
|
||||||
return f->depth - f->count;
|
return f->depth - f->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t tu_fifo_depth(tu_fifo_t* f)
|
static inline uint16_t tu_fifo_depth(tu_fifo_t* f)
|
||||||
{
|
{
|
||||||
return f->depth;
|
return f->depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_FIFO_H_ */
|
#endif /* _TUSB_FIFO_H_ */
|
||||||
|
@ -1,80 +1,80 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_Common Common Files
|
/** \ingroup Group_Common Common Files
|
||||||
* \defgroup Group_TimeoutTimer timeout timer
|
* \defgroup Group_TimeoutTimer timeout timer
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_TIMEOUT_H_
|
#ifndef _TUSB_TIMEOUT_H_
|
||||||
#define _TUSB_TIMEOUT_H_
|
#define _TUSB_TIMEOUT_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t start;
|
uint32_t start;
|
||||||
uint32_t interval;
|
uint32_t interval;
|
||||||
}tu_timeout_t;
|
}tu_timeout_t;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
extern uint32_t tusb_hal_millis(void);
|
extern uint32_t tusb_hal_millis(void);
|
||||||
|
|
||||||
static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec)
|
static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec)
|
||||||
{
|
{
|
||||||
tt->interval = msec;
|
tt->interval = msec;
|
||||||
tt->start = tusb_hal_millis();
|
tt->start = tusb_hal_millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool tu_timeout_expired(tu_timeout_t* tt)
|
static inline bool tu_timeout_expired(tu_timeout_t* tt)
|
||||||
{
|
{
|
||||||
return ( tusb_hal_millis() - tt->start ) >= tt->interval;
|
return ( tusb_hal_millis() - tt->start ) >= tt->interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For used with periodic event to prevent drift
|
// For used with periodic event to prevent drift
|
||||||
static inline void tu_timeout_reset(tu_timeout_t* tt)
|
static inline void tu_timeout_reset(tu_timeout_t* tt)
|
||||||
{
|
{
|
||||||
tt->start += tt->interval;
|
tt->start += tt->interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tu_timeout_restart(tu_timeout_t* tt)
|
static inline void tu_timeout_restart(tu_timeout_t* tt)
|
||||||
{
|
{
|
||||||
tt->start = tusb_hal_millis();
|
tt->start = tusb_hal_millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_TIMEOUT_H_ */
|
#endif /* _TUSB_TIMEOUT_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,481 +1,481 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_usb_definitions
|
/** \ingroup group_usb_definitions
|
||||||
* \defgroup USBDef_Type USB Types
|
* \defgroup USBDef_Type USB Types
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_TYPES_H_
|
#ifndef _TUSB_TYPES_H_
|
||||||
#define _TUSB_TYPES_H_
|
#define _TUSB_TYPES_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "tusb_compiler.h"
|
#include "tusb_compiler.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* CONSTANTS
|
/* CONSTANTS
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
/// defined base on EHCI specs value for Endpoint Speed
|
/// defined base on EHCI specs value for Endpoint Speed
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_SPEED_FULL = 0,
|
TUSB_SPEED_FULL = 0,
|
||||||
TUSB_SPEED_LOW ,
|
TUSB_SPEED_LOW ,
|
||||||
TUSB_SPEED_HIGH
|
TUSB_SPEED_HIGH
|
||||||
}tusb_speed_t;
|
}tusb_speed_t;
|
||||||
|
|
||||||
/// defined base on USB Specs Endpoint's bmAttributes
|
/// defined base on USB Specs Endpoint's bmAttributes
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_XFER_CONTROL = 0 ,
|
TUSB_XFER_CONTROL = 0 ,
|
||||||
TUSB_XFER_ISOCHRONOUS ,
|
TUSB_XFER_ISOCHRONOUS ,
|
||||||
TUSB_XFER_BULK ,
|
TUSB_XFER_BULK ,
|
||||||
TUSB_XFER_INTERRUPT
|
TUSB_XFER_INTERRUPT
|
||||||
}tusb_xfer_type_t;
|
}tusb_xfer_type_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_DIR_OUT = 0,
|
TUSB_DIR_OUT = 0,
|
||||||
TUSB_DIR_IN = 1,
|
TUSB_DIR_IN = 1,
|
||||||
|
|
||||||
TUSB_DIR_IN_MASK = 0x80
|
TUSB_DIR_IN_MASK = 0x80
|
||||||
}tusb_dir_t;
|
}tusb_dir_t;
|
||||||
|
|
||||||
/// USB Descriptor Types
|
/// USB Descriptor Types
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_DESC_DEVICE = 0x01,
|
TUSB_DESC_DEVICE = 0x01,
|
||||||
TUSB_DESC_CONFIGURATION = 0x02,
|
TUSB_DESC_CONFIGURATION = 0x02,
|
||||||
TUSB_DESC_STRING = 0x03,
|
TUSB_DESC_STRING = 0x03,
|
||||||
TUSB_DESC_INTERFACE = 0x04,
|
TUSB_DESC_INTERFACE = 0x04,
|
||||||
TUSB_DESC_ENDPOINT = 0x05,
|
TUSB_DESC_ENDPOINT = 0x05,
|
||||||
TUSB_DESC_DEVICE_QUALIFIER = 0x06,
|
TUSB_DESC_DEVICE_QUALIFIER = 0x06,
|
||||||
TUSB_DESC_OTHER_SPEED_CONFIG = 0x07,
|
TUSB_DESC_OTHER_SPEED_CONFIG = 0x07,
|
||||||
TUSB_DESC_INTERFACE_POWER = 0x08,
|
TUSB_DESC_INTERFACE_POWER = 0x08,
|
||||||
TUSB_DESC_OTG = 0x09,
|
TUSB_DESC_OTG = 0x09,
|
||||||
TUSB_DESC_DEBUG = 0x0A,
|
TUSB_DESC_DEBUG = 0x0A,
|
||||||
TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B,
|
TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B,
|
||||||
|
|
||||||
TUSB_DESC_BOS = 0x0F,
|
TUSB_DESC_BOS = 0x0F,
|
||||||
TUSB_DESC_DEVICE_CAPABILITY = 0x10,
|
TUSB_DESC_DEVICE_CAPABILITY = 0x10,
|
||||||
|
|
||||||
TUSB_DESC_FUNCTIONAL = 0x21,
|
TUSB_DESC_FUNCTIONAL = 0x21,
|
||||||
|
|
||||||
// Class Specific Descriptor
|
// Class Specific Descriptor
|
||||||
TUSB_DESC_CS_DEVICE = 0x21,
|
TUSB_DESC_CS_DEVICE = 0x21,
|
||||||
TUSB_DESC_CS_CONFIGURATION = 0x22,
|
TUSB_DESC_CS_CONFIGURATION = 0x22,
|
||||||
TUSB_DESC_CS_STRING = 0x23,
|
TUSB_DESC_CS_STRING = 0x23,
|
||||||
TUSB_DESC_CS_INTERFACE = 0x24,
|
TUSB_DESC_CS_INTERFACE = 0x24,
|
||||||
TUSB_DESC_CS_ENDPOINT = 0x25,
|
TUSB_DESC_CS_ENDPOINT = 0x25,
|
||||||
|
|
||||||
TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30,
|
TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30,
|
||||||
TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31
|
TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31
|
||||||
}tusb_desc_type_t;
|
}tusb_desc_type_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_REQ_GET_STATUS = 0 ,
|
TUSB_REQ_GET_STATUS = 0 ,
|
||||||
TUSB_REQ_CLEAR_FEATURE = 1 ,
|
TUSB_REQ_CLEAR_FEATURE = 1 ,
|
||||||
TUSB_REQ_RESERVED = 2 ,
|
TUSB_REQ_RESERVED = 2 ,
|
||||||
TUSB_REQ_SET_FEATURE = 3 ,
|
TUSB_REQ_SET_FEATURE = 3 ,
|
||||||
TUSB_REQ_RESERVED2 = 4 ,
|
TUSB_REQ_RESERVED2 = 4 ,
|
||||||
TUSB_REQ_SET_ADDRESS = 5 ,
|
TUSB_REQ_SET_ADDRESS = 5 ,
|
||||||
TUSB_REQ_GET_DESCRIPTOR = 6 ,
|
TUSB_REQ_GET_DESCRIPTOR = 6 ,
|
||||||
TUSB_REQ_SET_DESCRIPTOR = 7 ,
|
TUSB_REQ_SET_DESCRIPTOR = 7 ,
|
||||||
TUSB_REQ_GET_CONFIGURATION = 8 ,
|
TUSB_REQ_GET_CONFIGURATION = 8 ,
|
||||||
TUSB_REQ_SET_CONFIGURATION = 9 ,
|
TUSB_REQ_SET_CONFIGURATION = 9 ,
|
||||||
TUSB_REQ_GET_INTERFACE = 10 ,
|
TUSB_REQ_GET_INTERFACE = 10 ,
|
||||||
TUSB_REQ_SET_INTERFACE = 11 ,
|
TUSB_REQ_SET_INTERFACE = 11 ,
|
||||||
TUSB_REQ_SYNCH_FRAME = 12
|
TUSB_REQ_SYNCH_FRAME = 12
|
||||||
}tusb_request_code_t;
|
}tusb_request_code_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_REQ_FEATURE_EDPT_HALT = 0,
|
TUSB_REQ_FEATURE_EDPT_HALT = 0,
|
||||||
TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1,
|
TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1,
|
||||||
TUSB_REQ_FEATURE_TEST_MODE = 2
|
TUSB_REQ_FEATURE_TEST_MODE = 2
|
||||||
}tusb_request_feature_selector_t;
|
}tusb_request_feature_selector_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_REQ_TYPE_STANDARD = 0,
|
TUSB_REQ_TYPE_STANDARD = 0,
|
||||||
TUSB_REQ_TYPE_CLASS,
|
TUSB_REQ_TYPE_CLASS,
|
||||||
TUSB_REQ_TYPE_VENDOR,
|
TUSB_REQ_TYPE_VENDOR,
|
||||||
TUSB_REQ_TYPE_INVALID
|
TUSB_REQ_TYPE_INVALID
|
||||||
} tusb_request_type_t;
|
} tusb_request_type_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_REQ_RCPT_DEVICE =0,
|
TUSB_REQ_RCPT_DEVICE =0,
|
||||||
TUSB_REQ_RCPT_INTERFACE,
|
TUSB_REQ_RCPT_INTERFACE,
|
||||||
TUSB_REQ_RCPT_ENDPOINT,
|
TUSB_REQ_RCPT_ENDPOINT,
|
||||||
TUSB_REQ_RCPT_OTHER
|
TUSB_REQ_RCPT_OTHER
|
||||||
} tusb_request_recipient_t;
|
} tusb_request_recipient_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_CLASS_UNSPECIFIED = 0 ,
|
TUSB_CLASS_UNSPECIFIED = 0 ,
|
||||||
TUSB_CLASS_AUDIO = 1 ,
|
TUSB_CLASS_AUDIO = 1 ,
|
||||||
TUSB_CLASS_CDC = 2 ,
|
TUSB_CLASS_CDC = 2 ,
|
||||||
TUSB_CLASS_HID = 3 ,
|
TUSB_CLASS_HID = 3 ,
|
||||||
TUSB_CLASS_RESERVED_4 = 4 ,
|
TUSB_CLASS_RESERVED_4 = 4 ,
|
||||||
TUSB_CLASS_PHYSICAL = 5 ,
|
TUSB_CLASS_PHYSICAL = 5 ,
|
||||||
TUSB_CLASS_IMAGE = 6 ,
|
TUSB_CLASS_IMAGE = 6 ,
|
||||||
TUSB_CLASS_PRINTER = 7 ,
|
TUSB_CLASS_PRINTER = 7 ,
|
||||||
TUSB_CLASS_MSC = 8 ,
|
TUSB_CLASS_MSC = 8 ,
|
||||||
TUSB_CLASS_HUB = 9 ,
|
TUSB_CLASS_HUB = 9 ,
|
||||||
TUSB_CLASS_CDC_DATA = 10 ,
|
TUSB_CLASS_CDC_DATA = 10 ,
|
||||||
TUSB_CLASS_SMART_CARD = 11 ,
|
TUSB_CLASS_SMART_CARD = 11 ,
|
||||||
TUSB_CLASS_RESERVED_12 = 12 ,
|
TUSB_CLASS_RESERVED_12 = 12 ,
|
||||||
TUSB_CLASS_CONTENT_SECURITY = 13 ,
|
TUSB_CLASS_CONTENT_SECURITY = 13 ,
|
||||||
TUSB_CLASS_VIDEO = 14 ,
|
TUSB_CLASS_VIDEO = 14 ,
|
||||||
TUSB_CLASS_PERSONAL_HEALTHCARE = 15 ,
|
TUSB_CLASS_PERSONAL_HEALTHCARE = 15 ,
|
||||||
TUSB_CLASS_AUDIO_VIDEO = 16 ,
|
TUSB_CLASS_AUDIO_VIDEO = 16 ,
|
||||||
|
|
||||||
TUSB_CLASS_DIAGNOSTIC = 0xDC ,
|
TUSB_CLASS_DIAGNOSTIC = 0xDC ,
|
||||||
TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0 ,
|
TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0 ,
|
||||||
TUSB_CLASS_MISC = 0xEF ,
|
TUSB_CLASS_MISC = 0xEF ,
|
||||||
TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE ,
|
TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE ,
|
||||||
TUSB_CLASS_VENDOR_SPECIFIC = 0xFF
|
TUSB_CLASS_VENDOR_SPECIFIC = 0xFF
|
||||||
}tusb_class_code_t;
|
}tusb_class_code_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MISC_SUBCLASS_COMMON = 2
|
MISC_SUBCLASS_COMMON = 2
|
||||||
}misc_subclass_type_t;
|
}misc_subclass_type_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MISC_PROTOCOL_IAD = 1
|
MISC_PROTOCOL_IAD = 1
|
||||||
}misc_protocol_type_t;
|
}misc_protocol_type_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DEVICE_CAPABILITY_WIRELESS_USB = 0x01,
|
DEVICE_CAPABILITY_WIRELESS_USB = 0x01,
|
||||||
DEVICE_CAPABILITY_USB20_EXTENSION = 0x02,
|
DEVICE_CAPABILITY_USB20_EXTENSION = 0x02,
|
||||||
DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03,
|
DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03,
|
||||||
DEVICE_CAPABILITY_CONTAINER_id = 0x04,
|
DEVICE_CAPABILITY_CONTAINER_id = 0x04,
|
||||||
DEVICE_CAPABILITY_PLATFORM = 0x05,
|
DEVICE_CAPABILITY_PLATFORM = 0x05,
|
||||||
DEVICE_CAPABILITY_POWER_DELIVERY = 0x06,
|
DEVICE_CAPABILITY_POWER_DELIVERY = 0x06,
|
||||||
DEVICE_CAPABILITY_BATTERY_INFO = 0x07,
|
DEVICE_CAPABILITY_BATTERY_INFO = 0x07,
|
||||||
DEVICE_CAPABILITY_PD_CONSUMER_PORT = 0x08,
|
DEVICE_CAPABILITY_PD_CONSUMER_PORT = 0x08,
|
||||||
DEVICE_CAPABILITY_PD_PROVIDER_PORT = 0x09,
|
DEVICE_CAPABILITY_PD_PROVIDER_PORT = 0x09,
|
||||||
DEVICE_CAPABILITY_SUPERSPEED_PLUS = 0x0A,
|
DEVICE_CAPABILITY_SUPERSPEED_PLUS = 0x0A,
|
||||||
DEVICE_CAPABILITY_PRECESION_TIME_MEASUREMENT = 0x0B,
|
DEVICE_CAPABILITY_PRECESION_TIME_MEASUREMENT = 0x0B,
|
||||||
DEVICE_CAPABILITY_WIRELESS_USB_EXT = 0x0C,
|
DEVICE_CAPABILITY_WIRELESS_USB_EXT = 0x0C,
|
||||||
DEVICE_CAPABILITY_BILLBOARD = 0x0D,
|
DEVICE_CAPABILITY_BILLBOARD = 0x0D,
|
||||||
DEVICE_CAPABILITY_AUTHENTICATION = 0x0E,
|
DEVICE_CAPABILITY_AUTHENTICATION = 0x0E,
|
||||||
DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F,
|
DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F,
|
||||||
DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10
|
DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10
|
||||||
}device_capability_type_t;
|
}device_capability_type_t;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5),
|
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5),
|
||||||
TUSB_DESC_CONFIG_ATT_SELF_POWERED = TU_BIT(6),
|
TUSB_DESC_CONFIG_ATT_SELF_POWERED = TU_BIT(6),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2)
|
#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2)
|
||||||
|
|
||||||
/// Device State TODO remove
|
/// Device State TODO remove
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TUSB_DEVICE_STATE_UNPLUG = 0 ,
|
TUSB_DEVICE_STATE_UNPLUG = 0 ,
|
||||||
TUSB_DEVICE_STATE_CONFIGURED ,
|
TUSB_DEVICE_STATE_CONFIGURED ,
|
||||||
TUSB_DEVICE_STATE_SUSPENDED ,
|
TUSB_DEVICE_STATE_SUSPENDED ,
|
||||||
}tusb_device_state_t;
|
}tusb_device_state_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
XFER_RESULT_SUCCESS,
|
XFER_RESULT_SUCCESS,
|
||||||
XFER_RESULT_FAILED,
|
XFER_RESULT_FAILED,
|
||||||
XFER_RESULT_STALLED,
|
XFER_RESULT_STALLED,
|
||||||
}xfer_result_t;
|
}xfer_result_t;
|
||||||
|
|
||||||
enum // TODO remove
|
enum // TODO remove
|
||||||
{
|
{
|
||||||
DESC_OFFSET_LEN = 0,
|
DESC_OFFSET_LEN = 0,
|
||||||
DESC_OFFSET_TYPE = 1
|
DESC_OFFSET_TYPE = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
INTERFACE_INVALID_NUMBER = 0xff
|
INTERFACE_INVALID_NUMBER = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00,
|
MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00,
|
||||||
MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01,
|
MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01,
|
||||||
MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02,
|
MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02,
|
||||||
MS_OS_20_FEATURE_COMPATBLE_ID = 0x03,
|
MS_OS_20_FEATURE_COMPATBLE_ID = 0x03,
|
||||||
MS_OS_20_FEATURE_REG_PROPERTY = 0x04,
|
MS_OS_20_FEATURE_REG_PROPERTY = 0x04,
|
||||||
MS_OS_20_FEATURE_MIN_RESUME_TIME = 0x05,
|
MS_OS_20_FEATURE_MIN_RESUME_TIME = 0x05,
|
||||||
MS_OS_20_FEATURE_MODEL_ID = 0x06,
|
MS_OS_20_FEATURE_MODEL_ID = 0x06,
|
||||||
MS_OS_20_FEATURE_CCGP_DEVICE = 0x07,
|
MS_OS_20_FEATURE_CCGP_DEVICE = 0x07,
|
||||||
MS_OS_20_FEATURE_VENDOR_REVISION = 0x08
|
MS_OS_20_FEATURE_VENDOR_REVISION = 0x08
|
||||||
} microsoft_os_20_type_t;
|
} microsoft_os_20_type_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USB Descriptors
|
// USB Descriptors
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// USB Device Descriptor
|
/// USB Device Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||||
uint8_t bDescriptorType ; ///< DEVICE Descriptor Type.
|
uint8_t bDescriptorType ; ///< DEVICE Descriptor Type.
|
||||||
uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant.
|
uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant.
|
||||||
|
|
||||||
uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific.
|
uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific.
|
||||||
uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
|
uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
|
||||||
uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis.
|
uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis.
|
||||||
uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64.
|
uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64.
|
||||||
|
|
||||||
uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF).
|
uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF).
|
||||||
uint16_t idProduct ; ///< Product ID (assigned by the manufacturer).
|
uint16_t idProduct ; ///< Product ID (assigned by the manufacturer).
|
||||||
uint16_t bcdDevice ; ///< Device release number in binary-coded decimal.
|
uint16_t bcdDevice ; ///< Device release number in binary-coded decimal.
|
||||||
uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer.
|
uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer.
|
||||||
uint8_t iProduct ; ///< Index of string descriptor describing product.
|
uint8_t iProduct ; ///< Index of string descriptor describing product.
|
||||||
uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number.
|
uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number.
|
||||||
|
|
||||||
uint8_t bNumConfigurations ; ///< Number of possible configurations.
|
uint8_t bNumConfigurations ; ///< Number of possible configurations.
|
||||||
} tusb_desc_device_t;
|
} tusb_desc_device_t;
|
||||||
|
|
||||||
// USB Binary Device Object Store (BOS) Descriptor
|
// USB Binary Device Object Store (BOS) Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes
|
uint8_t bLength ; ///< Size of this descriptor in bytes
|
||||||
uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
|
uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
|
||||||
uint16_t wTotalLength ; ///< Total length of data returned for this descriptor
|
uint16_t wTotalLength ; ///< Total length of data returned for this descriptor
|
||||||
uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS
|
uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS
|
||||||
} tusb_desc_bos_t;
|
} tusb_desc_bos_t;
|
||||||
|
|
||||||
/// USB Configuration Descriptor
|
/// USB Configuration Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes
|
uint8_t bLength ; ///< Size of this descriptor in bytes
|
||||||
uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
|
uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
|
||||||
uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration.
|
uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration.
|
||||||
|
|
||||||
uint8_t bNumInterfaces ; ///< Number of interfaces supported by this configuration
|
uint8_t bNumInterfaces ; ///< Number of interfaces supported by this configuration
|
||||||
uint8_t bConfigurationValue ; ///< Value to use as an argument to the SetConfiguration() request to select this configuration.
|
uint8_t bConfigurationValue ; ///< Value to use as an argument to the SetConfiguration() request to select this configuration.
|
||||||
uint8_t iConfiguration ; ///< Index of string descriptor describing this configuration
|
uint8_t iConfiguration ; ///< Index of string descriptor describing this configuration
|
||||||
uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one.
|
uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one.
|
||||||
uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA).
|
uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA).
|
||||||
} tusb_desc_configuration_t;
|
} tusb_desc_configuration_t;
|
||||||
|
|
||||||
/// USB Interface Descriptor
|
/// USB Interface Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes
|
uint8_t bLength ; ///< Size of this descriptor in bytes
|
||||||
uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type
|
uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type
|
||||||
|
|
||||||
uint8_t bInterfaceNumber ; ///< Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration.
|
uint8_t bInterfaceNumber ; ///< Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration.
|
||||||
uint8_t bAlternateSetting ; ///< Value used to select this alternate setting for the interface identified in the prior field
|
uint8_t bAlternateSetting ; ///< Value used to select this alternate setting for the interface identified in the prior field
|
||||||
uint8_t bNumEndpoints ; ///< Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe.
|
uint8_t bNumEndpoints ; ///< Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe.
|
||||||
uint8_t bInterfaceClass ; ///< Class code (assigned by the USB-IF). \li A value of zero is reserved for future standardization. \li If this field is set to FFH, the interface class is vendor-specific. \li All other values are reserved for assignment by the USB-IF.
|
uint8_t bInterfaceClass ; ///< Class code (assigned by the USB-IF). \li A value of zero is reserved for future standardization. \li If this field is set to FFH, the interface class is vendor-specific. \li All other values are reserved for assignment by the USB-IF.
|
||||||
uint8_t bInterfaceSubClass ; ///< Subclass code (assigned by the USB-IF). \n These codes are qualified by the value of the bInterfaceClass field. \li If the bInterfaceClass field is reset to zero, this field must also be reset to zero. \li If the bInterfaceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
|
uint8_t bInterfaceSubClass ; ///< Subclass code (assigned by the USB-IF). \n These codes are qualified by the value of the bInterfaceClass field. \li If the bInterfaceClass field is reset to zero, this field must also be reset to zero. \li If the bInterfaceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
|
||||||
uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface.
|
uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface.
|
||||||
uint8_t iInterface ; ///< Index of string descriptor describing this interface
|
uint8_t iInterface ; ///< Index of string descriptor describing this interface
|
||||||
} tusb_desc_interface_t;
|
} tusb_desc_interface_t;
|
||||||
|
|
||||||
/// USB Endpoint Descriptor
|
/// USB Endpoint Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes
|
uint8_t bLength ; ///< Size of this descriptor in bytes
|
||||||
uint8_t bDescriptorType ; ///< ENDPOINT Descriptor Type
|
uint8_t bDescriptorType ; ///< ENDPOINT Descriptor Type
|
||||||
|
|
||||||
uint8_t bEndpointAddress ; ///< The address of the endpoint on the USB device described by this descriptor. The address is encoded as follows: \n Bit 3...0: The endpoint number \n Bit 6...4: Reserved, reset to zero \n Bit 7: Direction, ignored for control endpoints 0 = OUT endpoint 1 = IN endpoint.
|
uint8_t bEndpointAddress ; ///< The address of the endpoint on the USB device described by this descriptor. The address is encoded as follows: \n Bit 3...0: The endpoint number \n Bit 6...4: Reserved, reset to zero \n Bit 7: Direction, ignored for control endpoints 0 = OUT endpoint 1 = IN endpoint.
|
||||||
|
|
||||||
struct TU_ATTR_PACKED {
|
struct TU_ATTR_PACKED {
|
||||||
uint8_t xfer : 2;
|
uint8_t xfer : 2;
|
||||||
uint8_t sync : 2;
|
uint8_t sync : 2;
|
||||||
uint8_t usage : 2;
|
uint8_t usage : 2;
|
||||||
uint8_t : 2;
|
uint8_t : 2;
|
||||||
} bmAttributes ; ///< This field describes the endpoint's attributes when it is configured using the bConfigurationValue. \n Bits 1..0: Transfer Type \n- 00 = Control \n- 01 = Isochronous \n- 10 = Bulk \n- 11 = Interrupt \n If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: \n Bits 3..2: Synchronization Type \n- 00 = No Synchronization \n- 01 = Asynchronous \n- 10 = Adaptive \n- 11 = Synchronous \n Bits 5..4: Usage Type \n- 00 = Data endpoint \n- 01 = Feedback endpoint \n- 10 = Implicit feedback Data endpoint \n- 11 = Reserved \n Refer to Chapter 5 of USB 2.0 specification for more information. \n All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host.
|
} bmAttributes ; ///< This field describes the endpoint's attributes when it is configured using the bConfigurationValue. \n Bits 1..0: Transfer Type \n- 00 = Control \n- 01 = Isochronous \n- 10 = Bulk \n- 11 = Interrupt \n If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: \n Bits 3..2: Synchronization Type \n- 00 = No Synchronization \n- 01 = Asynchronous \n- 10 = Adaptive \n- 11 = Synchronous \n Bits 5..4: Usage Type \n- 00 = Data endpoint \n- 01 = Feedback endpoint \n- 10 = Implicit feedback Data endpoint \n- 11 = Reserved \n Refer to Chapter 5 of USB 2.0 specification for more information. \n All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host.
|
||||||
|
|
||||||
struct TU_ATTR_PACKED {
|
struct TU_ATTR_PACKED {
|
||||||
uint16_t size : 11; ///< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. \n For isochronous endpoints, this value is used to reserve the bus time in the schedule, required for the per-(micro)frame data payloads. The pipe may, on an ongoing basis, actually use less bandwidth than that reserved. The device reports, if necessary, the actual bandwidth used via its normal, non-USB defined mechanisms. \n For all endpoints, bits 10..0 specify the maximum packet size (in bytes). \n For high-speed isochronous and interrupt endpoints: \n Bits 12..11 specify the number of additional transaction opportunities per microframe: \n- 00 = None (1 transaction per microframe) \n- 01 = 1 additional (2 per microframe) \n- 10 = 2 additional (3 per microframe) \n- 11 = Reserved \n Bits 15..13 are reserved and must be set to zero.
|
uint16_t size : 11; ///< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. \n For isochronous endpoints, this value is used to reserve the bus time in the schedule, required for the per-(micro)frame data payloads. The pipe may, on an ongoing basis, actually use less bandwidth than that reserved. The device reports, if necessary, the actual bandwidth used via its normal, non-USB defined mechanisms. \n For all endpoints, bits 10..0 specify the maximum packet size (in bytes). \n For high-speed isochronous and interrupt endpoints: \n Bits 12..11 specify the number of additional transaction opportunities per microframe: \n- 00 = None (1 transaction per microframe) \n- 01 = 1 additional (2 per microframe) \n- 10 = 2 additional (3 per microframe) \n- 11 = Reserved \n Bits 15..13 are reserved and must be set to zero.
|
||||||
uint16_t hs_period_mult : 2;
|
uint16_t hs_period_mult : 2;
|
||||||
uint16_t : 0;
|
uint16_t : 0;
|
||||||
}wMaxPacketSize;
|
}wMaxPacketSize;
|
||||||
|
|
||||||
uint8_t bInterval ; ///< Interval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 us units). \n- For full-/high-speed isochronous endpoints, this value must be in the range from 1 to 16. The bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). \n- For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255. \n- For high-speed interrupt endpoints, the bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value must be from 1 to 16. \n- For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255. \n Refer to Chapter 5 of USB 2.0 specification for more information.
|
uint8_t bInterval ; ///< Interval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 us units). \n- For full-/high-speed isochronous endpoints, this value must be in the range from 1 to 16. The bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). \n- For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255. \n- For high-speed interrupt endpoints, the bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value must be from 1 to 16. \n- For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255. \n Refer to Chapter 5 of USB 2.0 specification for more information.
|
||||||
} tusb_desc_endpoint_t;
|
} tusb_desc_endpoint_t;
|
||||||
|
|
||||||
/// USB Other Speed Configuration Descriptor
|
/// USB Other Speed Configuration Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of descriptor
|
uint8_t bLength ; ///< Size of descriptor
|
||||||
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
|
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
|
||||||
uint16_t wTotalLength ; ///< Total length of data returned
|
uint16_t wTotalLength ; ///< Total length of data returned
|
||||||
|
|
||||||
uint8_t bNumInterfaces ; ///< Number of interfaces supported by this speed configuration
|
uint8_t bNumInterfaces ; ///< Number of interfaces supported by this speed configuration
|
||||||
uint8_t bConfigurationValue ; ///< Value to use to select configuration
|
uint8_t bConfigurationValue ; ///< Value to use to select configuration
|
||||||
uint8_t IConfiguration ; ///< Index of string descriptor
|
uint8_t IConfiguration ; ///< Index of string descriptor
|
||||||
uint8_t bmAttributes ; ///< Same as Configuration descriptor
|
uint8_t bmAttributes ; ///< Same as Configuration descriptor
|
||||||
uint8_t bMaxPower ; ///< Same as Configuration descriptor
|
uint8_t bMaxPower ; ///< Same as Configuration descriptor
|
||||||
} tusb_desc_other_speed_t;
|
} tusb_desc_other_speed_t;
|
||||||
|
|
||||||
/// USB Device Qualifier Descriptor
|
/// USB Device Qualifier Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of descriptor
|
uint8_t bLength ; ///< Size of descriptor
|
||||||
uint8_t bDescriptorType ; ///< Device Qualifier Type
|
uint8_t bDescriptorType ; ///< Device Qualifier Type
|
||||||
uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00)
|
uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00)
|
||||||
|
|
||||||
uint8_t bDeviceClass ; ///< Class Code
|
uint8_t bDeviceClass ; ///< Class Code
|
||||||
uint8_t bDeviceSubClass ; ///< SubClass Code
|
uint8_t bDeviceSubClass ; ///< SubClass Code
|
||||||
uint8_t bDeviceProtocol ; ///< Protocol Code
|
uint8_t bDeviceProtocol ; ///< Protocol Code
|
||||||
uint8_t bMaxPacketSize0 ; ///< Maximum packet size for other speed
|
uint8_t bMaxPacketSize0 ; ///< Maximum packet size for other speed
|
||||||
uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations
|
uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations
|
||||||
uint8_t bReserved ; ///< Reserved for future use, must be zero
|
uint8_t bReserved ; ///< Reserved for future use, must be zero
|
||||||
} tusb_desc_device_qualifier_t;
|
} tusb_desc_device_qualifier_t;
|
||||||
|
|
||||||
/// USB Interface Association Descriptor (IAD ECN)
|
/// USB Interface Association Descriptor (IAD ECN)
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of descriptor
|
uint8_t bLength ; ///< Size of descriptor
|
||||||
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
|
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
|
||||||
|
|
||||||
uint8_t bFirstInterface ; ///< Index of the first associated interface.
|
uint8_t bFirstInterface ; ///< Index of the first associated interface.
|
||||||
uint8_t bInterfaceCount ; ///< Total number of associated interfaces.
|
uint8_t bInterfaceCount ; ///< Total number of associated interfaces.
|
||||||
|
|
||||||
uint8_t bFunctionClass ; ///< Interface class ID.
|
uint8_t bFunctionClass ; ///< Interface class ID.
|
||||||
uint8_t bFunctionSubClass ; ///< Interface subclass ID.
|
uint8_t bFunctionSubClass ; ///< Interface subclass ID.
|
||||||
uint8_t bFunctionProtocol ; ///< Interface protocol ID.
|
uint8_t bFunctionProtocol ; ///< Interface protocol ID.
|
||||||
|
|
||||||
uint8_t iFunction ; ///< Index of the string descriptor describing the interface association.
|
uint8_t iFunction ; ///< Index of the string descriptor describing the interface association.
|
||||||
} tusb_desc_interface_assoc_t;
|
} tusb_desc_interface_assoc_t;
|
||||||
|
|
||||||
// USB String Descriptor
|
// USB String Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes
|
uint8_t bLength ; ///< Size of this descriptor in bytes
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type
|
uint8_t bDescriptorType ; ///< Descriptor Type
|
||||||
uint16_t unicode_string[];
|
uint16_t unicode_string[];
|
||||||
} tusb_desc_string_t;
|
} tusb_desc_string_t;
|
||||||
|
|
||||||
// USB Binary Device Object Store (BOS)
|
// USB Binary Device Object Store (BOS)
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength;
|
uint8_t bLength;
|
||||||
uint8_t bDescriptorType ;
|
uint8_t bDescriptorType ;
|
||||||
uint8_t bDevCapabilityType;
|
uint8_t bDevCapabilityType;
|
||||||
uint8_t bReserved;
|
uint8_t bReserved;
|
||||||
uint8_t PlatformCapabilityUUID[16];
|
uint8_t PlatformCapabilityUUID[16];
|
||||||
uint8_t CapabilityData[];
|
uint8_t CapabilityData[];
|
||||||
} tusb_desc_bos_platform_t;
|
} tusb_desc_bos_platform_t;
|
||||||
|
|
||||||
// USB WebuSB URL Descriptor
|
// USB WebuSB URL Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
{
|
{
|
||||||
uint8_t bLength;
|
uint8_t bLength;
|
||||||
uint8_t bDescriptorType;
|
uint8_t bDescriptorType;
|
||||||
uint8_t bScheme;
|
uint8_t bScheme;
|
||||||
char url[];
|
char url[];
|
||||||
} tusb_desc_webusb_url_t;
|
} tusb_desc_webusb_url_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* Types
|
/* Types
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
typedef struct TU_ATTR_PACKED{
|
typedef struct TU_ATTR_PACKED{
|
||||||
union {
|
union {
|
||||||
struct TU_ATTR_PACKED {
|
struct TU_ATTR_PACKED {
|
||||||
uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
|
uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
|
||||||
uint8_t type : 2; ///< Request type tusb_request_type_t.
|
uint8_t type : 2; ///< Request type tusb_request_type_t.
|
||||||
uint8_t direction : 1; ///< Direction type. tusb_dir_t
|
uint8_t direction : 1; ///< Direction type. tusb_dir_t
|
||||||
} bmRequestType_bit;
|
} bmRequestType_bit;
|
||||||
|
|
||||||
uint8_t bmRequestType;
|
uint8_t bmRequestType;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t bRequest;
|
uint8_t bRequest;
|
||||||
uint16_t wValue;
|
uint16_t wValue;
|
||||||
uint16_t wIndex;
|
uint16_t wIndex;
|
||||||
uint16_t wLength;
|
uint16_t wLength;
|
||||||
} tusb_control_request_t;
|
} tusb_control_request_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "mostly compiler option issue");
|
TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "mostly compiler option issue");
|
||||||
|
|
||||||
// TODO move to somewhere suitable
|
// TODO move to somewhere suitable
|
||||||
static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t recipient)
|
static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t recipient)
|
||||||
{
|
{
|
||||||
return ((uint8_t) (direction << 7)) | ((uint8_t) (type << 5)) | (recipient);
|
return ((uint8_t) (direction << 7)) | ((uint8_t) (type << 5)) | (recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Endpoint helper
|
// Endpoint helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Get direction from Endpoint address
|
// Get direction from Endpoint address
|
||||||
static inline tusb_dir_t tu_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 tu_edpt_number(uint8_t addr)
|
static inline uint8_t tu_edpt_number(uint8_t addr)
|
||||||
{
|
{
|
||||||
return (uint8_t)(addr & (~TUSB_DIR_IN_MASK));
|
return (uint8_t)(addr & (~TUSB_DIR_IN_MASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
|
static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
|
||||||
{
|
{
|
||||||
return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0));
|
return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Descriptor helper
|
// Descriptor helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline uint8_t const * tu_desc_next(void const* desc)
|
static inline uint8_t const * tu_desc_next(void const* desc)
|
||||||
{
|
{
|
||||||
uint8_t const* desc8 = (uint8_t const*) desc;
|
uint8_t const* desc8 = (uint8_t const*) desc;
|
||||||
return desc8 + desc8[DESC_OFFSET_LEN];
|
return desc8 + desc8[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t tu_desc_type(void const* desc)
|
static inline uint8_t tu_desc_type(void const* desc)
|
||||||
{
|
{
|
||||||
return ((uint8_t const*) desc)[DESC_OFFSET_TYPE];
|
return ((uint8_t const*) desc)[DESC_OFFSET_TYPE];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t tu_desc_len(void const* desc)
|
static inline uint8_t tu_desc_len(void const* desc)
|
||||||
{
|
{
|
||||||
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
|
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_TYPES_H_ */
|
#endif /* _TUSB_TYPES_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
302
src/device/dcd.h
302
src/device/dcd.h
@ -1,151 +1,151 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_usbd
|
/** \ingroup group_usbd
|
||||||
* \defgroup group_dcd Device Controller Driver (DCD)
|
* \defgroup group_dcd Device Controller Driver (DCD)
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_DCD_H_
|
#ifndef _TUSB_DCD_H_
|
||||||
#define _TUSB_DCD_H_
|
#define _TUSB_DCD_H_
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DCD_EVENT_INVALID = 0,
|
DCD_EVENT_INVALID = 0,
|
||||||
DCD_EVENT_BUS_RESET,
|
DCD_EVENT_BUS_RESET,
|
||||||
DCD_EVENT_UNPLUGGED,
|
DCD_EVENT_UNPLUGGED,
|
||||||
DCD_EVENT_SOF,
|
DCD_EVENT_SOF,
|
||||||
DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
|
DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
|
||||||
DCD_EVENT_RESUME,
|
DCD_EVENT_RESUME,
|
||||||
|
|
||||||
DCD_EVENT_SETUP_RECEIVED,
|
DCD_EVENT_SETUP_RECEIVED,
|
||||||
DCD_EVENT_XFER_COMPLETE,
|
DCD_EVENT_XFER_COMPLETE,
|
||||||
|
|
||||||
// Not an DCD event, just a convenient way to defer ISR function
|
// Not an DCD event, just a convenient way to defer ISR function
|
||||||
USBD_EVENT_FUNC_CALL,
|
USBD_EVENT_FUNC_CALL,
|
||||||
|
|
||||||
DCD_EVENT_COUNT
|
DCD_EVENT_COUNT
|
||||||
} dcd_eventid_t;
|
} dcd_eventid_t;
|
||||||
|
|
||||||
typedef struct TU_ATTR_ALIGNED(4)
|
typedef struct TU_ATTR_ALIGNED(4)
|
||||||
{
|
{
|
||||||
uint8_t rhport;
|
uint8_t rhport;
|
||||||
uint8_t event_id;
|
uint8_t event_id;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
// USBD_EVT_SETUP_RECEIVED
|
// USBD_EVT_SETUP_RECEIVED
|
||||||
tusb_control_request_t setup_received;
|
tusb_control_request_t setup_received;
|
||||||
|
|
||||||
// USBD_EVT_XFER_COMPLETE
|
// USBD_EVT_XFER_COMPLETE
|
||||||
struct {
|
struct {
|
||||||
uint8_t ep_addr;
|
uint8_t ep_addr;
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
}xfer_complete;
|
}xfer_complete;
|
||||||
|
|
||||||
// USBD_EVENT_FUNC_CALL
|
// USBD_EVENT_FUNC_CALL
|
||||||
struct {
|
struct {
|
||||||
void (*func) (void*);
|
void (*func) (void*);
|
||||||
void* param;
|
void* param;
|
||||||
}func_call;
|
}func_call;
|
||||||
};
|
};
|
||||||
} dcd_event_t;
|
} dcd_event_t;
|
||||||
|
|
||||||
//TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct");
|
//TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct");
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* Device API
|
/* Device API
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
// Initialize controller to device mode
|
// Initialize controller to device mode
|
||||||
void dcd_init (uint8_t rhport);
|
void dcd_init (uint8_t rhport);
|
||||||
|
|
||||||
// Interrupt Handler
|
// Interrupt Handler
|
||||||
void dcd_isr (uint8_t rhport);
|
void dcd_isr (uint8_t rhport);
|
||||||
|
|
||||||
// Enable device interrupt
|
// Enable device interrupt
|
||||||
void dcd_int_enable (uint8_t rhport);
|
void dcd_int_enable (uint8_t rhport);
|
||||||
|
|
||||||
// Disable device interrupt
|
// Disable device interrupt
|
||||||
void dcd_int_disable(uint8_t rhport);
|
void dcd_int_disable(uint8_t rhport);
|
||||||
|
|
||||||
// Receive Set Address request, mcu port must also include status IN response
|
// Receive Set Address request, mcu port must also include status IN response
|
||||||
void dcd_set_address(uint8_t rhport, uint8_t dev_addr);
|
void dcd_set_address(uint8_t rhport, uint8_t dev_addr);
|
||||||
|
|
||||||
// Receive Set Configure request
|
// Receive Set Configure request
|
||||||
void dcd_set_config (uint8_t rhport, uint8_t config_num);
|
void dcd_set_config (uint8_t rhport, uint8_t config_num);
|
||||||
|
|
||||||
// Wake up host
|
// Wake up host
|
||||||
void dcd_remote_wakeup(uint8_t rhport);
|
void dcd_remote_wakeup(uint8_t rhport);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Endpoint API
|
// Endpoint API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when a control transfer's status stage is complete.
|
// Invoked when a control transfer's status stage is complete.
|
||||||
// May help DCD to prepare for next control transfer, this API is optional.
|
// May help DCD to prepare for next control transfer, this API is optional.
|
||||||
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
|
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
|
||||||
|
|
||||||
// Configure endpoint's registers according to descriptor
|
// Configure endpoint's registers according to descriptor
|
||||||
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
|
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
|
||||||
|
|
||||||
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
|
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
|
||||||
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);
|
||||||
|
|
||||||
// Stall endpoint
|
// Stall endpoint
|
||||||
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
|
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
|
||||||
|
|
||||||
// clear stall, data toggle is also reset to DATA0
|
// clear stall, data toggle is also reset to DATA0
|
||||||
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
|
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Event API (Implemented by device stack)
|
// Event API (Implemented by device stack)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Called by DCD to notify device stack
|
// Called by DCD to notify device stack
|
||||||
extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
|
extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
|
||||||
|
|
||||||
// helper to send bus signal event
|
// helper to send bus signal event
|
||||||
extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr);
|
extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr);
|
||||||
|
|
||||||
// helper to send setup received
|
// helper to send setup received
|
||||||
extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr);
|
extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr);
|
||||||
|
|
||||||
// helper to send transfer complete event
|
// helper to send transfer complete event
|
||||||
extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
|
extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_DCD_H_ */
|
#endif /* _TUSB_DCD_H_ */
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
2000
src/device/usbd.c
2000
src/device/usbd.c
File diff suppressed because it is too large
Load Diff
@ -1,335 +1,335 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_usbd
|
/** \ingroup group_usbd
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_USBD_H_
|
#ifndef _TUSB_USBD_H_
|
||||||
#define _TUSB_USBD_H_
|
#define _TUSB_USBD_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
#include "dcd.h"
|
#include "dcd.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API
|
// Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Init device stack
|
// Init device stack
|
||||||
bool tud_init (void);
|
bool tud_init (void);
|
||||||
|
|
||||||
// Task function should be called in main/rtos loop
|
// Task function should be called in main/rtos loop
|
||||||
void tud_task (void);
|
void tud_task (void);
|
||||||
|
|
||||||
// Interrupt handler, name alias to DCD
|
// Interrupt handler, name alias to DCD
|
||||||
#define tud_isr dcd_isr
|
#define tud_isr dcd_isr
|
||||||
|
|
||||||
// Check if device is connected and configured
|
// Check if device is connected and configured
|
||||||
bool tud_mounted(void);
|
bool tud_mounted(void);
|
||||||
|
|
||||||
// Check if device is suspended
|
// Check if device is suspended
|
||||||
bool tud_suspended(void);
|
bool tud_suspended(void);
|
||||||
|
|
||||||
// Check if device is ready to transfer
|
// Check if device is ready to transfer
|
||||||
static inline bool tud_ready(void)
|
static inline bool tud_ready(void)
|
||||||
{
|
{
|
||||||
return tud_mounted() && !tud_suspended();
|
return tud_mounted() && !tud_suspended();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remote wake up host, only if suspended and enabled by host
|
// Remote wake up host, only if suspended and enabled by host
|
||||||
bool tud_remote_wakeup(void);
|
bool tud_remote_wakeup(void);
|
||||||
|
|
||||||
// Carry out Data and Status stage of control transfer
|
// Carry out Data and Status stage of control transfer
|
||||||
// - If len = 0, it is equivalent to sending status only
|
// - If len = 0, it is equivalent to sending status only
|
||||||
// - If len > wLength : it will be truncated
|
// - If len > wLength : it will be truncated
|
||||||
bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len);
|
bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len);
|
||||||
|
|
||||||
// Send STATUS (zero length) packet
|
// Send STATUS (zero length) packet
|
||||||
bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request);
|
bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application Callbacks (WEAK is optional)
|
// Application Callbacks (WEAK is optional)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when received GET DEVICE DESCRIPTOR request
|
// Invoked when received GET DEVICE DESCRIPTOR request
|
||||||
// Application return pointer to descriptor
|
// Application return pointer to descriptor
|
||||||
uint8_t const * tud_descriptor_device_cb(void);
|
uint8_t const * tud_descriptor_device_cb(void);
|
||||||
|
|
||||||
// Invoked when received GET BOS DESCRIPTOR request
|
// Invoked when received GET BOS DESCRIPTOR request
|
||||||
// Application return pointer to descriptor
|
// Application return pointer to descriptor
|
||||||
TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void);
|
TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void);
|
||||||
|
|
||||||
// Invoked when received GET CONFIGURATION DESCRIPTOR request
|
// Invoked when received GET CONFIGURATION DESCRIPTOR request
|
||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
uint8_t const * tud_descriptor_configuration_cb(uint8_t index);
|
uint8_t const * tud_descriptor_configuration_cb(uint8_t index);
|
||||||
|
|
||||||
// Invoked when received GET STRING DESCRIPTOR request
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
uint16_t const* tud_descriptor_string_cb(uint8_t index);
|
uint16_t const* tud_descriptor_string_cb(uint8_t index);
|
||||||
|
|
||||||
// Invoked when device is mounted (configured)
|
// Invoked when device is mounted (configured)
|
||||||
TU_ATTR_WEAK void tud_mount_cb(void);
|
TU_ATTR_WEAK void tud_mount_cb(void);
|
||||||
|
|
||||||
// Invoked when device is unmounted
|
// Invoked when device is unmounted
|
||||||
TU_ATTR_WEAK void tud_umount_cb(void);
|
TU_ATTR_WEAK void tud_umount_cb(void);
|
||||||
|
|
||||||
// Invoked when usb bus is suspended
|
// Invoked when usb bus is suspended
|
||||||
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
||||||
TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en);
|
TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en);
|
||||||
|
|
||||||
// Invoked when usb bus is resumed
|
// Invoked when usb bus is resumed
|
||||||
TU_ATTR_WEAK void tud_resume_cb(void);
|
TU_ATTR_WEAK void tud_resume_cb(void);
|
||||||
|
|
||||||
// Invoked when received control request with VENDOR TYPE
|
// Invoked when received control request with VENDOR TYPE
|
||||||
TU_ATTR_WEAK bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request);
|
TU_ATTR_WEAK bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request);
|
||||||
TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request);
|
TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request);
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Binary Device Object Store (BOS) Descriptor Templates
|
// Binary Device Object Store (BOS) Descriptor Templates
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#define TUD_BOS_DESC_LEN 5
|
#define TUD_BOS_DESC_LEN 5
|
||||||
|
|
||||||
// total length, number of device caps
|
// total length, number of device caps
|
||||||
#define TUD_BOS_DESCRIPTOR(_total_len, _caps_num) \
|
#define TUD_BOS_DESCRIPTOR(_total_len, _caps_num) \
|
||||||
5, TUSB_DESC_BOS, U16_TO_U8S_LE(_total_len), _caps_num
|
5, TUSB_DESC_BOS, U16_TO_U8S_LE(_total_len), _caps_num
|
||||||
|
|
||||||
// Device Capability Platform 128-bit UUID + Data
|
// Device Capability Platform 128-bit UUID + Data
|
||||||
#define TUD_BOS_PLATFORM_DESCRIPTOR(...) \
|
#define TUD_BOS_PLATFORM_DESCRIPTOR(...) \
|
||||||
4+TU_ARGS_NUM(__VA_ARGS__), TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_PLATFORM, 0x00, __VA_ARGS__
|
4+TU_ARGS_NUM(__VA_ARGS__), TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_PLATFORM, 0x00, __VA_ARGS__
|
||||||
|
|
||||||
//------------- WebUSB BOS Platform -------------//
|
//------------- WebUSB BOS Platform -------------//
|
||||||
|
|
||||||
// Descriptor Length
|
// Descriptor Length
|
||||||
#define TUD_BOS_WEBUSB_DESC_LEN 24
|
#define TUD_BOS_WEBUSB_DESC_LEN 24
|
||||||
|
|
||||||
// Vendor Code, iLandingPage
|
// Vendor Code, iLandingPage
|
||||||
#define TUD_BOS_WEBUSB_DESCRIPTOR(_vendor_code, _ipage) \
|
#define TUD_BOS_WEBUSB_DESCRIPTOR(_vendor_code, _ipage) \
|
||||||
TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_WEBUSB_UUID, U16_TO_U8S_LE(0x0100), _vendor_code, _ipage)
|
TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_WEBUSB_UUID, U16_TO_U8S_LE(0x0100), _vendor_code, _ipage)
|
||||||
|
|
||||||
#define TUD_BOS_WEBUSB_UUID \
|
#define TUD_BOS_WEBUSB_UUID \
|
||||||
0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, \
|
0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, \
|
||||||
0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65
|
0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65
|
||||||
|
|
||||||
//------------- Microsoft OS 2.0 Platform -------------//
|
//------------- Microsoft OS 2.0 Platform -------------//
|
||||||
#define TUD_BOS_MICROSOFT_OS_DESC_LEN 28
|
#define TUD_BOS_MICROSOFT_OS_DESC_LEN 28
|
||||||
|
|
||||||
// Total Length of descriptor set, vendor code
|
// Total Length of descriptor set, vendor code
|
||||||
#define TUD_BOS_MS_OS_20_DESCRIPTOR(_desc_set_len, _vendor_code) \
|
#define TUD_BOS_MS_OS_20_DESCRIPTOR(_desc_set_len, _vendor_code) \
|
||||||
TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_MS_OS_20_UUID, U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(_desc_set_len), _vendor_code, 0)
|
TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_MS_OS_20_UUID, U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(_desc_set_len), _vendor_code, 0)
|
||||||
|
|
||||||
#define TUD_BOS_MS_OS_20_UUID \
|
#define TUD_BOS_MS_OS_20_UUID \
|
||||||
0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, \
|
0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, \
|
||||||
0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F
|
0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Configuration & Interface Descriptor Templates
|
// Configuration & Interface Descriptor Templates
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
//------------- Configuration -------------//
|
//------------- Configuration -------------//
|
||||||
#define TUD_CONFIG_DESC_LEN (9)
|
#define TUD_CONFIG_DESC_LEN (9)
|
||||||
|
|
||||||
// Interface count, string index, total length, attribute, power in mA
|
// Interface count, string index, total length, attribute, power in mA
|
||||||
#define TUD_CONFIG_DESCRIPTOR(_itfcount, _stridx, _total_len, _attribute, _power_ma) \
|
#define TUD_CONFIG_DESCRIPTOR(_itfcount, _stridx, _total_len, _attribute, _power_ma) \
|
||||||
9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, 1, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2
|
9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, 1, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2
|
||||||
|
|
||||||
//------------- CDC -------------//
|
//------------- CDC -------------//
|
||||||
|
|
||||||
// Length of template descriptor: 66 bytes
|
// Length of template descriptor: 66 bytes
|
||||||
#define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7)
|
#define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7)
|
||||||
|
|
||||||
// CDC Descriptor Template
|
// CDC Descriptor Template
|
||||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
#define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \
|
#define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \
|
||||||
/* Interface Associate */\
|
/* Interface Associate */\
|
||||||
8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, 0,\
|
8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, 0,\
|
||||||
/* CDC Control Interface */\
|
/* CDC Control Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, _stridx,\
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, _stridx,\
|
||||||
/* CDC Header */\
|
/* CDC Header */\
|
||||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
|
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
|
||||||
/* CDC Call */\
|
/* CDC Call */\
|
||||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\
|
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\
|
||||||
/* CDC ACM: support line request */\
|
/* CDC ACM: support line request */\
|
||||||
4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\
|
4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\
|
||||||
/* CDC Union */\
|
/* CDC Union */\
|
||||||
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\
|
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\
|
||||||
/* Endpoint Notification */\
|
/* Endpoint Notification */\
|
||||||
7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 16,\
|
7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 16,\
|
||||||
/* CDC Data Interface */\
|
/* CDC Data Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
|
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
|
||||||
/* Endpoint Out */\
|
/* Endpoint Out */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||||
/* Endpoint In */\
|
/* Endpoint In */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||||
|
|
||||||
//------------- MSC -------------//
|
//------------- MSC -------------//
|
||||||
|
|
||||||
// Length of template descriptor: 23 bytes
|
// Length of template descriptor: 23 bytes
|
||||||
#define TUD_MSC_DESC_LEN (9 + 7 + 7)
|
#define TUD_MSC_DESC_LEN (9 + 7 + 7)
|
||||||
|
|
||||||
// Interface number, string index, EP Out & EP In address, EP size
|
// Interface number, string index, EP Out & EP In address, EP size
|
||||||
#define TUD_MSC_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
#define TUD_MSC_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
||||||
/* Interface */\
|
/* Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_MSC, MSC_SUBCLASS_SCSI, MSC_PROTOCOL_BOT, _stridx,\
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_MSC, MSC_SUBCLASS_SCSI, MSC_PROTOCOL_BOT, _stridx,\
|
||||||
/* Endpoint Out */\
|
/* Endpoint Out */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||||
/* Endpoint In */\
|
/* Endpoint In */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||||
|
|
||||||
//------------- HID -------------//
|
//------------- HID -------------//
|
||||||
|
|
||||||
// Length of template descriptor: 25 bytes
|
// Length of template descriptor: 25 bytes
|
||||||
#define TUD_HID_DESC_LEN (9 + 9 + 7)
|
#define TUD_HID_DESC_LEN (9 + 9 + 7)
|
||||||
|
|
||||||
// HID Input only descriptor
|
// HID Input only descriptor
|
||||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||||
#define TUD_HID_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \
|
#define TUD_HID_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \
|
||||||
/* Interface */\
|
/* Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\
|
||||||
/* HID descriptor */\
|
/* HID descriptor */\
|
||||||
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
|
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
|
||||||
/* Endpoint In */\
|
/* Endpoint In */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
|
||||||
|
|
||||||
// Length of template descriptor: 32 bytes
|
// Length of template descriptor: 32 bytes
|
||||||
#define TUD_HID_INOUT_DESC_LEN (9 + 9 + 7 + 7)
|
#define TUD_HID_INOUT_DESC_LEN (9 + 9 + 7 + 7)
|
||||||
|
|
||||||
// HID Input & Output descriptor
|
// HID Input & Output descriptor
|
||||||
// Interface number, string index, protocol, report descriptor len, EP OUT & IN address, size & polling interval
|
// Interface number, string index, protocol, report descriptor len, EP OUT & IN address, size & polling interval
|
||||||
#define TUD_HID_INOUT_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epout, _epin, _epsize, _ep_interval) \
|
#define TUD_HID_INOUT_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epout, _epin, _epsize, _ep_interval) \
|
||||||
/* Interface */\
|
/* Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\
|
||||||
/* HID descriptor */\
|
/* HID descriptor */\
|
||||||
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
|
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
|
||||||
/* Endpoint Out */\
|
/* Endpoint Out */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval, \
|
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval, \
|
||||||
/* Endpoint In */\
|
/* Endpoint In */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
|
||||||
|
|
||||||
//------------- MIDI -------------//
|
//------------- MIDI -------------//
|
||||||
|
|
||||||
// Length of template descriptor (96 bytes)
|
// Length of template descriptor (96 bytes)
|
||||||
#define TUD_MIDI_DESC_LEN (9 + 9 + 9 + 7 + 6 + 6 + 9 + 9 + 7 + 5 + 7 + 5)
|
#define TUD_MIDI_DESC_LEN (9 + 9 + 9 + 7 + 6 + 6 + 9 + 9 + 7 + 5 + 7 + 5)
|
||||||
|
|
||||||
// MIDI simple descriptor
|
// MIDI simple descriptor
|
||||||
// - 1 Embedded Jack In connected to 1 External Jack Out
|
// - 1 Embedded Jack In connected to 1 External Jack Out
|
||||||
// - 1 Embedded Jack out connected to 1 External Jack In
|
// - 1 Embedded Jack out connected to 1 External Jack In
|
||||||
#define TUD_MIDI_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
#define TUD_MIDI_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
||||||
/* Audio Control (AC) Interface */\
|
/* Audio Control (AC) Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_PROTOCOL_V1, _stridx,\
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_PROTOCOL_V1, _stridx,\
|
||||||
/* AC Header */\
|
/* AC Header */\
|
||||||
9, TUSB_DESC_CS_INTERFACE, AUDIO_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0009), 1, (uint8_t)((_itfnum)+1),\
|
9, TUSB_DESC_CS_INTERFACE, AUDIO_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0009), 1, (uint8_t)((_itfnum)+1),\
|
||||||
/* MIDI Streaming (MS) Interface */\
|
/* MIDI Streaming (MS) Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_PROTOCOL_V1, 0,\
|
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_PROTOCOL_V1, 0,\
|
||||||
/* MS Header */\
|
/* MS Header */\
|
||||||
7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0025),\
|
7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0025),\
|
||||||
/* MS In Jack (Embedded) */\
|
/* MS In Jack (Embedded) */\
|
||||||
6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EMBEDDED, 1, 0,\
|
6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EMBEDDED, 1, 0,\
|
||||||
/* MS In Jack (External) */\
|
/* MS In Jack (External) */\
|
||||||
6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EXTERNAL, 2, 0,\
|
6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EXTERNAL, 2, 0,\
|
||||||
/* MS Out Jack (Embedded), connected to In Jack External */\
|
/* MS Out Jack (Embedded), connected to In Jack External */\
|
||||||
9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, 3, 1, 2, 1, 0,\
|
9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, 3, 1, 2, 1, 0,\
|
||||||
/* MS Out Jack (External), connected to In Jack Embedded */\
|
/* MS Out Jack (External), connected to In Jack Embedded */\
|
||||||
9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, 4, 1, 1, 1, 0,\
|
9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, 4, 1, 1, 1, 0,\
|
||||||
/* Endpoint Out */\
|
/* Endpoint Out */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||||
/* MS Endpoint (connected to embedded jack in) */\
|
/* MS Endpoint (connected to embedded jack in) */\
|
||||||
5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 1,\
|
5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 1,\
|
||||||
/* Endpoint In */\
|
/* Endpoint In */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||||
/* MS Endpoint (connected to embedded jack out) */\
|
/* MS Endpoint (connected to embedded jack out) */\
|
||||||
5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 3
|
5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 3
|
||||||
|
|
||||||
//------------- TUD_USBTMC/USB488 -------------//
|
//------------- TUD_USBTMC/USB488 -------------//
|
||||||
#define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC)
|
#define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC)
|
||||||
#define TUD_USBTMC_APP_SUBCLASS 0x03u
|
#define TUD_USBTMC_APP_SUBCLASS 0x03u
|
||||||
|
|
||||||
#define TUD_USBTMC_PROTOCOL_STD 0x00u
|
#define TUD_USBTMC_PROTOCOL_STD 0x00u
|
||||||
#define TUD_USBTMC_PROTOCOL_USB488 0x01u
|
#define TUD_USBTMC_PROTOCOL_USB488 0x01u
|
||||||
|
|
||||||
// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID,
|
// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID,
|
||||||
// bulk-in endpoint ID
|
// bulk-in endpoint ID
|
||||||
#define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \
|
#define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \
|
||||||
/* Interface */ \
|
/* Interface */ \
|
||||||
0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx
|
0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx
|
||||||
|
|
||||||
#define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u
|
#define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u
|
||||||
|
|
||||||
#define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \
|
#define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \
|
||||||
/* Endpoint Out */ \
|
/* Endpoint Out */ \
|
||||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \
|
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \
|
||||||
/* Endpoint In */ \
|
/* Endpoint In */ \
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u
|
||||||
|
|
||||||
#define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u)
|
#define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u)
|
||||||
|
|
||||||
/* optional interrupt endpoint */ \
|
/* optional interrupt endpoint */ \
|
||||||
// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number?
|
// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number?
|
||||||
#define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \
|
#define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \
|
||||||
7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16
|
7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16
|
||||||
|
|
||||||
#define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u)
|
#define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u)
|
||||||
|
|
||||||
|
|
||||||
//------------- Vendor -------------//
|
//------------- Vendor -------------//
|
||||||
#define TUD_VENDOR_DESC_LEN (9+7+7)
|
#define TUD_VENDOR_DESC_LEN (9+7+7)
|
||||||
|
|
||||||
// Interface number, string index, EP Out & IN address, EP size
|
// Interface number, string index, EP Out & IN address, EP size
|
||||||
#define TUD_VENDOR_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
#define TUD_VENDOR_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
||||||
/* Interface */\
|
/* Interface */\
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_VENDOR_SPECIFIC, 0x00, 0x00, _stridx,\
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_VENDOR_SPECIFIC, 0x00, 0x00, _stridx,\
|
||||||
/* Endpoint Out */\
|
/* Endpoint Out */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||||
/* Endpoint In */\
|
/* Endpoint In */\
|
||||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||||
|
|
||||||
//------------- DFU Runtime -------------//
|
//------------- DFU Runtime -------------//
|
||||||
#define TUD_DFU_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC)
|
#define TUD_DFU_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC)
|
||||||
#define TUD_DFU_APP_SUBCLASS 0x01u
|
#define TUD_DFU_APP_SUBCLASS 0x01u
|
||||||
|
|
||||||
// Length of template descriptr: 18 bytes
|
// Length of template descriptr: 18 bytes
|
||||||
#define TUD_DFU_RT_DESC_LEN (9 + 9)
|
#define TUD_DFU_RT_DESC_LEN (9 + 9)
|
||||||
|
|
||||||
// DFU runtime descriptor
|
// DFU runtime descriptor
|
||||||
// Interface number, string index, attributes, detach timeout, transfer size
|
// Interface number, string index, attributes, detach timeout, transfer size
|
||||||
#define TUD_DFU_RT_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \
|
#define TUD_DFU_RT_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \
|
||||||
/* Interface */ \
|
/* Interface */ \
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \
|
||||||
/* Function */ \
|
/* Function */ \
|
||||||
9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
|
9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_USBD_H_ */
|
#endif /* _TUSB_USBD_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
1712
src/host/ehci/ehci.c
1712
src/host/ehci/ehci.c
File diff suppressed because it is too large
Load Diff
294
src/host/hcd.h
294
src/host/hcd.h
@ -1,147 +1,147 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_usbh
|
/** \ingroup group_usbh
|
||||||
* \defgroup Group_HCD Host Controller Driver (HCD)
|
* \defgroup Group_HCD Host Controller Driver (HCD)
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_HCD_H_
|
#ifndef _TUSB_HCD_H_
|
||||||
#define _TUSB_HCD_H_
|
#define _TUSB_HCD_H_
|
||||||
|
|
||||||
#include <common/tusb_common.h>
|
#include <common/tusb_common.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
HCD_EVENT_DEVICE_ATTACH,
|
HCD_EVENT_DEVICE_ATTACH,
|
||||||
HCD_EVENT_DEVICE_REMOVE,
|
HCD_EVENT_DEVICE_REMOVE,
|
||||||
HCD_EVENT_XFER_COMPLETE,
|
HCD_EVENT_XFER_COMPLETE,
|
||||||
} hcd_eventid_t;
|
} hcd_eventid_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t rhport;
|
uint8_t rhport;
|
||||||
uint8_t event_id;
|
uint8_t event_id;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t hub_addr;
|
uint8_t hub_addr;
|
||||||
uint8_t hub_port;
|
uint8_t hub_port;
|
||||||
} attach, remove;
|
} attach, remove;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t ep_addr;
|
uint8_t ep_addr;
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
} xfer_complete;
|
} xfer_complete;
|
||||||
};
|
};
|
||||||
|
|
||||||
} hcd_event_t;
|
} hcd_event_t;
|
||||||
|
|
||||||
#if TUSB_OPT_HOST_ENABLED
|
#if TUSB_OPT_HOST_ENABLED
|
||||||
// Max number of endpoints per device
|
// Max number of endpoints per device
|
||||||
enum {
|
enum {
|
||||||
HCD_MAX_ENDPOINT = CFG_TUSB_HOST_DEVICE_MAX*(CFG_TUH_HUB + CFG_TUH_HID_KEYBOARD + CFG_TUH_HID_MOUSE + CFG_TUSB_HOST_HID_GENERIC +
|
HCD_MAX_ENDPOINT = CFG_TUSB_HOST_DEVICE_MAX*(CFG_TUH_HUB + CFG_TUH_HID_KEYBOARD + CFG_TUH_HID_MOUSE + CFG_TUSB_HOST_HID_GENERIC +
|
||||||
CFG_TUH_MSC*2 + CFG_TUH_CDC*3),
|
CFG_TUH_MSC*2 + CFG_TUH_CDC*3),
|
||||||
|
|
||||||
HCD_MAX_XFER = HCD_MAX_ENDPOINT*2,
|
HCD_MAX_XFER = HCD_MAX_ENDPOINT*2,
|
||||||
};
|
};
|
||||||
|
|
||||||
//#define HCD_MAX_ENDPOINT 16
|
//#define HCD_MAX_ENDPOINT 16
|
||||||
//#define HCD_MAX_XFER 16
|
//#define HCD_MAX_XFER 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// HCD API
|
// HCD API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool hcd_init(void);
|
bool hcd_init(void);
|
||||||
void hcd_isr(uint8_t hostid);
|
void hcd_isr(uint8_t hostid);
|
||||||
void hcd_int_enable (uint8_t rhport);
|
void hcd_int_enable (uint8_t rhport);
|
||||||
void hcd_int_disable(uint8_t rhport);
|
void hcd_int_disable(uint8_t rhport);
|
||||||
|
|
||||||
// PORT API
|
// PORT API
|
||||||
/// return the current connect status of roothub port
|
/// return the current connect status of roothub port
|
||||||
bool hcd_port_connect_status(uint8_t hostid);
|
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 closes all opened endpoints belong to this device
|
// HCD closes all opened endpoints belong to this device
|
||||||
void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
|
void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Event function
|
// Event function
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void hcd_event_handler(hcd_event_t const* event, bool in_isr);
|
void hcd_event_handler(hcd_event_t const* event, bool in_isr);
|
||||||
|
|
||||||
// Helper to send device attach event
|
// Helper to send device attach event
|
||||||
void hcd_event_device_attach(uint8_t rhport);
|
void hcd_event_device_attach(uint8_t rhport);
|
||||||
|
|
||||||
// Helper to send device removal event
|
// Helper to send device removal event
|
||||||
void hcd_event_device_remove(uint8_t rhport);
|
void hcd_event_device_remove(uint8_t rhport);
|
||||||
|
|
||||||
// Helper to send USB transfer event
|
// Helper to send USB transfer event
|
||||||
void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Endpoints API
|
// Endpoints API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
|
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
|
||||||
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
|
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
|
||||||
|
|
||||||
bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr);
|
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
|
// 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);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// PIPE API
|
// PIPE API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// TODO control xfer should be used via usbh layer
|
// TODO control xfer should be used via usbh layer
|
||||||
bool hcd_pipe_queue_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes); // only queue, not transferring yet
|
bool hcd_pipe_queue_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes); // only queue, not transferring yet
|
||||||
bool hcd_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete);
|
bool hcd_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
tusb_error_t hcd_pipe_cancel();
|
tusb_error_t hcd_pipe_cancel();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_HCD_H_ */
|
#endif /* _TUSB_HCD_H_ */
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
500
src/host/hub.c
500
src/host/hub.c
@ -1,250 +1,250 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tusb_option.h"
|
#include "tusb_option.h"
|
||||||
|
|
||||||
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB)
|
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INCLUDE
|
// INCLUDE
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#include "hub.h"
|
#include "hub.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t itf_num;
|
uint8_t itf_num;
|
||||||
uint8_t ep_status;
|
uint8_t ep_status;
|
||||||
uint8_t port_number;
|
uint8_t port_number;
|
||||||
uint8_t status_change; // data from status change interrupt endpoint
|
uint8_t status_change; // data from status change interrupt endpoint
|
||||||
}usbh_hub_t;
|
}usbh_hub_t;
|
||||||
|
|
||||||
CFG_TUSB_MEM_SECTION static usbh_hub_t hub_data[CFG_TUSB_HOST_DEVICE_MAX];
|
CFG_TUSB_MEM_SECTION static usbh_hub_t hub_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||||
TU_ATTR_ALIGNED(4) CFG_TUSB_MEM_SECTION static uint8_t hub_enum_buffer[sizeof(descriptor_hub_desc_t)];
|
TU_ATTR_ALIGNED(4) CFG_TUSB_MEM_SECTION static uint8_t hub_enum_buffer[sizeof(descriptor_hub_desc_t)];
|
||||||
|
|
||||||
//OSAL_SEM_DEF(hub_enum_semaphore);
|
//OSAL_SEM_DEF(hub_enum_semaphore);
|
||||||
//static osal_semaphore_handle_t hub_enum_sem_hdl;
|
//static osal_semaphore_handle_t hub_enum_sem_hdl;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// HUB
|
// HUB
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature)
|
bool hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature)
|
||||||
{
|
{
|
||||||
TU_ASSERT(HUB_FEATURE_PORT_CONNECTION_CHANGE <= feature && feature <= HUB_FEATURE_PORT_RESET_CHANGE);
|
TU_ASSERT(HUB_FEATURE_PORT_CONNECTION_CHANGE <= feature && feature <= HUB_FEATURE_PORT_RESET_CHANGE);
|
||||||
|
|
||||||
tusb_control_request_t request = {
|
tusb_control_request_t request = {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = HUB_REQUEST_CLEAR_FEATURE,
|
.bRequest = HUB_REQUEST_CLEAR_FEATURE,
|
||||||
.wValue = feature,
|
.wValue = feature,
|
||||||
.wIndex = hub_port,
|
.wIndex = hub_port,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------- Clear Port Feature request -------------//
|
//------------- Clear Port Feature request -------------//
|
||||||
TU_ASSERT( usbh_control_xfer( hub_addr, &request, NULL ) );
|
TU_ASSERT( usbh_control_xfer( hub_addr, &request, NULL ) );
|
||||||
|
|
||||||
//------------- Get Port Status to check if feature is cleared -------------//
|
//------------- Get Port Status to check if feature is cleared -------------//
|
||||||
request = (tusb_control_request_t ) {
|
request = (tusb_control_request_t ) {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
||||||
.bRequest = HUB_REQUEST_GET_STATUS,
|
.bRequest = HUB_REQUEST_GET_STATUS,
|
||||||
.wValue = 0,
|
.wValue = 0,
|
||||||
.wIndex = hub_port,
|
.wIndex = hub_port,
|
||||||
.wLength = 4
|
.wLength = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT( usbh_control_xfer( hub_addr, &request, hub_enum_buffer ) );
|
TU_ASSERT( usbh_control_xfer( hub_addr, &request, hub_enum_buffer ) );
|
||||||
|
|
||||||
//------------- Check if feature is cleared -------------//
|
//------------- Check if feature is cleared -------------//
|
||||||
hub_port_status_response_t * p_port_status;
|
hub_port_status_response_t * p_port_status;
|
||||||
p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
|
p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
|
||||||
|
|
||||||
TU_ASSERT( !tu_bit_test(p_port_status->status_change.value, feature-16) );
|
TU_ASSERT( !tu_bit_test(p_port_status->status_change.value, feature-16) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port)
|
bool hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port)
|
||||||
{
|
{
|
||||||
enum { RESET_DELAY = 200 }; // USB specs say only 50ms but many devices require much longer
|
enum { RESET_DELAY = 200 }; // USB specs say only 50ms but many devices require much longer
|
||||||
|
|
||||||
//------------- Set Port Reset -------------//
|
//------------- Set Port Reset -------------//
|
||||||
tusb_control_request_t request = {
|
tusb_control_request_t request = {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = HUB_REQUEST_SET_FEATURE,
|
.bRequest = HUB_REQUEST_SET_FEATURE,
|
||||||
.wValue = HUB_FEATURE_PORT_RESET,
|
.wValue = HUB_FEATURE_PORT_RESET,
|
||||||
.wIndex = hub_port,
|
.wIndex = hub_port,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT( usbh_control_xfer( hub_addr, &request, NULL ) );
|
TU_ASSERT( usbh_control_xfer( hub_addr, &request, NULL ) );
|
||||||
|
|
||||||
osal_task_delay(RESET_DELAY); // TODO Hub wait for Status Endpoint on Reset Change
|
osal_task_delay(RESET_DELAY); // TODO Hub wait for Status Endpoint on Reset Change
|
||||||
|
|
||||||
//------------- Get Port Status to check if port is enabled, powered and reset_change -------------//
|
//------------- Get Port Status to check if port is enabled, powered and reset_change -------------//
|
||||||
request = (tusb_control_request_t ) {
|
request = (tusb_control_request_t ) {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
||||||
.bRequest = HUB_REQUEST_GET_STATUS,
|
.bRequest = HUB_REQUEST_GET_STATUS,
|
||||||
.wValue = 0,
|
.wValue = 0,
|
||||||
.wIndex = hub_port,
|
.wIndex = hub_port,
|
||||||
.wLength = 4
|
.wLength = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT( usbh_control_xfer( hub_addr, &request, hub_enum_buffer ) );
|
TU_ASSERT( usbh_control_xfer( hub_addr, &request, hub_enum_buffer ) );
|
||||||
|
|
||||||
hub_port_status_response_t * p_port_status;
|
hub_port_status_response_t * p_port_status;
|
||||||
p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
|
p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
|
||||||
|
|
||||||
TU_ASSERT ( p_port_status->status_change.reset && p_port_status->status_current.connect_status &&
|
TU_ASSERT ( p_port_status->status_change.reset && p_port_status->status_current.connect_status &&
|
||||||
p_port_status->status_current.port_power && p_port_status->status_current.port_enable);
|
p_port_status->status_current.port_power && p_port_status->status_current.port_enable);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// can only get the speed RIGHT AFTER hub_port_reset_subtask call
|
// can only get the speed RIGHT AFTER hub_port_reset_subtask call
|
||||||
tusb_speed_t hub_port_get_speed(void)
|
tusb_speed_t hub_port_get_speed(void)
|
||||||
{
|
{
|
||||||
hub_port_status_response_t * p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
|
hub_port_status_response_t * p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
|
||||||
return (p_port_status->status_current.high_speed_device_attached) ? TUSB_SPEED_HIGH :
|
return (p_port_status->status_current.high_speed_device_attached) ? TUSB_SPEED_HIGH :
|
||||||
(p_port_status->status_current.low_speed_device_attached ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL;
|
(p_port_status->status_current.low_speed_device_attached ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// CLASS-USBH API (don't require to verify parameters)
|
// CLASS-USBH API (don't require to verify parameters)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void hub_init(void)
|
void hub_init(void)
|
||||||
{
|
{
|
||||||
tu_memclr(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof(usbh_hub_t));
|
tu_memclr(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof(usbh_hub_t));
|
||||||
// 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 *itf_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 ( itf_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 *) tu_desc_next(itf_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 = itf_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);
|
||||||
|
|
||||||
//------------- Get Hub Descriptor -------------//
|
//------------- Get Hub Descriptor -------------//
|
||||||
tusb_control_request_t request = {
|
tusb_control_request_t request = {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
|
||||||
.bRequest = HUB_REQUEST_GET_DESCRIPTOR,
|
.bRequest = HUB_REQUEST_GET_DESCRIPTOR,
|
||||||
.wValue = 0,
|
.wValue = 0,
|
||||||
.wIndex = 0,
|
.wIndex = 0,
|
||||||
.wLength = sizeof(descriptor_hub_desc_t)
|
.wLength = sizeof(descriptor_hub_desc_t)
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_ASSERT( usbh_control_xfer( dev_addr, &request, hub_enum_buffer ) );
|
TU_ASSERT( usbh_control_xfer( dev_addr, &request, hub_enum_buffer ) );
|
||||||
|
|
||||||
// only care about this field in hub descriptor
|
// only care about this field in hub descriptor
|
||||||
hub_data[dev_addr-1].port_number = ((descriptor_hub_desc_t*) hub_enum_buffer)->bNbrPorts;
|
hub_data[dev_addr-1].port_number = ((descriptor_hub_desc_t*) hub_enum_buffer)->bNbrPorts;
|
||||||
|
|
||||||
//------------- Set Port_Power on all ports -------------//
|
//------------- Set Port_Power on all ports -------------//
|
||||||
// TODO may only power port with attached
|
// TODO may only power port with attached
|
||||||
request = (tusb_control_request_t ) {
|
request = (tusb_control_request_t ) {
|
||||||
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
.bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
|
||||||
.bRequest = HUB_REQUEST_SET_FEATURE,
|
.bRequest = HUB_REQUEST_SET_FEATURE,
|
||||||
.wValue = HUB_FEATURE_PORT_POWER,
|
.wValue = HUB_FEATURE_PORT_POWER,
|
||||||
.wIndex = 0,
|
.wIndex = 0,
|
||||||
.wLength = 0
|
.wLength = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
for(uint8_t i=1; i <= hub_data[dev_addr-1].port_number; i++)
|
for(uint8_t i=1; i <= hub_data[dev_addr-1].port_number; i++)
|
||||||
{
|
{
|
||||||
request.wIndex = i;
|
request.wIndex = i;
|
||||||
TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
|
TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Queue the initial Status endpoint transfer -------------//
|
//------------- Queue the initial Status endpoint transfer -------------//
|
||||||
TU_ASSERT( hcd_pipe_xfer(dev_addr, hub_data[dev_addr-1].ep_status, &hub_data[dev_addr-1].status_change, 1, true) );
|
TU_ASSERT( hcd_pipe_xfer(dev_addr, hub_data[dev_addr-1].ep_status, &hub_data[dev_addr-1].status_change, 1, true) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the response of interrupt endpoint polling
|
// is the response of interrupt endpoint polling
|
||||||
#include "usbh_hcd.h" // FIXME remove
|
#include "usbh_hcd.h" // FIXME remove
|
||||||
void hub_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
void hub_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||||
{
|
{
|
||||||
(void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports
|
(void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports
|
||||||
(void) ep_addr;
|
(void) ep_addr;
|
||||||
|
|
||||||
usbh_hub_t * p_hub = &hub_data[dev_addr-1];
|
usbh_hub_t * p_hub = &hub_data[dev_addr-1];
|
||||||
|
|
||||||
if ( event == XFER_RESULT_SUCCESS )
|
if ( event == XFER_RESULT_SUCCESS )
|
||||||
{
|
{
|
||||||
for (uint8_t port=1; port <= p_hub->port_number; port++)
|
for (uint8_t port=1; port <= p_hub->port_number; port++)
|
||||||
{
|
{
|
||||||
// TODO HUB ignore bit0 hub_status_change
|
// TODO HUB ignore bit0 hub_status_change
|
||||||
if ( tu_bit_test(p_hub->status_change, port) )
|
if ( tu_bit_test(p_hub->status_change, port) )
|
||||||
{
|
{
|
||||||
hcd_event_t event =
|
hcd_event_t event =
|
||||||
{
|
{
|
||||||
.rhport = _usbh_devices[dev_addr].rhport,
|
.rhport = _usbh_devices[dev_addr].rhport,
|
||||||
.event_id = HCD_EVENT_DEVICE_ATTACH
|
.event_id = HCD_EVENT_DEVICE_ATTACH
|
||||||
};
|
};
|
||||||
|
|
||||||
event.attach.hub_addr = dev_addr;
|
event.attach.hub_addr = dev_addr;
|
||||||
event.attach.hub_port = port;
|
event.attach.hub_port = port;
|
||||||
|
|
||||||
hcd_event_handler(&event, true);
|
hcd_event_handler(&event, true);
|
||||||
break; // handle one port at a time, next port if any will be handled in the next cycle
|
break; // handle one port at a time, next port if any will be handled in the next cycle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOTE: next status transfer is queued by usbh.c after handling this request
|
// NOTE: next status transfer is queued by usbh.c after handling this request
|
||||||
}
|
}
|
||||||
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 ( hub_status_pipe_queue(dev_addr) );
|
// TU_ASSERT ( hub_status_pipe_queue(dev_addr) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hub_close(uint8_t dev_addr)
|
void hub_close(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
tu_memclr(&hub_data[dev_addr-1], sizeof(usbh_hub_t));
|
tu_memclr(&hub_data[dev_addr-1], sizeof(usbh_hub_t));
|
||||||
// osal_semaphore_reset(hub_enum_sem_hdl);
|
// osal_semaphore_reset(hub_enum_sem_hdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hub_status_pipe_queue(uint8_t dev_addr)
|
bool hub_status_pipe_queue(uint8_t dev_addr)
|
||||||
{
|
{
|
||||||
return hcd_pipe_xfer(dev_addr, hub_data[dev_addr-1].ep_status, &hub_data[dev_addr-1].status_change, 1, true);
|
return hcd_pipe_xfer(dev_addr, hub_data[dev_addr-1].ep_status, &hub_data[dev_addr-1].status_change, 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
388
src/host/hub.h
388
src/host/hub.h
@ -1,194 +1,194 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup group_class
|
/** \ingroup group_class
|
||||||
* \defgroup ClassDriver_Hub Hub (Host only)
|
* \defgroup ClassDriver_Hub Hub (Host only)
|
||||||
* \details Like most PC's OS, Hub support is completely hidden from Application. In fact, application cannot determine whether
|
* \details Like most PC's OS, Hub support is completely hidden from Application. In fact, application cannot determine whether
|
||||||
* a device is mounted directly via roothub or via a hub's port. All Hub-related procedures are performed and managed
|
* a device is mounted directly via roothub or via a hub's port. All Hub-related procedures are performed and managed
|
||||||
* by tinyusb stack. Unless you are trying to develop the stack itself, there are nothing else can be used by Application.
|
* by tinyusb stack. Unless you are trying to develop the stack itself, there are nothing else can be used by Application.
|
||||||
* \note Due to my laziness, only 1-level of Hub is supported. In other way, the stack cannot mount a hub via another hub.
|
* \note Due to my laziness, only 1-level of Hub is supported. In other way, the stack cannot mount a hub via another hub.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_HUB_H_
|
#ifndef _TUSB_HUB_H_
|
||||||
#define _TUSB_HUB_H_
|
#define _TUSB_HUB_H_
|
||||||
|
|
||||||
#include <common/tusb_common.h>
|
#include <common/tusb_common.h>
|
||||||
#include "usbh.h"
|
#include "usbh.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//D1...D0: Logical Power Switching Mode
|
//D1...D0: Logical Power Switching Mode
|
||||||
//00: Ganged power switching (all ports’power at
|
//00: Ganged power switching (all ports’power at
|
||||||
//once)
|
//once)
|
||||||
//01: Individual port power switching
|
//01: Individual port power switching
|
||||||
//1X: Reserved. Used only on 1.0 compliant hubs
|
//1X: Reserved. Used only on 1.0 compliant hubs
|
||||||
//that implement no power switching
|
//that implement no power switching
|
||||||
//D2: Identifies a Compound Device
|
//D2: Identifies a Compound Device
|
||||||
//0: Hub is not part of a compound device.
|
//0: Hub is not part of a compound device.
|
||||||
//1: Hub is part of a compound device.
|
//1: Hub is part of a compound device.
|
||||||
//D4...D3: Over-current Protection Mode
|
//D4...D3: Over-current Protection Mode
|
||||||
//00: Global Over-current Protection. The hub
|
//00: Global Over-current Protection. The hub
|
||||||
//reports over-current as a summation of all
|
//reports over-current as a summation of all
|
||||||
//ports’current draw, without a breakdown of
|
//ports’current draw, without a breakdown of
|
||||||
//individual port over-current status.
|
//individual port over-current status.
|
||||||
//01: Individual Port Over-current Protection. The
|
//01: Individual Port Over-current Protection. The
|
||||||
//hub reports over-current on a per-port basis.
|
//hub reports over-current on a per-port basis.
|
||||||
//Each port has an over-current status.
|
//Each port has an over-current status.
|
||||||
//1X: No Over-current Protection. This option is
|
//1X: No Over-current Protection. This option is
|
||||||
//allowed only for bus-powered hubs that do not
|
//allowed only for bus-powered hubs that do not
|
||||||
//implement over-current protection.
|
//implement over-current protection.
|
||||||
//
|
//
|
||||||
//D6...D5: TT Think TIme
|
//D6...D5: TT Think TIme
|
||||||
//00: TT requires at most 8 FS bit times of inter
|
//00: TT requires at most 8 FS bit times of inter
|
||||||
//transaction gap on a full-/low-speed
|
//transaction gap on a full-/low-speed
|
||||||
//downstream bus.
|
//downstream bus.
|
||||||
//01: TT requires at most 16 FS bit times.
|
//01: TT requires at most 16 FS bit times.
|
||||||
//10: TT requires at most 24 FS bit times.
|
//10: TT requires at most 24 FS bit times.
|
||||||
//11: TT requires at most 32 FS bit times.
|
//11: TT requires at most 32 FS bit times.
|
||||||
//D7: Port Indicators Supported
|
//D7: Port Indicators Supported
|
||||||
//0: Port Indicators are not supported on its
|
//0: Port Indicators are not supported on its
|
||||||
//downstream facing ports and the
|
//downstream facing ports and the
|
||||||
//PORT_INDICATOR request has no effect.
|
//PORT_INDICATOR request has no effect.
|
||||||
//1: Port Indicators are supported on its
|
//1: Port Indicators are supported on its
|
||||||
//downstream facing ports and the
|
//downstream facing ports and the
|
||||||
//PORT_INDICATOR request controls the
|
//PORT_INDICATOR request controls the
|
||||||
//indicators. See Section 11.5.3.
|
//indicators. See Section 11.5.3.
|
||||||
//D15...D8: Reserved
|
//D15...D8: Reserved
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED{
|
typedef struct TU_ATTR_PACKED{
|
||||||
uint8_t bLength ; ///< Size of descriptor
|
uint8_t bLength ; ///< Size of descriptor
|
||||||
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
|
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
|
||||||
uint8_t bNbrPorts;
|
uint8_t bNbrPorts;
|
||||||
uint16_t wHubCharacteristics;
|
uint16_t wHubCharacteristics;
|
||||||
uint8_t bPwrOn2PwrGood;
|
uint8_t bPwrOn2PwrGood;
|
||||||
uint8_t bHubContrCurrent;
|
uint8_t bHubContrCurrent;
|
||||||
uint8_t DeviceRemovable; // bitmap each bit for a port (from bit1)
|
uint8_t DeviceRemovable; // bitmap each bit for a port (from bit1)
|
||||||
uint8_t PortPwrCtrlMask; // just for compatibility, should be 0xff
|
uint8_t PortPwrCtrlMask; // just for compatibility, should be 0xff
|
||||||
} descriptor_hub_desc_t;
|
} descriptor_hub_desc_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(descriptor_hub_desc_t) == 9, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(descriptor_hub_desc_t) == 9, "size is not correct");
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HUB_REQUEST_GET_STATUS = 0 ,
|
HUB_REQUEST_GET_STATUS = 0 ,
|
||||||
HUB_REQUEST_CLEAR_FEATURE = 1 ,
|
HUB_REQUEST_CLEAR_FEATURE = 1 ,
|
||||||
|
|
||||||
HUB_REQUEST_SET_FEATURE = 3 ,
|
HUB_REQUEST_SET_FEATURE = 3 ,
|
||||||
|
|
||||||
HUB_REQUEST_GET_DESCRIPTOR = 6 ,
|
HUB_REQUEST_GET_DESCRIPTOR = 6 ,
|
||||||
HUB_REQUEST_SET_DESCRIPTOR = 7 ,
|
HUB_REQUEST_SET_DESCRIPTOR = 7 ,
|
||||||
HUB_REQUEST_CLEAR_TT_BUFFER = 8 ,
|
HUB_REQUEST_CLEAR_TT_BUFFER = 8 ,
|
||||||
HUB_REQUEST_RESET_TT = 9 ,
|
HUB_REQUEST_RESET_TT = 9 ,
|
||||||
HUB_REQUEST_GET_TT_STATE = 10 ,
|
HUB_REQUEST_GET_TT_STATE = 10 ,
|
||||||
HUB_REQUEST_STOP_TT = 11
|
HUB_REQUEST_STOP_TT = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HUB_FEATURE_HUB_LOCAL_POWER_CHANGE = 0,
|
HUB_FEATURE_HUB_LOCAL_POWER_CHANGE = 0,
|
||||||
HUB_FEATURE_HUB_OVER_CURRENT_CHANGE
|
HUB_FEATURE_HUB_OVER_CURRENT_CHANGE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
HUB_FEATURE_PORT_CONNECTION = 0,
|
HUB_FEATURE_PORT_CONNECTION = 0,
|
||||||
HUB_FEATURE_PORT_ENABLE = 1,
|
HUB_FEATURE_PORT_ENABLE = 1,
|
||||||
HUB_FEATURE_PORT_SUSPEND = 2,
|
HUB_FEATURE_PORT_SUSPEND = 2,
|
||||||
HUB_FEATURE_PORT_OVER_CURRENT = 3,
|
HUB_FEATURE_PORT_OVER_CURRENT = 3,
|
||||||
HUB_FEATURE_PORT_RESET = 4,
|
HUB_FEATURE_PORT_RESET = 4,
|
||||||
|
|
||||||
HUB_FEATURE_PORT_POWER = 8,
|
HUB_FEATURE_PORT_POWER = 8,
|
||||||
HUB_FEATURE_PORT_LOW_SPEED = 9,
|
HUB_FEATURE_PORT_LOW_SPEED = 9,
|
||||||
|
|
||||||
HUB_FEATURE_PORT_CONNECTION_CHANGE = 16,
|
HUB_FEATURE_PORT_CONNECTION_CHANGE = 16,
|
||||||
HUB_FEATURE_PORT_ENABLE_CHANGE = 17,
|
HUB_FEATURE_PORT_ENABLE_CHANGE = 17,
|
||||||
HUB_FEATURE_PORT_SUSPEND_CHANGE = 18,
|
HUB_FEATURE_PORT_SUSPEND_CHANGE = 18,
|
||||||
HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19,
|
HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19,
|
||||||
HUB_FEATURE_PORT_RESET_CHANGE = 20,
|
HUB_FEATURE_PORT_RESET_CHANGE = 20,
|
||||||
HUB_FEATURE_PORT_TEST = 21,
|
HUB_FEATURE_PORT_TEST = 21,
|
||||||
HUB_FEATURE_PORT_INDICATOR = 22
|
HUB_FEATURE_PORT_INDICATOR = 22
|
||||||
};
|
};
|
||||||
|
|
||||||
// data in response of HUB_REQUEST_GET_STATUS, wIndex = 0 (hub)
|
// data in response of HUB_REQUEST_GET_STATUS, wIndex = 0 (hub)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union{
|
union{
|
||||||
struct TU_ATTR_PACKED {
|
struct TU_ATTR_PACKED {
|
||||||
uint16_t local_power_source : 1;
|
uint16_t local_power_source : 1;
|
||||||
uint16_t over_current : 1;
|
uint16_t over_current : 1;
|
||||||
uint16_t : 14;
|
uint16_t : 14;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t value;
|
uint16_t value;
|
||||||
} status, status_change;
|
} status, status_change;
|
||||||
} hub_status_response_t;
|
} hub_status_response_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct");
|
||||||
|
|
||||||
// data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num
|
// data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
struct TU_ATTR_PACKED {
|
struct TU_ATTR_PACKED {
|
||||||
uint16_t connect_status : 1;
|
uint16_t connect_status : 1;
|
||||||
uint16_t port_enable : 1;
|
uint16_t port_enable : 1;
|
||||||
uint16_t suspend : 1;
|
uint16_t suspend : 1;
|
||||||
uint16_t over_current : 1;
|
uint16_t over_current : 1;
|
||||||
uint16_t reset : 1;
|
uint16_t reset : 1;
|
||||||
|
|
||||||
uint16_t : 3;
|
uint16_t : 3;
|
||||||
uint16_t port_power : 1;
|
uint16_t port_power : 1;
|
||||||
uint16_t low_speed_device_attached : 1;
|
uint16_t low_speed_device_attached : 1;
|
||||||
uint16_t high_speed_device_attached : 1;
|
uint16_t high_speed_device_attached : 1;
|
||||||
uint16_t port_test_mode : 1;
|
uint16_t port_test_mode : 1;
|
||||||
uint16_t port_indicator_control : 1;
|
uint16_t port_indicator_control : 1;
|
||||||
uint16_t : 0;
|
uint16_t : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t value;
|
uint16_t value;
|
||||||
} status_current, status_change;
|
} status_current, status_change;
|
||||||
} hub_port_status_response_t;
|
} hub_port_status_response_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct");
|
||||||
|
|
||||||
bool hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port);
|
bool hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port);
|
||||||
bool hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature);
|
bool hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature);
|
||||||
tusb_speed_t hub_port_get_speed(void);
|
tusb_speed_t hub_port_get_speed(void);
|
||||||
bool hub_status_pipe_queue(uint8_t dev_addr);
|
bool hub_status_pipe_queue(uint8_t dev_addr);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Internal Class Driver API
|
// Internal Class Driver API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void hub_init(void);
|
void hub_init(void);
|
||||||
bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_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);
|
||||||
void hub_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
void hub_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
void hub_close(uint8_t dev_addr);
|
void hub_close(uint8_t dev_addr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_HUB_H_ */
|
#endif /* _TUSB_HUB_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
1302
src/host/ohci/ohci.c
1302
src/host/ohci/ohci.c
File diff suppressed because it is too large
Load Diff
@ -1,291 +1,291 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_HCD
|
/** \ingroup Group_HCD
|
||||||
* @{
|
* @{
|
||||||
* \defgroup OHCI
|
* \defgroup OHCI
|
||||||
* \brief OHCI driver. All documents sources mentioned here (eg section 3.5) is referring to OHCI Specs unless state otherwise
|
* \brief OHCI driver. All documents sources mentioned here (eg section 3.5) is referring to OHCI Specs unless state otherwise
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#ifndef _TUSB_OHCI_H_
|
#ifndef _TUSB_OHCI_H_
|
||||||
#define _TUSB_OHCI_H_
|
#define _TUSB_OHCI_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// OHCI CONFIGURATION & CONSTANTS
|
// OHCI CONFIGURATION & CONSTANTS
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed
|
#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed
|
||||||
#define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS)
|
#define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS)
|
||||||
|
|
||||||
// TODO merge OHCI with EHCI
|
// TODO merge OHCI with EHCI
|
||||||
enum {
|
enum {
|
||||||
OHCI_MAX_ITD = 4
|
OHCI_MAX_ITD = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OHCI_PID_SETUP = 0,
|
OHCI_PID_SETUP = 0,
|
||||||
OHCI_PID_OUT,
|
OHCI_PID_OUT,
|
||||||
OHCI_PID_IN,
|
OHCI_PID_IN,
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// OHCI Data Structure
|
// OHCI Data Structure
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t interrupt_table[32];
|
uint32_t interrupt_table[32];
|
||||||
volatile uint16_t frame_number;
|
volatile uint16_t frame_number;
|
||||||
volatile uint16_t frame_pad;
|
volatile uint16_t frame_pad;
|
||||||
volatile uint32_t done_head;
|
volatile uint32_t done_head;
|
||||||
uint8_t reserved[116+4]; // TODO try to make use of this area if possible, extra 4 byte to make the whole struct size = 256
|
uint8_t reserved[116+4]; // TODO try to make use of this area if possible, extra 4 byte to make the whole struct size = 256
|
||||||
}ohci_hcca_t; // TU_ATTR_ALIGNED(256)
|
}ohci_hcca_t; // TU_ATTR_ALIGNED(256)
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" );
|
TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" );
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t reserved[2];
|
uint32_t reserved[2];
|
||||||
volatile uint32_t next;
|
volatile uint32_t next;
|
||||||
uint32_t reserved2;
|
uint32_t reserved2;
|
||||||
}ohci_td_item_t;
|
}ohci_td_item_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct TU_ATTR_ALIGNED(16)
|
typedef struct TU_ATTR_ALIGNED(16)
|
||||||
{
|
{
|
||||||
// Word 0
|
// Word 0
|
||||||
uint32_t used : 1;
|
uint32_t used : 1;
|
||||||
uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer
|
uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer
|
||||||
uint32_t expected_bytes : 13; // TODO available for hcd
|
uint32_t expected_bytes : 13; // TODO available for hcd
|
||||||
|
|
||||||
uint32_t buffer_rounding : 1;
|
uint32_t buffer_rounding : 1;
|
||||||
uint32_t pid : 2;
|
uint32_t pid : 2;
|
||||||
uint32_t delay_interrupt : 3;
|
uint32_t delay_interrupt : 3;
|
||||||
volatile uint32_t data_toggle : 2;
|
volatile uint32_t data_toggle : 2;
|
||||||
volatile uint32_t error_count : 2;
|
volatile uint32_t error_count : 2;
|
||||||
volatile uint32_t condition_code : 4;
|
volatile uint32_t condition_code : 4;
|
||||||
|
|
||||||
// Word 1
|
// Word 1
|
||||||
volatile uint8_t* current_buffer_pointer;
|
volatile uint8_t* current_buffer_pointer;
|
||||||
|
|
||||||
// Word 2 : next TD
|
// Word 2 : next TD
|
||||||
volatile uint32_t next;
|
volatile uint32_t next;
|
||||||
|
|
||||||
// Word 3
|
// Word 3
|
||||||
uint8_t* buffer_end;
|
uint8_t* buffer_end;
|
||||||
} ohci_gtd_t;
|
} ohci_gtd_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(ohci_gtd_t) == 16, "size is not correct" );
|
TU_VERIFY_STATIC( sizeof(ohci_gtd_t) == 16, "size is not correct" );
|
||||||
|
|
||||||
typedef struct TU_ATTR_ALIGNED(16)
|
typedef struct TU_ATTR_ALIGNED(16)
|
||||||
{
|
{
|
||||||
// Word 0
|
// Word 0
|
||||||
uint32_t dev_addr : 7;
|
uint32_t dev_addr : 7;
|
||||||
uint32_t ep_number : 4;
|
uint32_t ep_number : 4;
|
||||||
uint32_t pid : 2; // 00b from TD, 01b Out, 10b In
|
uint32_t pid : 2; // 00b from TD, 01b Out, 10b In
|
||||||
uint32_t speed : 1;
|
uint32_t speed : 1;
|
||||||
uint32_t skip : 1;
|
uint32_t skip : 1;
|
||||||
uint32_t is_iso : 1;
|
uint32_t is_iso : 1;
|
||||||
uint32_t max_packet_size : 11;
|
uint32_t max_packet_size : 11;
|
||||||
// HCD: make use of 5 reserved bits
|
// HCD: make use of 5 reserved bits
|
||||||
uint32_t used : 1;
|
uint32_t used : 1;
|
||||||
uint32_t is_interrupt_xfer : 1;
|
uint32_t is_interrupt_xfer : 1;
|
||||||
uint32_t is_stalled : 1;
|
uint32_t is_stalled : 1;
|
||||||
uint32_t : 2;
|
uint32_t : 2;
|
||||||
|
|
||||||
// Word 1
|
// Word 1
|
||||||
uint32_t td_tail;
|
uint32_t td_tail;
|
||||||
|
|
||||||
// Word 2
|
// Word 2
|
||||||
volatile union {
|
volatile union {
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
struct {
|
struct {
|
||||||
uint32_t halted : 1;
|
uint32_t halted : 1;
|
||||||
uint32_t toggle : 1;
|
uint32_t toggle : 1;
|
||||||
uint32_t : 30;
|
uint32_t : 30;
|
||||||
};
|
};
|
||||||
}td_head;
|
}td_head;
|
||||||
|
|
||||||
// Word 3: next ED
|
// Word 3: next ED
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
} ohci_ed_t;
|
} ohci_ed_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(ohci_ed_t) == 16, "size is not correct" );
|
TU_VERIFY_STATIC( sizeof(ohci_ed_t) == 16, "size is not correct" );
|
||||||
|
|
||||||
typedef struct TU_ATTR_ALIGNED(32)
|
typedef struct TU_ATTR_ALIGNED(32)
|
||||||
{
|
{
|
||||||
/*---------- Word 1 ----------*/
|
/*---------- Word 1 ----------*/
|
||||||
uint32_t starting_frame : 16;
|
uint32_t starting_frame : 16;
|
||||||
uint32_t : 5; // can be used
|
uint32_t : 5; // can be used
|
||||||
uint32_t delay_interrupt : 3;
|
uint32_t delay_interrupt : 3;
|
||||||
uint32_t frame_count : 3;
|
uint32_t frame_count : 3;
|
||||||
uint32_t : 1; // can be used
|
uint32_t : 1; // can be used
|
||||||
volatile uint32_t condition_code : 4;
|
volatile uint32_t condition_code : 4;
|
||||||
|
|
||||||
/*---------- Word 2 ----------*/
|
/*---------- Word 2 ----------*/
|
||||||
uint32_t buffer_page0; // 12 lsb bits can be used
|
uint32_t buffer_page0; // 12 lsb bits can be used
|
||||||
|
|
||||||
/*---------- Word 3 ----------*/
|
/*---------- Word 3 ----------*/
|
||||||
volatile uint32_t next;
|
volatile uint32_t next;
|
||||||
|
|
||||||
/*---------- Word 4 ----------*/
|
/*---------- Word 4 ----------*/
|
||||||
uint32_t buffer_end;
|
uint32_t buffer_end;
|
||||||
|
|
||||||
/*---------- Word 5-8 ----------*/
|
/*---------- Word 5-8 ----------*/
|
||||||
volatile uint16_t offset_packetstatus[8];
|
volatile uint16_t offset_packetstatus[8];
|
||||||
} ochi_itd_t;
|
} ochi_itd_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
|
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
|
||||||
|
|
||||||
// structure with member alignment required from large to small
|
// structure with member alignment required from large to small
|
||||||
typedef struct TU_ATTR_ALIGNED(256)
|
typedef struct TU_ATTR_ALIGNED(256)
|
||||||
{
|
{
|
||||||
ohci_hcca_t hcca;
|
ohci_hcca_t hcca;
|
||||||
|
|
||||||
ohci_ed_t bulk_head_ed; // static bulk head (dummy)
|
ohci_ed_t bulk_head_ed; // static bulk head (dummy)
|
||||||
ohci_ed_t period_head_ed; // static periodic list head (dummy)
|
ohci_ed_t period_head_ed; // static periodic list head (dummy)
|
||||||
|
|
||||||
// control endpoints has reserved resources
|
// control endpoints has reserved resources
|
||||||
struct {
|
struct {
|
||||||
ohci_ed_t ed;
|
ohci_ed_t ed;
|
||||||
ohci_gtd_t gtd;
|
ohci_gtd_t gtd;
|
||||||
}control[CFG_TUSB_HOST_DEVICE_MAX+1];
|
}control[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||||
|
|
||||||
// ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32
|
// ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32
|
||||||
ohci_ed_t ed_pool[HCD_MAX_ENDPOINT];
|
ohci_ed_t ed_pool[HCD_MAX_ENDPOINT];
|
||||||
ohci_gtd_t gtd_pool[HCD_MAX_XFER];
|
ohci_gtd_t gtd_pool[HCD_MAX_XFER];
|
||||||
|
|
||||||
} ohci_data_t;
|
} ohci_data_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// OHCI Operational Register
|
// OHCI Operational Register
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// OHCI Data Organization
|
// OHCI Data Organization
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef volatile struct
|
typedef volatile struct
|
||||||
{
|
{
|
||||||
uint32_t revision;
|
uint32_t revision;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t control;
|
uint32_t control;
|
||||||
struct {
|
struct {
|
||||||
uint32_t control_bulk_service_ratio : 2;
|
uint32_t control_bulk_service_ratio : 2;
|
||||||
uint32_t periodic_list_enable : 1;
|
uint32_t periodic_list_enable : 1;
|
||||||
uint32_t isochronous_enable : 1;
|
uint32_t isochronous_enable : 1;
|
||||||
uint32_t control_list_enable : 1;
|
uint32_t control_list_enable : 1;
|
||||||
uint32_t bulk_list_enable : 1;
|
uint32_t bulk_list_enable : 1;
|
||||||
uint32_t hc_functional_state : 2;
|
uint32_t hc_functional_state : 2;
|
||||||
uint32_t interrupt_routing : 1;
|
uint32_t interrupt_routing : 1;
|
||||||
uint32_t remote_wakeup_connected : 1;
|
uint32_t remote_wakeup_connected : 1;
|
||||||
uint32_t remote_wakeup_enale : 1;
|
uint32_t remote_wakeup_enale : 1;
|
||||||
uint32_t : 0;
|
uint32_t : 0;
|
||||||
}control_bit;
|
}control_bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t command_status;
|
uint32_t command_status;
|
||||||
struct {
|
struct {
|
||||||
uint32_t controller_reset : 1;
|
uint32_t controller_reset : 1;
|
||||||
uint32_t control_list_filled : 1;
|
uint32_t control_list_filled : 1;
|
||||||
uint32_t bulk_list_filled : 1;
|
uint32_t bulk_list_filled : 1;
|
||||||
uint32_t ownership_change_request : 1;
|
uint32_t ownership_change_request : 1;
|
||||||
uint32_t : 12;
|
uint32_t : 12;
|
||||||
uint32_t scheduling_overrun_count : 2;
|
uint32_t scheduling_overrun_count : 2;
|
||||||
}command_status_bit;
|
}command_status_bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t interrupt_status;
|
uint32_t interrupt_status;
|
||||||
uint32_t interrupt_enable;
|
uint32_t interrupt_enable;
|
||||||
uint32_t interrupt_disable;
|
uint32_t interrupt_disable;
|
||||||
|
|
||||||
uint32_t hcca;
|
uint32_t hcca;
|
||||||
uint32_t period_current_ed;
|
uint32_t period_current_ed;
|
||||||
uint32_t control_head_ed;
|
uint32_t control_head_ed;
|
||||||
uint32_t control_current_ed;
|
uint32_t control_current_ed;
|
||||||
uint32_t bulk_head_ed;
|
uint32_t bulk_head_ed;
|
||||||
uint32_t bulk_current_ed;
|
uint32_t bulk_current_ed;
|
||||||
uint32_t done_head;
|
uint32_t done_head;
|
||||||
|
|
||||||
uint32_t frame_interval;
|
uint32_t frame_interval;
|
||||||
uint32_t frame_remaining;
|
uint32_t frame_remaining;
|
||||||
uint32_t frame_number;
|
uint32_t frame_number;
|
||||||
uint32_t periodic_start;
|
uint32_t periodic_start;
|
||||||
uint32_t lowspeed_threshold;
|
uint32_t lowspeed_threshold;
|
||||||
|
|
||||||
uint32_t rh_descriptorA;
|
uint32_t rh_descriptorA;
|
||||||
uint32_t rh_descriptorB;
|
uint32_t rh_descriptorB;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t rh_status;
|
uint32_t rh_status;
|
||||||
struct {
|
struct {
|
||||||
uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power
|
uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power
|
||||||
uint32_t over_current_indicator : 1;
|
uint32_t over_current_indicator : 1;
|
||||||
uint32_t : 13;
|
uint32_t : 13;
|
||||||
uint32_t device_remote_wakeup_enable : 1;
|
uint32_t device_remote_wakeup_enable : 1;
|
||||||
uint32_t local_power_status_change : 1;
|
uint32_t local_power_status_change : 1;
|
||||||
uint32_t over_current_indicator_change : 1;
|
uint32_t over_current_indicator_change : 1;
|
||||||
uint32_t : 13;
|
uint32_t : 13;
|
||||||
uint32_t clear_remote_wakeup_enable : 1;
|
uint32_t clear_remote_wakeup_enable : 1;
|
||||||
}rh_status_bit;
|
}rh_status_bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t rhport_status[2]; // TODO NXP OHCI controller only has 2 ports
|
uint32_t rhport_status[2]; // TODO NXP OHCI controller only has 2 ports
|
||||||
struct {
|
struct {
|
||||||
uint32_t current_connect_status : 1;
|
uint32_t current_connect_status : 1;
|
||||||
uint32_t port_enable_status : 1;
|
uint32_t port_enable_status : 1;
|
||||||
uint32_t port_suspend_status : 1;
|
uint32_t port_suspend_status : 1;
|
||||||
uint32_t port_over_current_indicator : 1;
|
uint32_t port_over_current_indicator : 1;
|
||||||
uint32_t port_reset_status : 1;
|
uint32_t port_reset_status : 1;
|
||||||
uint32_t : 3;
|
uint32_t : 3;
|
||||||
uint32_t port_power_status : 1;
|
uint32_t port_power_status : 1;
|
||||||
uint32_t low_speed_device_attached : 1;
|
uint32_t low_speed_device_attached : 1;
|
||||||
uint32_t : 6;
|
uint32_t : 6;
|
||||||
uint32_t connect_status_change : 1;
|
uint32_t connect_status_change : 1;
|
||||||
uint32_t port_enable_status_change : 1;
|
uint32_t port_enable_status_change : 1;
|
||||||
uint32_t port_suspend_status_change : 1;
|
uint32_t port_suspend_status_change : 1;
|
||||||
uint32_t port_over_current_indicator_change : 1;
|
uint32_t port_over_current_indicator_change : 1;
|
||||||
uint32_t port_reset_status_change : 1;
|
uint32_t port_reset_status_change : 1;
|
||||||
uint32_t : 0;
|
uint32_t : 0;
|
||||||
}rhport_status_bit[2];
|
}rhport_status_bit[2];
|
||||||
};
|
};
|
||||||
}ohci_registers_t;
|
}ohci_registers_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(ohci_registers_t) == 0x5c, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(ohci_registers_t) == 0x5c, "size is not correct");
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_OHCI_H_ */
|
#endif /* _TUSB_OHCI_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
1352
src/host/usbh.c
1352
src/host/usbh.c
File diff suppressed because it is too large
Load Diff
196
src/osal/osal.h
196
src/osal/osal.h
@ -1,98 +1,98 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_OSAL_H_
|
#ifndef _TUSB_OSAL_H_
|
||||||
#define _TUSB_OSAL_H_
|
#define _TUSB_OSAL_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \addtogroup group_osal
|
/** \addtogroup group_osal
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OSAL_TIMEOUT_NOTIMEOUT = 0, // return immediately
|
OSAL_TIMEOUT_NOTIMEOUT = 0, // return immediately
|
||||||
OSAL_TIMEOUT_NORMAL = 10, // default timeout
|
OSAL_TIMEOUT_NORMAL = 10, // default timeout
|
||||||
OSAL_TIMEOUT_WAIT_FOREVER = 0xFFFFFFFFUL
|
OSAL_TIMEOUT_WAIT_FOREVER = 0xFFFFFFFFUL
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER
|
#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER
|
||||||
|
|
||||||
typedef void (*osal_task_func_t)( void * );
|
typedef void (*osal_task_func_t)( void * );
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
#include "osal_none.h"
|
#include "osal_none.h"
|
||||||
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||||
#include "osal_freertos.h"
|
#include "osal_freertos.h"
|
||||||
#elif CFG_TUSB_OS == OPT_OS_MYNEWT
|
#elif CFG_TUSB_OS == OPT_OS_MYNEWT
|
||||||
#include "osal_mynewt.h"
|
#include "osal_mynewt.h"
|
||||||
#else
|
#else
|
||||||
#error OS is not supported yet
|
#error OS is not supported yet
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// OSAL Porting API
|
// OSAL Porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static inline void osal_task_delay(uint32_t msec);
|
static inline void osal_task_delay(uint32_t msec);
|
||||||
|
|
||||||
//------------- Semaphore -------------//
|
//------------- Semaphore -------------//
|
||||||
static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
|
static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
|
||||||
static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
|
static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
|
||||||
static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
|
static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
|
||||||
|
|
||||||
static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
|
static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
|
||||||
|
|
||||||
//------------- Mutex -------------//
|
//------------- Mutex -------------//
|
||||||
static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
|
static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
|
||||||
static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
|
static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
|
||||||
static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
|
static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
|
||||||
|
|
||||||
//------------- Queue -------------//
|
//------------- Queue -------------//
|
||||||
static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
|
static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
|
||||||
static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data);
|
static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data);
|
||||||
static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr);
|
static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr);
|
||||||
|
|
||||||
#if 0 // TODO remove subtask related macros later
|
#if 0 // TODO remove subtask related macros later
|
||||||
// Sub Task
|
// Sub Task
|
||||||
#define OSAL_SUBTASK_BEGIN
|
#define OSAL_SUBTASK_BEGIN
|
||||||
#define OSAL_SUBTASK_END return TUSB_ERROR_NONE;
|
#define OSAL_SUBTASK_END return TUSB_ERROR_NONE;
|
||||||
|
|
||||||
#define STASK_RETURN(_error) return _error;
|
#define STASK_RETURN(_error) return _error;
|
||||||
#define STASK_INVOKE(_subtask, _status) (_status) = _subtask
|
#define STASK_INVOKE(_subtask, _status) (_status) = _subtask
|
||||||
#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED)
|
#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* _TUSB_OSAL_H_ */
|
#endif /* _TUSB_OSAL_H_ */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user