mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-16 05:42:56 +00:00
Merge branch 'master' of https://github.com/YixingShen/tinyusb
This commit is contained in:
commit
2f2d2bcf3e
2
.github/workflows/build_aarch64.yml
vendored
2
.github/workflows/build_aarch64.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
|||||||
- 'broadcom_64bit'
|
- 'broadcom_64bit'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
4
.github/workflows/build_arm.yml
vendored
4
.github/workflows/build_arm.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
|||||||
# Alphabetical order
|
# Alphabetical order
|
||||||
- 'broadcom_32bit'
|
- 'broadcom_32bit'
|
||||||
- 'kinetis_k32l2'
|
- 'kinetis_k32l2'
|
||||||
- 'lpc11 lpc13 lpc15 lpc17'
|
- 'lpc11 lpc13 lpc15'
|
||||||
- 'lpc51'
|
- 'lpc51'
|
||||||
- 'mm32 msp432e4'
|
- 'mm32 msp432e4'
|
||||||
- 'samd11 same5x saml2x'
|
- 'samd11 same5x saml2x'
|
||||||
@ -46,7 +46,7 @@ jobs:
|
|||||||
- 'tm4c123 xmc4000'
|
- 'tm4c123 xmc4000'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
4
.github/workflows/build_esp.yml
vendored
4
.github/workflows/build_esp.yml
vendored
@ -8,6 +8,7 @@ on:
|
|||||||
- 'examples/**'
|
- 'examples/**'
|
||||||
- 'lib/**'
|
- 'lib/**'
|
||||||
- 'hw/**'
|
- 'hw/**'
|
||||||
|
- 'test/hil/**'
|
||||||
- '.github/workflows/build_esp.yml'
|
- '.github/workflows/build_esp.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
@ -16,6 +17,7 @@ on:
|
|||||||
- 'examples/**'
|
- 'examples/**'
|
||||||
- 'lib/**'
|
- 'lib/**'
|
||||||
- 'hw/**'
|
- 'hw/**'
|
||||||
|
- 'test/hil/**'
|
||||||
- '.github/workflows/build_esp.yml'
|
- '.github/workflows/build_esp.yml'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
@ -35,7 +37,7 @@ jobs:
|
|||||||
- 'espressif_s3_devkitc'
|
- 'espressif_s3_devkitc'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
2
.github/workflows/build_iar.yml
vendored
2
.github/workflows/build_iar.yml
vendored
@ -9,6 +9,7 @@ on:
|
|||||||
- 'lib/**'
|
- 'lib/**'
|
||||||
- 'hw/**'
|
- 'hw/**'
|
||||||
- 'tools/get_deps.py'
|
- 'tools/get_deps.py'
|
||||||
|
- 'test/hil/**'
|
||||||
- '.github/workflows/build_iar.yml'
|
- '.github/workflows/build_iar.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
@ -18,6 +19,7 @@ on:
|
|||||||
- 'lib/**'
|
- 'lib/**'
|
||||||
- 'hw/**'
|
- 'hw/**'
|
||||||
- 'tools/get_deps.py'
|
- 'tools/get_deps.py'
|
||||||
|
- 'test/hil/**'
|
||||||
- '.github/workflows/build_iar.yml'
|
- '.github/workflows/build_iar.yml'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
2
.github/workflows/build_msp430.yml
vendored
2
.github/workflows/build_msp430.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
2
.github/workflows/build_renesas.yml
vendored
2
.github/workflows/build_renesas.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
- 'rx'
|
- 'rx'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
2
.github/workflows/build_riscv.yml
vendored
2
.github/workflows/build_riscv.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
|||||||
- 'gd32vf103'
|
- 'gd32vf103'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
2
.github/workflows/build_win_mac.yml
vendored
2
.github/workflows/build_win_mac.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
6
.github/workflows/cmake_arm.yml
vendored
6
.github/workflows/cmake_arm.yml
vendored
@ -8,6 +8,7 @@ on:
|
|||||||
- 'examples/**'
|
- 'examples/**'
|
||||||
- 'lib/**'
|
- 'lib/**'
|
||||||
- 'hw/**'
|
- 'hw/**'
|
||||||
|
- 'test/hil/**'
|
||||||
- 'tools/get_deps.py'
|
- 'tools/get_deps.py'
|
||||||
- '.github/workflows/cmake_arm.yml'
|
- '.github/workflows/cmake_arm.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -17,6 +18,7 @@ on:
|
|||||||
- 'examples/**'
|
- 'examples/**'
|
||||||
- 'lib/**'
|
- 'lib/**'
|
||||||
- 'hw/**'
|
- 'hw/**'
|
||||||
|
- 'test/hil/**'
|
||||||
- 'tools/get_deps.py'
|
- 'tools/get_deps.py'
|
||||||
- '.github/workflows/cmake_arm.yml'
|
- '.github/workflows/cmake_arm.yml'
|
||||||
|
|
||||||
@ -37,7 +39,7 @@ jobs:
|
|||||||
# Alphabetical order
|
# Alphabetical order
|
||||||
- 'imxrt'
|
- 'imxrt'
|
||||||
- 'kinetis_kl'
|
- 'kinetis_kl'
|
||||||
- 'lpc18 lpc40 lpc43'
|
- 'lpc17 lpc18 lpc40 lpc43'
|
||||||
- 'lpc54 lpc55'
|
- 'lpc54 lpc55'
|
||||||
- 'mcx'
|
- 'mcx'
|
||||||
- 'nrf'
|
- 'nrf'
|
||||||
@ -57,7 +59,7 @@ jobs:
|
|||||||
- 'stm32u5'
|
- 'stm32u5'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
|
1
.idea/cmake.xml
generated
1
.idea/cmake.xml
generated
@ -80,6 +80,7 @@
|
|||||||
<configuration PROFILE_NAME="ra6m5 PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1 -DPORT=0" />
|
<configuration PROFILE_NAME="ra6m5 PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1 -DPORT=0" />
|
||||||
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
|
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
|
||||||
|
<configuration PROFILE_NAME="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=3 -DLOGGER=RTT" />
|
||||||
</configurations>
|
</configurations>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,4 +1,5 @@
|
|||||||
#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
|
// uncopmressed frame
|
||||||
static const unsigned char frame_buffer[128 * (96 + 1) * 2] = {
|
static const unsigned char frame_buffer[128 * (96 + 1) * 2] = {
|
||||||
/* 0 */
|
/* 0 */
|
||||||
0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80,
|
0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80,
|
||||||
@ -1650,8 +1651,10 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = {
|
|||||||
0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
|
0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
|
||||||
0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
|
0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
#define color_bar_0_jpg_len 511
|
#define color_bar_0_jpg_len 511
|
||||||
#define color_bar_1_jpg_len 512
|
#define color_bar_1_jpg_len 512
|
||||||
#define color_bar_2_jpg_len 511
|
#define color_bar_2_jpg_len 511
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
* - 1000 ms : device mounted
|
* - 1000 ms : device mounted
|
||||||
* - 2500 ms : device is suspended
|
* - 2500 ms : device is suspended
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
BLINK_NOT_MOUNTED = 250,
|
BLINK_NOT_MOUNTED = 250,
|
||||||
BLINK_MOUNTED = 1000,
|
BLINK_MOUNTED = 1000,
|
||||||
BLINK_SUSPENDED = 2500,
|
BLINK_SUSPENDED = 2500,
|
||||||
@ -52,8 +52,7 @@ void led_blinking_task(void);
|
|||||||
void video_task(void);
|
void video_task(void);
|
||||||
|
|
||||||
/*------------- MAIN -------------*/
|
/*------------- MAIN -------------*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
|
||||||
board_init();
|
board_init();
|
||||||
|
|
||||||
// init device stack on configured roothub port
|
// init device stack on configured roothub port
|
||||||
@ -63,8 +62,7 @@ int main(void)
|
|||||||
board_init_after_tusb();
|
board_init_after_tusb();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
tud_task(); // tinyusb device task
|
tud_task(); // tinyusb device task
|
||||||
led_blinking_task();
|
led_blinking_task();
|
||||||
|
|
||||||
@ -77,33 +75,28 @@ int main(void)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when device is mounted
|
// Invoked when device is mounted
|
||||||
void tud_mount_cb(void)
|
void tud_mount_cb(void) {
|
||||||
{
|
|
||||||
blink_interval_ms = BLINK_MOUNTED;
|
blink_interval_ms = BLINK_MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when device is unmounted
|
// Invoked when device is unmounted
|
||||||
void tud_umount_cb(void)
|
void tud_umount_cb(void) {
|
||||||
{
|
|
||||||
blink_interval_ms = BLINK_NOT_MOUNTED;
|
blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when usb bus is suspended
|
// Invoked when usb bus is suspended
|
||||||
// remote_wakeup_en : if host allow us to perform remote wakeup
|
// remote_wakeup_en : if host allow us to perform remote wakeup
|
||||||
// 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
|
||||||
void tud_suspend_cb(bool remote_wakeup_en)
|
void tud_suspend_cb(bool remote_wakeup_en) {
|
||||||
{
|
|
||||||
(void) remote_wakeup_en;
|
(void) remote_wakeup_en;
|
||||||
blink_interval_ms = BLINK_SUSPENDED;
|
blink_interval_ms = BLINK_SUSPENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when usb bus is resumed
|
// Invoked when usb bus is resumed
|
||||||
void tud_resume_cb(void)
|
void tud_resume_cb(void) {
|
||||||
{
|
|
||||||
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USB Video
|
// USB Video
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -111,11 +104,12 @@ static unsigned frame_num = 0;
|
|||||||
static unsigned tx_busy = 0;
|
static unsigned tx_busy = 0;
|
||||||
static unsigned interval_ms = 1000 / FRAME_RATE;
|
static unsigned interval_ms = 1000 / FRAME_RATE;
|
||||||
|
|
||||||
/* YUY2 frame buffer */
|
|
||||||
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
||||||
|
// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data.
|
||||||
|
// To further reduce the size, we use MJPEG format instead of YUY2.
|
||||||
#include "images.h"
|
#include "images.h"
|
||||||
|
|
||||||
# if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
static struct {
|
static struct {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t const *buffer;
|
uint8_t const *buffer;
|
||||||
@ -129,29 +123,30 @@ static struct {
|
|||||||
{color_bar_6_jpg_len, color_bar_6_jpg},
|
{color_bar_6_jpg_len, color_bar_6_jpg},
|
||||||
{color_bar_7_jpg_len, color_bar_7_jpg},
|
{color_bar_7_jpg_len, color_bar_7_jpg},
|
||||||
};
|
};
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// YUY2 frame buffer
|
||||||
static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8];
|
static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8];
|
||||||
static void fill_color_bar(uint8_t *buffer, unsigned start_position)
|
|
||||||
{
|
static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
|
||||||
/* EBU color bars
|
/* EBU color bars: https://stackoverflow.com/questions/6939422 */
|
||||||
* See also https://stackoverflow.com/questions/6939422 */
|
|
||||||
static uint8_t const bar_color[8][4] = {
|
static uint8_t const bar_color[8][4] = {
|
||||||
/* Y, U, Y, V */
|
/* Y, U, Y, V */
|
||||||
{ 235, 128, 235, 128}, /* 100% White */
|
{ 235, 128, 235, 128}, /* 100% White */
|
||||||
{ 219, 16, 219, 138}, /* Yellow */
|
{ 219, 16, 219, 138}, /* Yellow */
|
||||||
{ 188, 154, 188, 16}, /* Cyan */
|
{ 188, 154, 188, 16}, /* Cyan */
|
||||||
{ 173, 42, 173, 26}, /* Green */
|
{ 173, 42, 173, 26}, /* Green */
|
||||||
{ 78, 214, 78, 230}, /* Magenta */
|
{ 78, 214, 78, 230}, /* Magenta */
|
||||||
{ 63, 102, 63, 240}, /* Red */
|
{ 63, 102, 63, 240}, /* Red */
|
||||||
{ 32, 240, 32, 118}, /* Blue */
|
{ 32, 240, 32, 118}, /* Blue */
|
||||||
{ 16, 128, 16, 128}, /* Black */
|
{ 16, 128, 16, 128}, /* Black */
|
||||||
};
|
};
|
||||||
uint8_t *p;
|
uint8_t* p;
|
||||||
|
|
||||||
/* Generate the 1st line */
|
/* Generate the 1st line */
|
||||||
uint8_t *end = &buffer[FRAME_WIDTH * 2];
|
uint8_t* end = &buffer[FRAME_WIDTH * 2];
|
||||||
unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2));
|
unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2));
|
||||||
p = &buffer[idx * 4];
|
p = &buffer[idx * 4];
|
||||||
for (unsigned i = 0; i < 8; ++i) {
|
for (unsigned i = 0; i < 8; ++i) {
|
||||||
@ -163,6 +158,7 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the 1st line to the others */
|
/* Duplicate the 1st line to the others */
|
||||||
p = &buffer[FRAME_WIDTH * 2];
|
p = &buffer[FRAME_WIDTH * 2];
|
||||||
for (unsigned i = 1; i < FRAME_HEIGHT; ++i) {
|
for (unsigned i = 1; i < FRAME_HEIGHT; ++i) {
|
||||||
@ -170,16 +166,16 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position)
|
|||||||
p += FRAME_WIDTH * 2;
|
p += FRAME_WIDTH * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void video_task(void)
|
void video_task(void) {
|
||||||
{
|
|
||||||
static unsigned start_ms = 0;
|
static unsigned start_ms = 0;
|
||||||
static unsigned already_sent = 0;
|
static unsigned already_sent = 0;
|
||||||
|
|
||||||
if (!tud_video_n_streaming(0, 0)) {
|
if (!tud_video_n_streaming(0, 0)) {
|
||||||
already_sent = 0;
|
already_sent = 0;
|
||||||
frame_num = 0;
|
frame_num = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,15 +184,15 @@ void video_task(void)
|
|||||||
tx_busy = 1;
|
tx_busy = 1;
|
||||||
start_ms = board_millis();
|
start_ms = board_millis();
|
||||||
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
||||||
# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
|
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
|
||||||
FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
||||||
# else
|
#else
|
||||||
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size);
|
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size);
|
||||||
# endif
|
#endif
|
||||||
#else
|
#else
|
||||||
fill_color_bar(frame_buffer, frame_num);
|
fill_color_bar(frame_buffer, frame_num);
|
||||||
tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,30 +203,30 @@ void video_task(void)
|
|||||||
tx_busy = 1;
|
tx_busy = 1;
|
||||||
|
|
||||||
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
||||||
# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
|
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
|
||||||
FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
||||||
# else
|
#else
|
||||||
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size);
|
tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size);
|
||||||
# endif
|
#endif
|
||||||
#else
|
#else
|
||||||
fill_color_bar(frame_buffer, frame_num);
|
fill_color_bar(frame_buffer, frame_num);
|
||||||
tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx)
|
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
|
||||||
{
|
(void) ctl_idx;
|
||||||
(void)ctl_idx; (void)stm_idx;
|
(void) stm_idx;
|
||||||
tx_busy = 0;
|
tx_busy = 0;
|
||||||
/* flip buffer */
|
/* flip buffer */
|
||||||
++frame_num;
|
++frame_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
|
int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
|
||||||
video_probe_and_commit_control_t const *parameters)
|
video_probe_and_commit_control_t const* parameters) {
|
||||||
{
|
(void) ctl_idx;
|
||||||
(void)ctl_idx; (void)stm_idx;
|
(void) stm_idx;
|
||||||
/* convert unit to ms from 100 ns */
|
/* convert unit to ms from 100 ns */
|
||||||
interval_ms = parameters->dwFrameInterval / 10000;
|
interval_ms = parameters->dwFrameInterval / 10000;
|
||||||
return VIDEO_ERROR_NONE;
|
return VIDEO_ERROR_NONE;
|
||||||
@ -239,13 +235,12 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// BLINKING TASK
|
// BLINKING TASK
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void led_blinking_task(void)
|
void led_blinking_task(void) {
|
||||||
{
|
|
||||||
static uint32_t start_ms = 0;
|
static uint32_t start_ms = 0;
|
||||||
static bool led_state = false;
|
static bool led_state = false;
|
||||||
|
|
||||||
// Blink every interval ms
|
// Blink every interval ms
|
||||||
if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
|
if (board_millis() - start_ms < blink_interval_ms) return; // not enough time
|
||||||
start_ms += blink_interval_ms;
|
start_ms += blink_interval_ms;
|
||||||
|
|
||||||
board_led_write(led_state);
|
board_led_write(led_state);
|
||||||
|
@ -97,11 +97,11 @@
|
|||||||
// The number of video streaming interfaces
|
// The number of video streaming interfaces
|
||||||
#define CFG_TUD_VIDEO_STREAMING 1
|
#define CFG_TUD_VIDEO_STREAMING 1
|
||||||
|
|
||||||
// video streaming endpoint size
|
// video streaming endpoint buffer size
|
||||||
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256
|
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256
|
||||||
|
|
||||||
// use bulk endpoint for streaming interface
|
// use bulk endpoint for streaming interface
|
||||||
#define CFG_TUD_VIDEO_STREAMING_BULK 0
|
#define CFG_TUD_VIDEO_STREAMING_BULK 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,7 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Device Descriptors
|
// Device Descriptors
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
tusb_desc_device_t const desc_device =
|
tusb_desc_device_t const desc_device = {
|
||||||
{
|
|
||||||
.bLength = sizeof(tusb_desc_device_t),
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bcdUSB = USB_BCD,
|
.bcdUSB = USB_BCD,
|
||||||
@ -70,111 +69,70 @@ tusb_desc_device_t const desc_device =
|
|||||||
|
|
||||||
// Invoked when received GET DEVICE DESCRIPTOR
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
// 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) {
|
||||||
{
|
return (uint8_t const*) &desc_device;
|
||||||
return (uint8_t const *) &desc_device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Configuration Descriptor
|
// Configuration Descriptor
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
// Select appropriate endpoint number
|
||||||
# if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
|
||||||
# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN)
|
|
||||||
# else
|
|
||||||
# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN)
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
|
||||||
# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN)
|
|
||||||
# else
|
|
||||||
# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
|
#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
|
||||||
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||||
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
|
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
|
||||||
#if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
#define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x82 : 0x83)
|
||||||
#define EPNUM_VIDEO_IN 0x82
|
|
||||||
#else
|
|
||||||
#define EPNUM_VIDEO_IN 0x83
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
|
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
|
||||||
// nRF5x ISO can only be endpoint 8
|
// nRF5x ISO can only be endpoint 8
|
||||||
#define EPNUM_VIDEO_IN 0x88
|
#define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define EPNUM_VIDEO_IN 0x81
|
#define EPNUM_VIDEO_IN 0x81
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t const desc_fs_configuration[] =
|
// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data.
|
||||||
{
|
// To further reduce the size, we use MJPEG format instead of YUY2.
|
||||||
// Config number, interface count, string index, total length, attribute, power in mA
|
// Select interface descriptor and length accordingly.
|
||||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500),
|
|
||||||
|
|
||||||
// IAD for Video Control
|
|
||||||
#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
# if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
#if CFG_TUD_VIDEO_STREAMING_BULK
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN,
|
#define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize)
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
#define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN
|
||||||
64)
|
#else
|
||||||
# else
|
#define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize)
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN,
|
#define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
#endif
|
||||||
CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
|
|
||||||
# endif
|
|
||||||
#else
|
#else
|
||||||
# if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
#if CFG_TUD_VIDEO_STREAMING_BULK
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN,
|
#define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize)
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
#define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN
|
||||||
64)
|
#else
|
||||||
# else
|
#define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize)
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN,
|
#define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
#endif
|
||||||
CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + ITF_VIDEO_LEN)
|
||||||
|
|
||||||
|
// full speed descriptor
|
||||||
|
uint8_t const desc_fs_configuration[] = {
|
||||||
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500),
|
||||||
|
|
||||||
|
// IAD for Video Control
|
||||||
|
ITF_VIDEO_DESC(CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
|
||||||
};
|
};
|
||||||
|
|
||||||
#if TUD_OPT_HIGH_SPEED
|
#if TUD_OPT_HIGH_SPEED
|
||||||
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
|
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
|
||||||
|
uint8_t const desc_hs_configuration[] = {
|
||||||
uint8_t const desc_hs_configuration[] =
|
|
||||||
{
|
|
||||||
// Config number, interface count, string index, total length, attribute, power in mA
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500),
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500),
|
||||||
|
|
||||||
// IAD for Video Control
|
// IAD for Video Control
|
||||||
#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
ITF_VIDEO_DESC(CFG_TUD_VIDEO_STREAMING_BULK ? 512 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
|
||||||
# if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN,
|
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
|
||||||
512)
|
|
||||||
# else
|
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN,
|
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
|
||||||
CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# if 1 == CFG_TUD_VIDEO_STREAMING_BULK
|
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN,
|
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
|
||||||
512)
|
|
||||||
# else
|
|
||||||
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN,
|
|
||||||
FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
|
|
||||||
CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
|
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
|
||||||
tusb_desc_device_qualifier_t const desc_device_qualifier =
|
tusb_desc_device_qualifier_t const desc_device_qualifier = {
|
||||||
{
|
|
||||||
.bLength = sizeof(tusb_desc_device_t),
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bcdUSB = USB_BCD,
|
.bcdUSB = USB_BCD,
|
||||||
@ -192,29 +150,24 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
|
|||||||
// 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.
|
||||||
// device_qualifier descriptor describes information about a high-speed capable device that would
|
// device_qualifier descriptor describes information about a high-speed capable device that would
|
||||||
// change if the device were operating at the other speed. If not highspeed capable stall this request.
|
// change if the device were operating at the other speed. If not highspeed capable stall this request.
|
||||||
uint8_t const* tud_descriptor_device_qualifier_cb(void)
|
uint8_t const* tud_descriptor_device_qualifier_cb(void) {
|
||||||
{
|
|
||||||
return (uint8_t const*) &desc_device_qualifier;
|
return (uint8_t const*) &desc_device_qualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
|
// Invoked when received GET OTHER SEED 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
|
||||||
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
|
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
|
||||||
uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
|
uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) {
|
||||||
{
|
|
||||||
(void) index; // for multiple configurations
|
(void) index; // for multiple configurations
|
||||||
|
|
||||||
// if link speed is high return fullspeed config, and vice versa
|
// if link speed is high return fullspeed config, and vice versa
|
||||||
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration;
|
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // highspeed
|
#endif // highspeed
|
||||||
|
|
||||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
// Application return pointer to descriptor
|
// Application return pointer to descriptor
|
||||||
// Descriptor contents must exist long enough for transfer to complete
|
// Descriptor 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) {
|
||||||
{
|
|
||||||
(void) index; // for multiple configurations
|
(void) index; // for multiple configurations
|
||||||
|
|
||||||
#if TUD_OPT_HIGH_SPEED
|
#if TUD_OPT_HIGH_SPEED
|
||||||
@ -238,24 +191,23 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// array of pointer to string descriptors
|
// array of pointer to string descriptors
|
||||||
char const *string_desc_arr[] =
|
char const* string_desc_arr[] = {
|
||||||
{
|
(const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409)
|
||||||
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
"TinyUSB", // 1: Manufacturer
|
||||||
"TinyUSB", // 1: Manufacturer
|
"TinyUSB Device", // 2: Product
|
||||||
"TinyUSB Device", // 2: Product
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
NULL, // 3: Serials will use unique ID if possible
|
"TinyUSB UVC", // 4: UVC Interface
|
||||||
"TinyUSB UVC", // 4: UVC Interface
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint16_t _desc_str[32 + 1];
|
static uint16_t _desc_str[32 + 1];
|
||||||
|
|
||||||
// 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 langid) {
|
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||||
(void) langid;
|
(void) langid;
|
||||||
size_t chr_count;
|
size_t chr_count;
|
||||||
|
|
||||||
switch ( index ) {
|
switch (index) {
|
||||||
case STRID_LANGID:
|
case STRID_LANGID:
|
||||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
chr_count = 1;
|
chr_count = 1;
|
||||||
@ -269,17 +221,17 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
|||||||
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||||
|
|
||||||
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
|
if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) return NULL;
|
||||||
|
|
||||||
const char *str = string_desc_arr[index];
|
const char* str = string_desc_arr[index];
|
||||||
|
|
||||||
// Cap at max char
|
// Cap at max char
|
||||||
chr_count = strlen(str);
|
chr_count = strlen(str);
|
||||||
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
|
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
|
||||||
if ( chr_count > max_count ) chr_count = max_count;
|
if (chr_count > max_count) chr_count = max_count;
|
||||||
|
|
||||||
// Convert ASCII string into UTF-16
|
// Convert ASCII string into UTF-16
|
||||||
for ( size_t i = 0; i < chr_count; i++ ) {
|
for (size_t i = 0; i < chr_count; i++) {
|
||||||
_desc_str[1 + i] = str[i];
|
_desc_str[1 + i] = str[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -126,23 +126,17 @@ enum {
|
|||||||
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \
|
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \
|
||||||
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
||||||
/* Video control 0 */ \
|
/* Video control 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
||||||
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
|
/* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \
|
||||||
/* wTotalLength - bLength */ \
|
TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
|
/* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \
|
||||||
UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
|
|
||||||
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
|
|
||||||
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
|
|
||||||
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
||||||
/* Video stream alt. 0 */ \
|
/* Video stream alt. 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \
|
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \
|
||||||
/* Video stream header for without still image capture */ \
|
/* Video stream header for without still image capture */ \
|
||||||
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
||||||
/*wTotalLength - bLength */\
|
/*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
||||||
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
|
||||||
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
||||||
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
||||||
/*bmaControls(1)*/0), \
|
/*bmaControls(1)*/0), \
|
||||||
@ -163,23 +157,17 @@ enum {
|
|||||||
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \
|
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \
|
||||||
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
||||||
/* Video control 0 */ \
|
/* Video control 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
||||||
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
|
/* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \
|
||||||
/* wTotalLength - bLength */ \
|
TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
|
/* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \
|
||||||
UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
|
|
||||||
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
|
|
||||||
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
|
|
||||||
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
||||||
/* Video stream alt. 0 */ \
|
/* Video stream alt. 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \
|
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \
|
||||||
/* Video stream header for without still image capture */ \
|
/* Video stream header for without still image capture */ \
|
||||||
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
||||||
/*wTotalLength - bLength */\
|
/*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
||||||
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
|
||||||
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
||||||
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
||||||
/*bmaControls(1)*/0), \
|
/*bmaControls(1)*/0), \
|
||||||
@ -202,22 +190,17 @@ enum {
|
|||||||
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
||||||
/* Video control 0 */ \
|
/* Video control 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
||||||
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
|
/* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \
|
||||||
/* wTotalLength - bLength */ \
|
TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
|
/* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \
|
||||||
UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
|
|
||||||
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
|
|
||||||
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
|
|
||||||
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
||||||
/* Video stream alt. 0 */ \
|
/* Video stream alt. 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \
|
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \
|
||||||
/* Video stream header for without still image capture */ \
|
/* Video stream header for without still image capture */ \
|
||||||
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
||||||
/*wTotalLength - bLength */\
|
/*wTotalLength - bLength */\
|
||||||
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\
|
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
||||||
+ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
|
||||||
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
||||||
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
||||||
/*bmaControls(1)*/0), \
|
/*bmaControls(1)*/0), \
|
||||||
@ -235,23 +218,17 @@ enum {
|
|||||||
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \
|
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \
|
||||||
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
|
||||||
/* Video control 0 */ \
|
/* Video control 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
|
||||||
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
|
/* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \
|
||||||
/* wTotalLength - bLength */ \
|
TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
|
/* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \
|
||||||
UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
|
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \
|
||||||
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
|
|
||||||
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
|
|
||||||
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
|
|
||||||
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
|
||||||
/* Video stream alt. 0 */ \
|
/* Video stream alt. 0 */ \
|
||||||
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \
|
TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \
|
||||||
/* Video stream header for without still image capture */ \
|
/* Video stream header for without still image capture */ \
|
||||||
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
|
||||||
/*wTotalLength - bLength */\
|
/*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
||||||
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
|
|
||||||
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
|
|
||||||
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
|
||||||
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
|
||||||
/*bmaControls(1)*/0), \
|
/*bmaControls(1)*/0), \
|
||||||
|
@ -27,20 +27,11 @@
|
|||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
|
||||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
|
|
||||||
//------------- IMPLEMENTATION -------------//
|
|
||||||
|
|
||||||
size_t get_console_inputs(uint8_t* buf, size_t bufsize)
|
|
||||||
{
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
while (count < bufsize)
|
while (count < bufsize) {
|
||||||
{
|
|
||||||
int ch = board_getchar();
|
int ch = board_getchar();
|
||||||
if ( ch <= 0 ) break;
|
if (ch <= 0) break;
|
||||||
|
|
||||||
buf[count] = (uint8_t) ch;
|
buf[count] = (uint8_t) ch;
|
||||||
count++;
|
count++;
|
||||||
@ -49,22 +40,18 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdc_app_task(void)
|
void cdc_app_task(void) {
|
||||||
{
|
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||||
uint8_t buf[64+1]; // +1 for extra null character
|
uint32_t const bufsize = sizeof(buf) - 1;
|
||||||
uint32_t const bufsize = sizeof(buf)-1;
|
|
||||||
|
|
||||||
uint32_t count = get_console_inputs(buf, bufsize);
|
uint32_t count = get_console_inputs(buf, bufsize);
|
||||||
buf[count] = 0;
|
buf[count] = 0;
|
||||||
|
|
||||||
// loop over all mounted interfaces
|
// loop over all mounted interfaces
|
||||||
for(uint8_t idx=0; idx<CFG_TUH_CDC; idx++)
|
for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) {
|
||||||
{
|
if (tuh_cdc_mounted(idx)) {
|
||||||
if ( tuh_cdc_mounted(idx) )
|
|
||||||
{
|
|
||||||
// console --> cdc interfaces
|
// console --> cdc interfaces
|
||||||
if (count)
|
if (count) {
|
||||||
{
|
|
||||||
tuh_cdc_write(idx, buf, count);
|
tuh_cdc_write(idx, buf, count);
|
||||||
tuh_cdc_write_flush(idx);
|
tuh_cdc_write_flush(idx);
|
||||||
}
|
}
|
||||||
@ -72,11 +59,14 @@ void cdc_app_task(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB callbacks
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when received new data
|
// Invoked when received new data
|
||||||
void tuh_cdc_rx_cb(uint8_t idx)
|
void tuh_cdc_rx_cb(uint8_t idx) {
|
||||||
{
|
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||||
uint8_t buf[64+1]; // +1 for extra null character
|
uint32_t const bufsize = sizeof(buf) - 1;
|
||||||
uint32_t const bufsize = sizeof(buf)-1;
|
|
||||||
|
|
||||||
// forward cdc interfaces -> console
|
// forward cdc interfaces -> console
|
||||||
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
|
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
|
||||||
@ -85,29 +75,35 @@ void tuh_cdc_rx_cb(uint8_t idx)
|
|||||||
printf((char*) buf);
|
printf((char*) buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tuh_cdc_mount_cb(uint8_t idx)
|
// Invoked when a device with CDC interface is mounted
|
||||||
{
|
// idx is index of cdc interface in the internal pool.
|
||||||
tuh_itf_info_t itf_info = { 0 };
|
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||||
|
tuh_itf_info_t itf_info = {0};
|
||||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
tuh_cdc_itf_get_info(idx, &itf_info);
|
||||||
|
|
||||||
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
|
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr,
|
||||||
|
itf_info.desc.bInterfaceNumber);
|
||||||
|
|
||||||
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
||||||
// CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration
|
// If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack
|
||||||
// otherwise you need to call tuh_cdc_set_line_coding() first
|
// while eneumerating new cdc device
|
||||||
cdc_line_coding_t line_coding = { 0 };
|
cdc_line_coding_t line_coding = {0};
|
||||||
if ( tuh_cdc_get_local_line_coding(idx, &line_coding) )
|
if (tuh_cdc_get_local_line_coding(idx, &line_coding)) {
|
||||||
{
|
|
||||||
printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
|
printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
|
||||||
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits);
|
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Set Line Coding upon mounted
|
||||||
|
cdc_line_coding_t new_line_coding = { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 };
|
||||||
|
tuh_cdc_set_line_coding(idx, &new_line_coding, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tuh_cdc_umount_cb(uint8_t idx)
|
// Invoked when a device with CDC interface is unmounted
|
||||||
{
|
void tuh_cdc_umount_cb(uint8_t idx) {
|
||||||
tuh_itf_info_t itf_info = { 0 };
|
tuh_itf_info_t itf_info = {0};
|
||||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
tuh_cdc_itf_get_info(idx, &itf_info);
|
||||||
|
|
||||||
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
|
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr,
|
||||||
|
itf_info.desc.bInterfaceNumber);
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@
|
|||||||
#define CFG_TUH_CDC 1 // CDC ACM
|
#define CFG_TUH_CDC 1 // CDC ACM
|
||||||
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
|
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
|
||||||
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
|
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
|
||||||
|
#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API
|
||||||
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
|
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
|
||||||
#define CFG_TUH_MSC 1
|
#define CFG_TUH_MSC 1
|
||||||
#define CFG_TUH_VENDOR 0
|
#define CFG_TUH_VENDOR 0
|
||||||
|
@ -110,6 +110,7 @@
|
|||||||
#define CFG_TUH_CDC 1 // CDC ACM
|
#define CFG_TUH_CDC 1 // CDC ACM
|
||||||
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
|
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
|
||||||
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
|
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
|
||||||
|
#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API
|
||||||
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
|
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
|
||||||
#define CFG_TUH_MSC 1
|
#define CFG_TUH_MSC 1
|
||||||
#define CFG_TUH_VENDOR 0
|
#define CFG_TUH_VENDOR 0
|
||||||
|
@ -211,7 +211,6 @@ function(family_configure_common TARGET RTOS)
|
|||||||
target_link_options(${TARGET} PUBLIC "LINKER:--map=$<TARGET_FILE:${TARGET}>.map")
|
target_link_options(${TARGET} PUBLIC "LINKER:--map=$<TARGET_FILE:${TARGET}>.map")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# ETM Trace option
|
# ETM Trace option
|
||||||
if (TRACE_ETM STREQUAL "1")
|
if (TRACE_ETM STREQUAL "1")
|
||||||
target_compile_definitions(${TARGET} PUBLIC TRACE_ETM)
|
target_compile_definitions(${TARGET} PUBLIC TRACE_ETM)
|
||||||
|
149
hw/bsp/lpc17/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
149
hw/bsp/lpc17/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// skip if included from IAR assembler
|
||||||
|
#ifndef __IASMARM__
|
||||||
|
#include "chip.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cortex M23/M33 port configuration. */
|
||||||
|
#define configENABLE_MPU 0
|
||||||
|
#define configENABLE_FPU 0
|
||||||
|
#define configENABLE_TRUSTZONE 0
|
||||||
|
#define configMINIMAL_SECURE_STACK_SIZE (1024)
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||||
|
#define configTICK_RATE_HZ ( 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 4
|
||||||
|
#define configUSE_QUEUE_SETS 0
|
||||||
|
#define configUSE_TIME_SLICING 0
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||||
|
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||||
|
|
||||||
|
/* Hook function related definitions. */
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
#define configCHECK_HANDLER_INSTALLATION 0
|
||||||
|
|
||||||
|
/* Run time and task stats gathering related definitions. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||||
|
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 32
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 0
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 0
|
||||||
|
#define INCLUDE_vTaskDelete 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||||
|
#define INCLUDE_xResumeFromISR 0
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#define INCLUDE_eTaskGetState 0
|
||||||
|
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
|
||||||
|
/* FreeRTOS hooks to NVIC vectors */
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Interrupt nesting behavior configuration.
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
|
||||||
|
#define configPRIO_BITS 3
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
|
||||||
|
|
||||||
|
/* The highest interrupt priority that can be used by any interrupt service
|
||||||
|
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||||
|
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||||
|
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||||
|
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
|
||||||
|
|
||||||
|
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||||
|
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
|
||||||
|
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||||
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
|
||||||
|
#endif
|
11
hw/bsp/lpc17/boards/lpcxpresso1769/board.cmake
Normal file
11
hw/bsp/lpc17/boards/lpcxpresso1769/board.cmake
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
set(MCU_VARIANT LPC1769)
|
||||||
|
|
||||||
|
set(JLINK_DEVICE LPC1769)
|
||||||
|
set(PYOCD_TARGET LPC1769)
|
||||||
|
set(NXPLINK_DEVICE LPC1769:LPC1769)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc1769.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
# nothing to do
|
||||||
|
endfunction()
|
78
hw/bsp/lpc17/boards/lpcxpresso1769/board.h
Normal file
78
hw/bsp/lpc17/boards/lpcxpresso1769/board.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, 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_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LED_PORT 0
|
||||||
|
#define LED_PIN 22
|
||||||
|
#define LED_STATE_ON 1
|
||||||
|
|
||||||
|
// JOYSTICK_DOWN if using LPCXpresso Base Board
|
||||||
|
#define BUTTON_PORT 0
|
||||||
|
#define BUTTON_PIN 15
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
#define BOARD_UART_PORT LPC_UART3
|
||||||
|
|
||||||
|
/* System oscillator rate and RTC oscillator rate */
|
||||||
|
const uint32_t OscRateIn = 12000000;
|
||||||
|
const uint32_t RTCOscRateIn = 32768;
|
||||||
|
|
||||||
|
// Pin muxing configuration
|
||||||
|
static const PINMUX_GRP_T pinmuxing[] = {
|
||||||
|
{0, 0, IOCON_MODE_INACT | IOCON_FUNC2}, /* TXD3 */
|
||||||
|
{0, 1, IOCON_MODE_INACT | IOCON_FUNC2}, /* RXD3 */
|
||||||
|
{LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0}, /* Led 0 */
|
||||||
|
|
||||||
|
/* Joystick buttons. */
|
||||||
|
// {2, 3, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_UP */
|
||||||
|
{BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP}, /* JOYSTICK_DOWN */
|
||||||
|
// {2, 4, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_LEFT */
|
||||||
|
// {0, 16, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_RIGHT */
|
||||||
|
// {0, 17, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_PRESS */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PINMUX_GRP_T pin_usb_mux[] = {
|
||||||
|
{0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+
|
||||||
|
{0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D-
|
||||||
|
{2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Soft Connect
|
||||||
|
|
||||||
|
{1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR (Host mode)
|
||||||
|
|
||||||
|
// VBUS is not connected on this board, so leave the pin at default setting.
|
||||||
|
/// Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2); // USB VBUS
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,209 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "chip.h"
|
|
||||||
#include "bsp/board_api.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// USB Interrupt Handler
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void USB_IRQHandler(void)
|
|
||||||
{
|
|
||||||
#if CFG_TUD_ENABLED
|
|
||||||
tud_int_handler(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED
|
|
||||||
tuh_int_handler(0, true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// MACRO TYPEDEF CONSTANT ENUM
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
#define LED_PORT 0
|
|
||||||
#define LED_PIN 22
|
|
||||||
#define LED_STATE_ON 1
|
|
||||||
|
|
||||||
// JOYSTICK_DOWN if using LPCXpresso Base Board
|
|
||||||
#define BUTTON_PORT 0
|
|
||||||
#define BUTTON_PIN 15
|
|
||||||
#define BUTTON_STATE_ACTIVE 0
|
|
||||||
|
|
||||||
#define BOARD_UART_PORT LPC_UART3
|
|
||||||
|
|
||||||
/* System oscillator rate and RTC oscillator rate */
|
|
||||||
const uint32_t OscRateIn = 12000000;
|
|
||||||
const uint32_t RTCOscRateIn = 32768;
|
|
||||||
|
|
||||||
/* Pin muxing configuration */
|
|
||||||
static const PINMUX_GRP_T pinmuxing[] =
|
|
||||||
{
|
|
||||||
{0, 0, IOCON_MODE_INACT | IOCON_FUNC2}, /* TXD3 */
|
|
||||||
{0, 1, IOCON_MODE_INACT | IOCON_FUNC2}, /* RXD3 */
|
|
||||||
{LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0}, /* Led 0 */
|
|
||||||
|
|
||||||
/* Joystick buttons. */
|
|
||||||
// {2, 3, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_UP */
|
|
||||||
{BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP}, /* JOYSTICK_DOWN */
|
|
||||||
// {2, 4, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_LEFT */
|
|
||||||
// {0, 16, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_RIGHT */
|
|
||||||
// {0, 17, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_PRESS */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const PINMUX_GRP_T pin_usb_mux[] =
|
|
||||||
{
|
|
||||||
{0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+
|
|
||||||
{0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D-
|
|
||||||
{2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Soft Connect
|
|
||||||
|
|
||||||
{1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR (Host mode)
|
|
||||||
|
|
||||||
// VBUS is not connected on this board, so leave the pin at default setting.
|
|
||||||
/// Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2); // USB VBUS
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invoked by startup code
|
|
||||||
void SystemInit(void)
|
|
||||||
{
|
|
||||||
#ifdef __USE_LPCOPEN
|
|
||||||
extern void (* const g_pfnVectors[])(void);
|
|
||||||
unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08;
|
|
||||||
*pSCB_VTOR = (unsigned int) g_pfnVectors;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Chip_IOCON_Init(LPC_IOCON);
|
|
||||||
Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
|
|
||||||
Chip_SetupXtalClocking();
|
|
||||||
|
|
||||||
Chip_SYSCTL_SetFLASHAccess(FLASHTIM_100MHZ_CPU);
|
|
||||||
}
|
|
||||||
|
|
||||||
void board_init(void)
|
|
||||||
{
|
|
||||||
SystemCoreClockUpdate();
|
|
||||||
|
|
||||||
#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(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Chip_GPIO_Init(LPC_GPIO);
|
|
||||||
|
|
||||||
// LED
|
|
||||||
Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN);
|
|
||||||
|
|
||||||
// Button
|
|
||||||
Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//------------- UART -------------//
|
|
||||||
PINSEL_CFG_Type PinCfg =
|
|
||||||
{
|
|
||||||
.Portnum = 0,
|
|
||||||
.Pinnum = 0, // TXD is P0.0
|
|
||||||
.Funcnum = 2,
|
|
||||||
.OpenDrain = 0,
|
|
||||||
.Pinmode = 0
|
|
||||||
};
|
|
||||||
PINSEL_ConfigPin(&PinCfg);
|
|
||||||
|
|
||||||
PinCfg.Portnum = 0;
|
|
||||||
PinCfg.Pinnum = 1; // RXD is P0.1
|
|
||||||
PINSEL_ConfigPin(&PinCfg);
|
|
||||||
|
|
||||||
UART_CFG_Type UARTConfigStruct;
|
|
||||||
UART_ConfigStructInit(&UARTConfigStruct);
|
|
||||||
UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE;
|
|
||||||
|
|
||||||
UART_Init(BOARD_UART_PORT, &UARTConfigStruct);
|
|
||||||
UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------- USB -------------//
|
|
||||||
Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T));
|
|
||||||
Chip_USB_Init();
|
|
||||||
|
|
||||||
enum {
|
|
||||||
USBCLK_DEVCIE = 0x12, // AHB + Device
|
|
||||||
USBCLK_HOST = 0x19, // AHB + Host + OTG
|
|
||||||
// 0x1B // Host + Device + OTG + AHB
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST;
|
|
||||||
|
|
||||||
LPC_USB->OTGClkCtrl = clk_en;
|
|
||||||
while ( (LPC_USB->OTGClkSt & clk_en) != clk_en );
|
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED
|
|
||||||
// set portfunc to host !!!
|
|
||||||
LPC_USB->StCtrl = 0x3; // should be 1
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Board porting API
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void board_led_write(bool state)
|
|
||||||
{
|
|
||||||
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
|
||||||
{
|
|
||||||
return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
|
||||||
{
|
|
||||||
// return UART_ReceiveByte(BOARD_UART_PORT);
|
|
||||||
(void) buf; (void) len;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
|
||||||
{
|
|
||||||
// UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING);
|
|
||||||
(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
|
|
11
hw/bsp/lpc17/boards/mbed1768/board.cmake
Normal file
11
hw/bsp/lpc17/boards/mbed1768/board.cmake
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
set(MCU_VARIANT LPC1768)
|
||||||
|
|
||||||
|
set(JLINK_DEVICE LPC1768)
|
||||||
|
set(PYOCD_TARGET LPC1768)
|
||||||
|
set(NXPLINK_DEVICE LPC1768:LPC1768)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc1768.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
# nothing to do
|
||||||
|
endfunction()
|
71
hw/bsp/lpc17/boards/mbed1768/board.h
Normal file
71
hw/bsp/lpc17/boards/mbed1768/board.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, 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_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LED_PORT 1
|
||||||
|
#define LED_PIN 18
|
||||||
|
#define LED_STATE_ON 1
|
||||||
|
|
||||||
|
// JOYSTICK_DOWN if using LPCXpresso Base Board
|
||||||
|
#define BUTTON_PORT 0
|
||||||
|
#define BUTTON_PIN 15
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
#define BOARD_UART_PORT LPC_UART3
|
||||||
|
|
||||||
|
/* System oscillator rate and RTC oscillator rate */
|
||||||
|
const uint32_t OscRateIn = 10000000;
|
||||||
|
const uint32_t RTCOscRateIn = 32768;
|
||||||
|
|
||||||
|
// Pin muxing configuration
|
||||||
|
static const PINMUX_GRP_T pinmuxing[] = {
|
||||||
|
{LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0},
|
||||||
|
{BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PINMUX_GRP_T pin_usb_mux[] = {
|
||||||
|
{0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+
|
||||||
|
{0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D-
|
||||||
|
{2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Soft Connect
|
||||||
|
|
||||||
|
{1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR (Host mode)
|
||||||
|
{1, 22, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PWRD
|
||||||
|
|
||||||
|
// VBUS is not connected on this board, so leave the pin at default setting.
|
||||||
|
// Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2); // USB VBUS
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -26,58 +26,24 @@
|
|||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
|
#include "board.h"
|
||||||
#define LED_PORT 1
|
|
||||||
#define LED_PIN 18
|
|
||||||
#define LED_STATE_ON 1
|
|
||||||
|
|
||||||
// JOYSTICK_DOWN if using LPCXpresso Base Board
|
|
||||||
#define BUTTON_PORT 0
|
|
||||||
#define BUTTON_PIN 15
|
|
||||||
#define BUTTON_STATE_ACTIVE 0
|
|
||||||
|
|
||||||
#define BOARD_UART_PORT LPC_UART3
|
|
||||||
|
|
||||||
/* System oscillator rate and RTC oscillator rate */
|
|
||||||
const uint32_t OscRateIn = 10000000;
|
|
||||||
const uint32_t RTCOscRateIn = 32768;
|
|
||||||
|
|
||||||
/* Pin muxing configuration */
|
|
||||||
static const PINMUX_GRP_T pinmuxing[] =
|
|
||||||
{
|
|
||||||
{LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0},
|
|
||||||
{BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const PINMUX_GRP_T pin_usb_mux[] =
|
|
||||||
{
|
|
||||||
{0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+
|
|
||||||
{0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D-
|
|
||||||
{2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Connect
|
|
||||||
|
|
||||||
{1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR
|
|
||||||
{1, 22, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PWRD
|
|
||||||
|
|
||||||
/* VBUS is not connected on this board, so leave the pin at default setting. */
|
|
||||||
/*Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2);*/ /* USB VBUS */
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invoked by startup code
|
// Invoked by startup code
|
||||||
void SystemInit(void)
|
void SystemInit(void) {
|
||||||
{
|
|
||||||
#ifdef __USE_LPCOPEN
|
#ifdef __USE_LPCOPEN
|
||||||
extern void (* const g_pfnVectors[])(void);
|
extern void (* const g_pfnVectors[])(void);
|
||||||
unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08;
|
unsigned int* pSCB_VTOR = (unsigned int*) 0xE000ED08;
|
||||||
*pSCB_VTOR = (unsigned int) g_pfnVectors;
|
*pSCB_VTOR = (unsigned int) g_pfnVectors;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Chip_IOCON_Init(LPC_IOCON);
|
Chip_IOCON_Init(LPC_IOCON);
|
||||||
Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
|
Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
|
||||||
Chip_SetupXtalClocking();
|
Chip_SetupXtalClocking();
|
||||||
|
|
||||||
|
Chip_SYSCTL_SetFLASHAccess(FLASHTIM_100MHZ_CPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
|
||||||
SystemCoreClockUpdate();
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
@ -89,11 +55,7 @@ void board_init(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Chip_GPIO_Init(LPC_GPIO);
|
Chip_GPIO_Init(LPC_GPIO);
|
||||||
|
|
||||||
// LED
|
|
||||||
Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN);
|
Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN);
|
||||||
|
|
||||||
// Button
|
|
||||||
Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -106,34 +68,34 @@ void board_init(void)
|
|||||||
.OpenDrain = 0,
|
.OpenDrain = 0,
|
||||||
.Pinmode = 0
|
.Pinmode = 0
|
||||||
};
|
};
|
||||||
PINSEL_ConfigPin(&PinCfg);
|
PINSEL_ConfigPin(&PinCfg);
|
||||||
|
|
||||||
PinCfg.Portnum = 0;
|
PinCfg.Portnum = 0;
|
||||||
PinCfg.Pinnum = 1; // RXD is P0.1
|
PinCfg.Pinnum = 1; // RXD is P0.1
|
||||||
PINSEL_ConfigPin(&PinCfg);
|
PINSEL_ConfigPin(&PinCfg);
|
||||||
|
|
||||||
UART_CFG_Type UARTConfigStruct;
|
UART_CFG_Type UARTConfigStruct;
|
||||||
UART_ConfigStructInit(&UARTConfigStruct);
|
UART_ConfigStructInit(&UARTConfigStruct);
|
||||||
UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE;
|
UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE;
|
||||||
|
|
||||||
UART_Init(BOARD_UART_PORT, &UARTConfigStruct);
|
UART_Init(BOARD_UART_PORT, &UARTConfigStruct);
|
||||||
UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit
|
UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------- USB -------------//
|
//------------- USB -------------//
|
||||||
Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T));
|
Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T));
|
||||||
Chip_USB_Init();
|
Chip_USB_Init();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
USBCLK_DEVCIE = 0x12, // AHB + Device
|
USBCLK_DEVCIE = 0x12, // AHB + Device
|
||||||
USBCLK_HOST = 0x19, // AHB + Host + OTG
|
USBCLK_HOST = 0x19, // AHB + Host + OTG
|
||||||
// 0x1B // Host + Device + OTG + AHB
|
// 0x1B // Host + Device + OTG + AHB
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST;
|
uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST;
|
||||||
|
|
||||||
LPC_USB->OTGClkCtrl = clk_en;
|
LPC_USB->OTGClkCtrl = clk_en;
|
||||||
while ( (LPC_USB->OTGClkSt & clk_en) != clk_en );
|
while ((LPC_USB->OTGClkSt & clk_en) != clk_en) {}
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED
|
#if CFG_TUH_ENABLED
|
||||||
// set portfunc to host !!!
|
// set portfunc to host !!!
|
||||||
@ -141,57 +103,53 @@ void board_init(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// USB Interrupt Handler
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void USB_IRQHandler(void)
|
|
||||||
{
|
|
||||||
#if CFG_TUD_ENABLED
|
|
||||||
tud_int_handler(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED
|
|
||||||
tuh_int_handler(0, true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
void board_led_write(bool state) {
|
||||||
void board_led_write(bool state)
|
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||||
{
|
|
||||||
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
|
||||||
return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
int board_uart_read(uint8_t* buf, int len) {
|
||||||
{
|
|
||||||
// return UART_ReceiveByte(BOARD_UART_PORT);
|
// return UART_ReceiveByte(BOARD_UART_PORT);
|
||||||
(void) buf; (void) len;
|
(void) buf;
|
||||||
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const* buf, int len) {
|
||||||
{
|
|
||||||
// UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING);
|
// UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING);
|
||||||
(void) buf; (void) len;
|
(void) buf;
|
||||||
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
void SysTick_Handler (void)
|
|
||||||
{
|
void SysTick_Handler(void) {
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// USB Interrupt Handler
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void USB_IRQHandler(void) {
|
||||||
|
#if CFG_TUD_ENABLED
|
||||||
|
tud_int_handler(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CFG_TUH_ENABLED
|
||||||
|
tuh_int_handler(0, true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
102
hw/bsp/lpc17/family.cmake
Normal file
102
hw/bsp/lpc17/family.cmake
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
if (NOT BOARD)
|
||||||
|
message(FATAL_ERROR "BOARD not specified")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x)
|
||||||
|
|
||||||
|
# include board specific
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||||
|
|
||||||
|
# toolchain set up
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR cortex-m3 CACHE INTERNAL "System Processor")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||||
|
|
||||||
|
set(FAMILY_MCUS LPC175X_6X CACHE INTERNAL "")
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# BOARD_TARGET
|
||||||
|
#------------------------------------
|
||||||
|
# only need to be built ONCE for all examples
|
||||||
|
function(add_board_target BOARD_TARGET)
|
||||||
|
if (NOT TARGET ${BOARD_TARGET})
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${SDK_DIR}/../gcc/cr_startup_lpc175x_6x.c
|
||||||
|
${SDK_DIR}/src/chip_17xx_40xx.c
|
||||||
|
${SDK_DIR}/src/clock_17xx_40xx.c
|
||||||
|
${SDK_DIR}/src/gpio_17xx_40xx.c
|
||||||
|
${SDK_DIR}/src/iocon_17xx_40xx.c
|
||||||
|
${SDK_DIR}/src/sysctl_17xx_40xx.c
|
||||||
|
${SDK_DIR}/src/sysinit_17xx_40xx.c
|
||||||
|
${SDK_DIR}/src/uart_17xx_40xx.c
|
||||||
|
)
|
||||||
|
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||||
|
-nostdlib
|
||||||
|
)
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
__USE_LPCOPEN
|
||||||
|
CORE_M3
|
||||||
|
RTC_EV_SUPPORT=0
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_DIR}/inc
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
# nanolib
|
||||||
|
--specs=nosys.specs --specs=nano.specs
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# Functions
|
||||||
|
#------------------------------------
|
||||||
|
function(family_configure_example TARGET RTOS)
|
||||||
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
|
# Board target
|
||||||
|
add_board_target(board_${BOARD})
|
||||||
|
|
||||||
|
#---------- Port Specific ----------
|
||||||
|
# These files are built for each example since it depends on example's tusb_config.h
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
# BSP
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
|
)
|
||||||
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
# family, hw, board
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add TinyUSB target and port source
|
||||||
|
family_add_tinyusb(${TARGET} OPT_MCU_LPC175X_6X ${RTOS})
|
||||||
|
target_sources(${TARGET}-tinyusb PUBLIC
|
||||||
|
${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
|
||||||
|
${TOP}/src/portable/nxp/lpc17_40/hcd_lpc17_40.c
|
||||||
|
${TOP}/src/portable/ohci/ohci.c
|
||||||
|
)
|
||||||
|
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
# Link dependencies
|
||||||
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||||
|
|
||||||
|
# Flashing
|
||||||
|
family_flash_jlink(${TARGET})
|
||||||
|
#family_flash_nxplink(${TARGET})
|
||||||
|
endfunction()
|
@ -34,4 +34,5 @@ SRC_C += \
|
|||||||
$(MCU_DIR)/src/uart_17xx_40xx.c \
|
$(MCU_DIR)/src/uart_17xx_40xx.c \
|
||||||
|
|
||||||
INC += \
|
INC += \
|
||||||
$(TOP)/$(MCU_DIR)/inc
|
$(TOP)/$(BOARD_PATH) \
|
||||||
|
$(TOP)/$(MCU_DIR)/inc \
|
||||||
|
@ -1729,7 +1729,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
|
|||||||
// Find correct interface
|
// Find correct interface
|
||||||
if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt)
|
if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt)
|
||||||
{
|
{
|
||||||
#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
|
#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING)
|
||||||
uint8_t const * p_desc_parse_for_params = p_desc;
|
uint8_t const * p_desc_parse_for_params = p_desc;
|
||||||
#endif
|
#endif
|
||||||
// From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary
|
// From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary
|
||||||
|
@ -136,8 +136,7 @@ typedef enum{
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// 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,
|
||||||
@ -180,39 +179,38 @@ typedef enum
|
|||||||
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;
|
||||||
|
|
||||||
enum {
|
typedef enum {
|
||||||
CDC_CONTROL_LINE_STATE_DTR = 0x01,
|
CDC_CONTROL_LINE_STATE_DTR = 0x01,
|
||||||
CDC_CONTROL_LINE_STATE_RTS = 0x02,
|
CDC_CONTROL_LINE_STATE_RTS = 0x02,
|
||||||
};
|
} cdc_control_line_state_t;
|
||||||
|
|
||||||
enum {
|
typedef enum {
|
||||||
CDC_LINE_CODING_STOP_BITS_1 = 0, // 1 bit
|
CDC_LINE_CODING_STOP_BITS_1 = 0, // 1 bit
|
||||||
CDC_LINE_CODING_STOP_BITS_1_5 = 1, // 1.5 bits
|
CDC_LINE_CODING_STOP_BITS_1_5 = 1, // 1.5 bits
|
||||||
CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits
|
CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits
|
||||||
};
|
} cdc_line_coding_stopbits_t;
|
||||||
|
|
||||||
// TODO Backward compatible for typos. Maybe removed in the future release
|
// TODO Backward compatible for typos. Maybe removed in the future release
|
||||||
#define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1
|
#define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1
|
||||||
#define CDC_LINE_CONDING_STOP_BITS_1_5 CDC_LINE_CODING_STOP_BITS_1_5
|
#define CDC_LINE_CONDING_STOP_BITS_1_5 CDC_LINE_CODING_STOP_BITS_1_5
|
||||||
#define CDC_LINE_CONDING_STOP_BITS_2 CDC_LINE_CODING_STOP_BITS_2
|
#define CDC_LINE_CONDING_STOP_BITS_2 CDC_LINE_CODING_STOP_BITS_2
|
||||||
|
|
||||||
enum {
|
typedef enum {
|
||||||
CDC_LINE_CODING_PARITY_NONE = 0,
|
CDC_LINE_CODING_PARITY_NONE = 0,
|
||||||
CDC_LINE_CODING_PARITY_ODD = 1,
|
CDC_LINE_CODING_PARITY_ODD = 1,
|
||||||
CDC_LINE_CODING_PARITY_EVEN = 2,
|
CDC_LINE_CODING_PARITY_EVEN = 2,
|
||||||
CDC_LINE_CODING_PARITY_MARK = 3,
|
CDC_LINE_CODING_PARITY_MARK = 3,
|
||||||
CDC_LINE_CODING_PARITY_SPACE = 4,
|
CDC_LINE_CODING_PARITY_SPACE = 4,
|
||||||
};
|
} cdc_line_coding_parity_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Management Element Notification (Notification Endpoint)
|
// Management Element Notification (Notification Endpoint)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/// 6.3 Notification Codes
|
/// 6.3 Notification Codes
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status.
|
CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status.
|
||||||
CDC_NOTIF_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.
|
CDC_NOTIF_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.
|
||||||
CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,
|
CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -148,8 +148,11 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c
|
|||||||
// Request to set baudrate
|
// Request to set baudrate
|
||||||
bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
||||||
|
|
||||||
// Request to Set Line Coding (ACM only)
|
// Request to set data format
|
||||||
// Should only use if you don't work with serial devices such as FTDI/CP210x
|
bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
||||||
|
|
||||||
|
// Request to Set Line Coding = baudrate + data format
|
||||||
|
// Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet
|
||||||
bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
|
||||||
|
|
||||||
// Request to Get Line Coding (ACM only)
|
// Request to Get Line Coding (ACM only)
|
||||||
@ -159,15 +162,13 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding,
|
|||||||
|
|
||||||
// Connect by set both DTR, RTS
|
// Connect by set both DTR, RTS
|
||||||
TU_ATTR_ALWAYS_INLINE static inline
|
TU_ATTR_ALWAYS_INLINE static inline
|
||||||
bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
|
bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
{
|
|
||||||
return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data);
|
return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect by clear both DTR, RTS
|
// Disconnect by clear both DTR, RTS
|
||||||
TU_ATTR_ALWAYS_INLINE static inline
|
TU_ATTR_ALWAYS_INLINE static inline
|
||||||
bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
|
bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
|
||||||
{
|
|
||||||
return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data);
|
return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
84
src/class/cdc/serial/ch34x.h
Normal file
84
src/class/cdc/serial/ch34x.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Heiko Kuester
|
||||||
|
*
|
||||||
|
* 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 _CH34X_H_
|
||||||
|
#define _CH34X_H_
|
||||||
|
|
||||||
|
// There is no official documentation for the CH34x (CH340, CH341) chips. Reference can be found
|
||||||
|
// - https://github.com/WCHSoftGroup/ch341ser_linux
|
||||||
|
// - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c
|
||||||
|
// - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c
|
||||||
|
|
||||||
|
// set line_coding @ enumeration
|
||||||
|
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
||||||
|
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
||||||
|
#else // this default is necessary to work properly
|
||||||
|
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// USB requests
|
||||||
|
#define CH34X_REQ_READ_VERSION 0x5F // dec 95
|
||||||
|
#define CH34X_REQ_WRITE_REG 0x9A // dec 154
|
||||||
|
#define CH34X_REQ_READ_REG 0x95 // dec 149
|
||||||
|
#define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161
|
||||||
|
#define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164
|
||||||
|
|
||||||
|
// registers
|
||||||
|
#define CH34X_REG_BREAK 0x05
|
||||||
|
#define CH34X_REG_PRESCALER 0x12
|
||||||
|
#define CH34X_REG_DIVISOR 0x13
|
||||||
|
#define CH34X_REG_LCR 0x18
|
||||||
|
#define CH34X_REG_LCR2 0x25
|
||||||
|
#define CH34X_REG_MCR_MSR 0x06
|
||||||
|
#define CH34X_REG_MCR_MSR2 0x07
|
||||||
|
#define CH34X_NBREAK_BITS 0x01
|
||||||
|
|
||||||
|
#define CH341_REG_0x0F 0x0F // undocumented register
|
||||||
|
#define CH341_REG_0x2C 0x2C // undocumented register
|
||||||
|
#define CH341_REG_0x27 0x27 // hardware flow control (cts/rts)
|
||||||
|
|
||||||
|
#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER)
|
||||||
|
#define CH32X_REG16_LCR2_LCR TU_U16(CH34X_REG_LCR2, CH34X_REG_LCR)
|
||||||
|
|
||||||
|
// modem control bits
|
||||||
|
#define CH34X_BIT_RTS ( 1 << 6 )
|
||||||
|
#define CH34X_BIT_DTR ( 1 << 5 )
|
||||||
|
|
||||||
|
// line control bits
|
||||||
|
#define CH34X_LCR_ENABLE_RX 0x80
|
||||||
|
#define CH34X_LCR_ENABLE_TX 0x40
|
||||||
|
#define CH34X_LCR_MARK_SPACE 0x20
|
||||||
|
#define CH34X_LCR_PAR_EVEN 0x10
|
||||||
|
#define CH34X_LCR_ENABLE_PAR 0x08
|
||||||
|
#define CH34X_LCR_PAR_MASK 0x38 // all parity bits
|
||||||
|
#define CH34X_LCR_STOP_BITS_2 0x04
|
||||||
|
#define CH34X_LCR_CS8 0x03
|
||||||
|
#define CH34X_LCR_CS7 0x02
|
||||||
|
#define CH34X_LCR_CS6 0x01
|
||||||
|
#define CH34X_LCR_CS5 0x00
|
||||||
|
#define CH34X_LCR_CS_MASK 0x03 // all CSx bits
|
||||||
|
|
||||||
|
#endif /* _CH34X_H_ */
|
@ -434,8 +434,9 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
|
|||||||
uint_fast32_t interval_ms = interval / 10000;
|
uint_fast32_t interval_ms = interval / 10000;
|
||||||
TU_ASSERT(interval_ms);
|
TU_ASSERT(interval_ms);
|
||||||
uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2;
|
uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2;
|
||||||
if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size)
|
if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) {
|
||||||
payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE;
|
payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE;
|
||||||
|
}
|
||||||
param->dwMaxPayloadTransferSize = payload_size;
|
param->dwMaxPayloadTransferSize = payload_size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -577,8 +578,9 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *
|
|||||||
} else {
|
} else {
|
||||||
payload_size = (frame_size + interval_ms - 1) / interval_ms + 2;
|
payload_size = (frame_size + interval_ms - 1) / interval_ms + 2;
|
||||||
}
|
}
|
||||||
if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size)
|
if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) {
|
||||||
payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE;
|
payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE;
|
||||||
|
}
|
||||||
param->dwMaxPayloadTransferSize = payload_size;
|
param->dwMaxPayloadTransferSize = payload_size;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#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_DIV_CEIL(n, d) (((n) + (d) - 1) / (d))
|
||||||
|
|
||||||
#define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low)))
|
#define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low)))
|
||||||
#define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff))
|
#define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff))
|
||||||
|
@ -44,43 +44,38 @@
|
|||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
/// 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 = 1,
|
TUSB_SPEED_LOW = 1,
|
||||||
TUSB_SPEED_HIGH = 2,
|
TUSB_SPEED_HIGH = 2,
|
||||||
TUSB_SPEED_INVALID = 0xff,
|
TUSB_SPEED_INVALID = 0xff,
|
||||||
}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;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
TUSB_EPSIZE_BULK_FS = 64,
|
TUSB_EPSIZE_BULK_FS = 64,
|
||||||
TUSB_EPSIZE_BULK_HS= 512,
|
TUSB_EPSIZE_BULK_HS = 512,
|
||||||
|
|
||||||
TUSB_EPSIZE_ISO_FS_MAX = 1023,
|
TUSB_EPSIZE_ISO_FS_MAX = 1023,
|
||||||
TUSB_EPSIZE_ISO_HS_MAX = 1024,
|
TUSB_EPSIZE_ISO_HS_MAX = 1024,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Isochronous End Point Attributes
|
/// Isochronous Endpoint Attributes
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
TUSB_ISO_EP_ATT_NO_SYNC = 0x00,
|
TUSB_ISO_EP_ATT_NO_SYNC = 0x00,
|
||||||
TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04,
|
TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04,
|
||||||
TUSB_ISO_EP_ATT_ADAPTIVE = 0x08,
|
TUSB_ISO_EP_ATT_ADAPTIVE = 0x08,
|
||||||
@ -88,11 +83,10 @@ typedef enum
|
|||||||
TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point
|
TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point
|
||||||
TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point
|
TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point
|
||||||
TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback
|
TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback
|
||||||
}tusb_iso_ep_attribute_t;
|
} tusb_iso_ep_attribute_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,
|
||||||
@ -119,10 +113,9 @@ typedef enum
|
|||||||
|
|
||||||
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 ,
|
||||||
@ -136,25 +129,22 @@ typedef enum
|
|||||||
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,
|
||||||
@ -162,8 +152,7 @@ typedef enum
|
|||||||
} tusb_request_recipient_t;
|
} tusb_request_recipient_t;
|
||||||
|
|
||||||
// https://www.usb.org/defined-class-codes
|
// https://www.usb.org/defined-class-codes
|
||||||
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 ,
|
||||||
@ -187,26 +176,23 @@ typedef enum
|
|||||||
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 {
|
||||||
{
|
|
||||||
APP_SUBCLASS_USBTMC = 0x03,
|
APP_SUBCLASS_USBTMC = 0x03,
|
||||||
APP_SUBCLASS_DFU_RUNTIME = 0x01
|
APP_SUBCLASS_DFU_RUNTIME = 0x01
|
||||||
} app_subclass_type_t;
|
} app_subclass_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,
|
||||||
@ -223,7 +209,7 @@ typedef enum
|
|||||||
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),
|
||||||
@ -235,28 +221,25 @@ enum {
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
XFER_RESULT_SUCCESS = 0,
|
XFER_RESULT_SUCCESS = 0,
|
||||||
XFER_RESULT_FAILED,
|
XFER_RESULT_FAILED,
|
||||||
XFER_RESULT_STALLED,
|
XFER_RESULT_STALLED,
|
||||||
XFER_RESULT_TIMEOUT,
|
XFER_RESULT_TIMEOUT,
|
||||||
XFER_RESULT_INVALID
|
XFER_RESULT_INVALID
|
||||||
}xfer_result_t;
|
} xfer_result_t;
|
||||||
|
|
||||||
enum // TODO remove
|
// TODO remove
|
||||||
{
|
enum {
|
||||||
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,
|
||||||
@ -268,16 +251,14 @@ typedef enum
|
|||||||
MS_OS_20_FEATURE_VENDOR_REVISION = 0x08
|
MS_OS_20_FEATURE_VENDOR_REVISION = 0x08
|
||||||
} microsoft_os_20_type_t;
|
} microsoft_os_20_type_t;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
CONTROL_STAGE_IDLE,
|
CONTROL_STAGE_IDLE,
|
||||||
CONTROL_STAGE_SETUP,
|
CONTROL_STAGE_SETUP,
|
||||||
CONTROL_STAGE_DATA,
|
CONTROL_STAGE_DATA,
|
||||||
CONTROL_STAGE_ACK
|
CONTROL_STAGE_ACK
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
TUSB_INDEX_INVALID_8 = 0xFFu
|
TUSB_INDEX_INVALID_8 = 0xFFu
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -290,8 +271,7 @@ TU_ATTR_PACKED_BEGIN
|
|||||||
TU_ATTR_BIT_FIELD_ORDER_BEGIN
|
TU_ATTR_BIT_FIELD_ORDER_BEGIN
|
||||||
|
|
||||||
/// 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.
|
||||||
@ -314,8 +294,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct");
|
||||||
|
|
||||||
// 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
|
||||||
@ -325,8 +304,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct");
|
||||||
|
|
||||||
/// 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.
|
||||||
@ -341,8 +319,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct");
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
||||||
@ -358,8 +335,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct");
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
||||||
@ -379,8 +355,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct");
|
||||||
|
|
||||||
/// 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
|
||||||
@ -393,8 +368,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
} 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)
|
||||||
@ -411,8 +385,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct");
|
TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct");
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
||||||
@ -427,16 +400,14 @@ typedef struct TU_ATTR_PACKED
|
|||||||
} 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;
|
||||||
@ -445,9 +416,8 @@ typedef struct TU_ATTR_PACKED
|
|||||||
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;
|
||||||
@ -455,8 +425,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
} tusb_desc_webusb_url_t;
|
} tusb_desc_webusb_url_t;
|
||||||
|
|
||||||
// DFU Functional Descriptor
|
// DFU Functional Descriptor
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED {
|
||||||
{
|
|
||||||
uint8_t bLength;
|
uint8_t bLength;
|
||||||
uint8_t bDescriptorType;
|
uint8_t bDescriptorType;
|
||||||
|
|
||||||
@ -481,7 +450,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
//
|
//
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
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.
|
||||||
@ -509,36 +478,30 @@ TU_ATTR_BIT_FIELD_ORDER_END
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Get direction from Endpoint address
|
// Get direction from Endpoint address
|
||||||
TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr)
|
TU_ATTR_ALWAYS_INLINE 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
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr)
|
TU_ATTR_ALWAYS_INLINE 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
|
TU_ATTR_ALWAYS_INLINE 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep)
|
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) {
|
||||||
{
|
|
||||||
return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0);
|
return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_DEBUG
|
#if CFG_TUSB_DEBUG
|
||||||
TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir)
|
TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) {
|
||||||
{
|
|
||||||
tu_static const char *str[] = {"out", "in"};
|
tu_static const char *str[] = {"out", "in"};
|
||||||
return str[dir];
|
return str[dir];
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t)
|
TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) {
|
||||||
{
|
|
||||||
tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"};
|
tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"};
|
||||||
return str[t];
|
return str[t];
|
||||||
}
|
}
|
||||||
@ -549,21 +512,18 @@ TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// return next descriptor
|
// return next descriptor
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc)
|
TU_ATTR_ALWAYS_INLINE 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get descriptor type
|
// get descriptor type
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc)
|
TU_ATTR_ALWAYS_INLINE 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get descriptor length
|
// get descriptor length
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc)
|
TU_ATTR_ALWAYS_INLINE 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void dcd_sof_enable(uint8_t rhport, bool en);
|
|||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
// 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 * desc_ep);
|
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep);
|
||||||
|
@ -38,11 +38,19 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBD Configuration
|
// USBD Configuration
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#ifndef CFG_TUD_TASK_QUEUE_SZ
|
#ifndef CFG_TUD_TASK_QUEUE_SZ
|
||||||
#define CFG_TUD_TASK_QUEUE_SZ 16
|
#define CFG_TUD_TASK_QUEUE_SZ 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Callback weak stubs (called if application does not provide)
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
|
||||||
|
(void)rhport;
|
||||||
|
(void)eventid;
|
||||||
|
(void)in_isr;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Device Data
|
// Device Data
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -50,10 +58,8 @@
|
|||||||
// Invalid driver ID in itf2drv[] ep2drv[][] mapping
|
// Invalid driver ID in itf2drv[] ep2drv[][] mapping
|
||||||
enum { DRVID_INVALID = 0xFFu };
|
enum { DRVID_INVALID = 0xFFu };
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
struct TU_ATTR_PACKED {
|
||||||
struct TU_ATTR_PACKED
|
|
||||||
{
|
|
||||||
volatile uint8_t connected : 1;
|
volatile uint8_t connected : 1;
|
||||||
volatile uint8_t addressed : 1;
|
volatile uint8_t addressed : 1;
|
||||||
volatile uint8_t suspended : 1;
|
volatile uint8_t suspended : 1;
|
||||||
@ -85,151 +91,150 @@ tu_static usbd_device_t _usbd_dev;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Built-in class drivers
|
// Built-in class drivers
|
||||||
tu_static usbd_class_driver_t const _usbd_driver[] =
|
tu_static usbd_class_driver_t const _usbd_driver[] = {
|
||||||
{
|
#if CFG_TUD_CDC
|
||||||
#if CFG_TUD_CDC
|
{
|
||||||
{
|
DRIVER_NAME("CDC")
|
||||||
DRIVER_NAME("CDC")
|
.init = cdcd_init,
|
||||||
.init = cdcd_init,
|
.reset = cdcd_reset,
|
||||||
.reset = cdcd_reset,
|
.open = cdcd_open,
|
||||||
.open = cdcd_open,
|
.control_xfer_cb = cdcd_control_xfer_cb,
|
||||||
.control_xfer_cb = cdcd_control_xfer_cb,
|
.xfer_cb = cdcd_xfer_cb,
|
||||||
.xfer_cb = cdcd_xfer_cb,
|
.sof = NULL
|
||||||
.sof = NULL
|
},
|
||||||
},
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CFG_TUD_MSC
|
#if CFG_TUD_MSC
|
||||||
{
|
{
|
||||||
DRIVER_NAME("MSC")
|
DRIVER_NAME("MSC")
|
||||||
.init = mscd_init,
|
.init = mscd_init,
|
||||||
.reset = mscd_reset,
|
.reset = mscd_reset,
|
||||||
.open = mscd_open,
|
.open = mscd_open,
|
||||||
.control_xfer_cb = mscd_control_xfer_cb,
|
.control_xfer_cb = mscd_control_xfer_cb,
|
||||||
.xfer_cb = mscd_xfer_cb,
|
.xfer_cb = mscd_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_HID
|
#if CFG_TUD_HID
|
||||||
{
|
{
|
||||||
DRIVER_NAME("HID")
|
DRIVER_NAME("HID")
|
||||||
.init = hidd_init,
|
.init = hidd_init,
|
||||||
.reset = hidd_reset,
|
.reset = hidd_reset,
|
||||||
.open = hidd_open,
|
.open = hidd_open,
|
||||||
.control_xfer_cb = hidd_control_xfer_cb,
|
.control_xfer_cb = hidd_control_xfer_cb,
|
||||||
.xfer_cb = hidd_xfer_cb,
|
.xfer_cb = hidd_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_AUDIO
|
#if CFG_TUD_AUDIO
|
||||||
{
|
{
|
||||||
DRIVER_NAME("AUDIO")
|
DRIVER_NAME("AUDIO")
|
||||||
.init = audiod_init,
|
.init = audiod_init,
|
||||||
.reset = audiod_reset,
|
.reset = audiod_reset,
|
||||||
.open = audiod_open,
|
.open = audiod_open,
|
||||||
.control_xfer_cb = audiod_control_xfer_cb,
|
.control_xfer_cb = audiod_control_xfer_cb,
|
||||||
.xfer_cb = audiod_xfer_cb,
|
.xfer_cb = audiod_xfer_cb,
|
||||||
.sof = audiod_sof_isr
|
.sof = audiod_sof_isr
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_VIDEO
|
#if CFG_TUD_VIDEO
|
||||||
{
|
{
|
||||||
DRIVER_NAME("VIDEO")
|
DRIVER_NAME("VIDEO")
|
||||||
.init = videod_init,
|
.init = videod_init,
|
||||||
.reset = videod_reset,
|
.reset = videod_reset,
|
||||||
.open = videod_open,
|
.open = videod_open,
|
||||||
.control_xfer_cb = videod_control_xfer_cb,
|
.control_xfer_cb = videod_control_xfer_cb,
|
||||||
.xfer_cb = videod_xfer_cb,
|
.xfer_cb = videod_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_MIDI
|
#if CFG_TUD_MIDI
|
||||||
{
|
{
|
||||||
DRIVER_NAME("MIDI")
|
DRIVER_NAME("MIDI")
|
||||||
.init = midid_init,
|
.init = midid_init,
|
||||||
.open = midid_open,
|
.open = midid_open,
|
||||||
.reset = midid_reset,
|
.reset = midid_reset,
|
||||||
.control_xfer_cb = midid_control_xfer_cb,
|
.control_xfer_cb = midid_control_xfer_cb,
|
||||||
.xfer_cb = midid_xfer_cb,
|
.xfer_cb = midid_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_VENDOR
|
#if CFG_TUD_VENDOR
|
||||||
{
|
{
|
||||||
DRIVER_NAME("VENDOR")
|
DRIVER_NAME("VENDOR")
|
||||||
.init = vendord_init,
|
.init = vendord_init,
|
||||||
.reset = vendord_reset,
|
.reset = vendord_reset,
|
||||||
.open = vendord_open,
|
.open = vendord_open,
|
||||||
.control_xfer_cb = tud_vendor_control_xfer_cb,
|
.control_xfer_cb = tud_vendor_control_xfer_cb,
|
||||||
.xfer_cb = vendord_xfer_cb,
|
.xfer_cb = vendord_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_USBTMC
|
#if CFG_TUD_USBTMC
|
||||||
{
|
{
|
||||||
DRIVER_NAME("TMC")
|
DRIVER_NAME("TMC")
|
||||||
.init = usbtmcd_init_cb,
|
.init = usbtmcd_init_cb,
|
||||||
.reset = usbtmcd_reset_cb,
|
.reset = usbtmcd_reset_cb,
|
||||||
.open = usbtmcd_open_cb,
|
.open = usbtmcd_open_cb,
|
||||||
.control_xfer_cb = usbtmcd_control_xfer_cb,
|
.control_xfer_cb = usbtmcd_control_xfer_cb,
|
||||||
.xfer_cb = usbtmcd_xfer_cb,
|
.xfer_cb = usbtmcd_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_DFU_RUNTIME
|
#if CFG_TUD_DFU_RUNTIME
|
||||||
{
|
{
|
||||||
DRIVER_NAME("DFU-RUNTIME")
|
DRIVER_NAME("DFU-RUNTIME")
|
||||||
.init = dfu_rtd_init,
|
.init = dfu_rtd_init,
|
||||||
.reset = dfu_rtd_reset,
|
.reset = dfu_rtd_reset,
|
||||||
.open = dfu_rtd_open,
|
.open = dfu_rtd_open,
|
||||||
.control_xfer_cb = dfu_rtd_control_xfer_cb,
|
.control_xfer_cb = dfu_rtd_control_xfer_cb,
|
||||||
.xfer_cb = NULL,
|
.xfer_cb = NULL,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_DFU
|
#if CFG_TUD_DFU
|
||||||
{
|
{
|
||||||
DRIVER_NAME("DFU")
|
DRIVER_NAME("DFU")
|
||||||
.init = dfu_moded_init,
|
.init = dfu_moded_init,
|
||||||
.reset = dfu_moded_reset,
|
.reset = dfu_moded_reset,
|
||||||
.open = dfu_moded_open,
|
.open = dfu_moded_open,
|
||||||
.control_xfer_cb = dfu_moded_control_xfer_cb,
|
.control_xfer_cb = dfu_moded_control_xfer_cb,
|
||||||
.xfer_cb = NULL,
|
.xfer_cb = NULL,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
|
#if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
|
||||||
{
|
{
|
||||||
DRIVER_NAME("NET")
|
DRIVER_NAME("NET")
|
||||||
.init = netd_init,
|
.init = netd_init,
|
||||||
.reset = netd_reset,
|
.reset = netd_reset,
|
||||||
.open = netd_open,
|
.open = netd_open,
|
||||||
.control_xfer_cb = netd_control_xfer_cb,
|
.control_xfer_cb = netd_control_xfer_cb,
|
||||||
.xfer_cb = netd_xfer_cb,
|
.xfer_cb = netd_xfer_cb,
|
||||||
.sof = NULL,
|
.sof = NULL,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_BTH
|
#if CFG_TUD_BTH
|
||||||
{
|
{
|
||||||
DRIVER_NAME("BTH")
|
DRIVER_NAME("BTH")
|
||||||
.init = btd_init,
|
.init = btd_init,
|
||||||
.reset = btd_reset,
|
.reset = btd_reset,
|
||||||
.open = btd_open,
|
.open = btd_open,
|
||||||
.control_xfer_cb = btd_control_xfer_cb,
|
.control_xfer_cb = btd_control_xfer_cb,
|
||||||
.xfer_cb = btd_xfer_cb,
|
.xfer_cb = btd_xfer_cb,
|
||||||
.sof = NULL
|
.sof = NULL
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
|
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
|
||||||
@ -275,7 +280,7 @@ tu_static osal_queue_t _usbd_q;
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) {
|
TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) {
|
||||||
bool ret = osal_queue_send(_usbd_q, event, in_isr);
|
bool ret = osal_queue_send(_usbd_q, event, in_isr);
|
||||||
if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr);
|
tud_event_hook_cb(event->rhport, event->event_id, in_isr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,27 +302,23 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
|||||||
// Debug
|
// Debug
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||||
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
|
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = {
|
||||||
{
|
"Invalid",
|
||||||
"Invalid" ,
|
"Bus Reset",
|
||||||
"Bus Reset" ,
|
"Unplugged",
|
||||||
"Unplugged" ,
|
"SOF",
|
||||||
"SOF" ,
|
"Suspend",
|
||||||
"Suspend" ,
|
"Resume",
|
||||||
"Resume" ,
|
"Setup Received",
|
||||||
"Setup Received" ,
|
"Xfer Complete",
|
||||||
"Xfer Complete" ,
|
"Func Call"
|
||||||
"Func Call"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// for usbd_control to print the name of control complete driver
|
// for usbd_control to print the name of control complete driver
|
||||||
void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
|
void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) {
|
||||||
{
|
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
|
||||||
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
|
usbd_class_driver_t const* driver = get_driver(i);
|
||||||
{
|
if (driver && driver->control_xfer_cb == callback) {
|
||||||
usbd_class_driver_t const * driver = get_driver(i);
|
|
||||||
if ( driver && driver->control_xfer_cb == callback )
|
|
||||||
{
|
|
||||||
TU_LOG_USBD(" %s control complete\r\n", driver->name);
|
TU_LOG_USBD(" %s control complete\r\n", driver->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -329,43 +330,36 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API
|
// Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
tusb_speed_t tud_speed_get(void)
|
tusb_speed_t tud_speed_get(void) {
|
||||||
{
|
|
||||||
return (tusb_speed_t) _usbd_dev.speed;
|
return (tusb_speed_t) _usbd_dev.speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_connected(void)
|
bool tud_connected(void) {
|
||||||
{
|
|
||||||
return _usbd_dev.connected;
|
return _usbd_dev.connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_mounted(void)
|
bool tud_mounted(void) {
|
||||||
{
|
|
||||||
return _usbd_dev.cfg_num ? true : false;
|
return _usbd_dev.cfg_num ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_suspended(void)
|
bool tud_suspended(void) {
|
||||||
{
|
|
||||||
return _usbd_dev.suspended;
|
return _usbd_dev.suspended;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_remote_wakeup(void)
|
bool tud_remote_wakeup(void) {
|
||||||
{
|
|
||||||
// only wake up host if this feature is supported and enabled and we are suspended
|
// only wake up host if this feature is supported and enabled and we are suspended
|
||||||
TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en );
|
TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en);
|
||||||
dcd_remote_wakeup(_usbd_rhport);
|
dcd_remote_wakeup(_usbd_rhport);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_disconnect(void)
|
bool tud_disconnect(void) {
|
||||||
{
|
|
||||||
TU_VERIFY(dcd_disconnect);
|
TU_VERIFY(dcd_disconnect);
|
||||||
dcd_disconnect(_usbd_rhport);
|
dcd_disconnect(_usbd_rhport);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_connect(void)
|
bool tud_connect(void) {
|
||||||
{
|
|
||||||
TU_VERIFY(dcd_connect);
|
TU_VERIFY(dcd_connect);
|
||||||
dcd_connect(_usbd_rhport);
|
dcd_connect(_usbd_rhport);
|
||||||
return true;
|
return true;
|
||||||
|
@ -147,7 +147,7 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en);
|
|||||||
TU_ATTR_WEAK void tud_resume_cb(void);
|
TU_ATTR_WEAK void tud_resume_cb(void);
|
||||||
|
|
||||||
// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext()
|
// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext()
|
||||||
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
|
void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
|
||||||
|
|
||||||
// Invoked when received control request with VENDOR TYPE
|
// Invoked when received control request with VENDOR TYPE
|
||||||
TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||||
|
@ -32,24 +32,32 @@
|
|||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "device/usbd_pvt.h"
|
#include "device/usbd_pvt.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Callback weak stubs (called if application does not provide)
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) {
|
||||||
|
(void) rhport;
|
||||||
|
(void) request;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO CONSTANT TYPEDEF
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||||
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
|
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
EDPT_CTRL_OUT = 0x00,
|
EDPT_CTRL_OUT = 0x00,
|
||||||
EDPT_CTRL_IN = 0x80
|
EDPT_CTRL_IN = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
tusb_control_request_t request;
|
tusb_control_request_t request;
|
||||||
|
|
||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
uint16_t data_len;
|
uint16_t data_len;
|
||||||
uint16_t total_xferred;
|
uint16_t total_xferred;
|
||||||
|
|
||||||
usbd_control_xfer_cb_t complete_cb;
|
usbd_control_xfer_cb_t complete_cb;
|
||||||
} usbd_control_xfer_t;
|
} usbd_control_xfer_t;
|
||||||
|
|
||||||
@ -63,20 +71,18 @@ tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Queue ZLP status transaction
|
// Queue ZLP status transaction
|
||||||
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const * request)
|
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) {
|
||||||
{
|
|
||||||
// Opposite to endpoint in Data Phase
|
// Opposite to endpoint in Data Phase
|
||||||
uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN;
|
uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN;
|
||||||
return usbd_edpt_xfer(rhport, ep_addr, NULL, 0);
|
return usbd_edpt_xfer(rhport, ep_addr, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status phase
|
// Status phase
|
||||||
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) {
|
||||||
{
|
_ctrl_xfer.request = (*request);
|
||||||
_ctrl_xfer.request = (*request);
|
_ctrl_xfer.buffer = NULL;
|
||||||
_ctrl_xfer.buffer = NULL;
|
|
||||||
_ctrl_xfer.total_xferred = 0;
|
_ctrl_xfer.total_xferred = 0;
|
||||||
_ctrl_xfer.data_len = 0;
|
_ctrl_xfer.data_len = 0;
|
||||||
|
|
||||||
return _status_stage_xact(rhport, request);
|
return _status_stage_xact(rhport, request);
|
||||||
}
|
}
|
||||||
@ -84,16 +90,15 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request)
|
|||||||
// Queue a transaction in Data Stage
|
// Queue a transaction in Data Stage
|
||||||
// Each transaction has up to Endpoint0's max packet size.
|
// Each transaction has up to Endpoint0's max packet size.
|
||||||
// This function can also transfer an zero-length packet
|
// This function can also transfer an zero-length packet
|
||||||
static bool _data_stage_xact(uint8_t rhport)
|
static bool _data_stage_xact(uint8_t rhport) {
|
||||||
{
|
uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred,
|
||||||
uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE);
|
CFG_TUD_ENDPOINT0_SIZE);
|
||||||
|
|
||||||
uint8_t ep_addr = EDPT_CTRL_OUT;
|
uint8_t ep_addr = EDPT_CTRL_OUT;
|
||||||
|
|
||||||
if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN )
|
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) {
|
||||||
{
|
|
||||||
ep_addr = EDPT_CTRL_IN;
|
ep_addr = EDPT_CTRL_IN;
|
||||||
if ( xact_len ) {
|
if (xact_len) {
|
||||||
TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len));
|
TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,29 +108,24 @@ static bool _data_stage_xact(uint8_t rhport)
|
|||||||
|
|
||||||
// Transmit data to/from the control endpoint.
|
// Transmit data to/from the control endpoint.
|
||||||
// If the request's wLength is zero, a status packet is sent instead.
|
// If the request's wLength is zero, a status packet is sent instead.
|
||||||
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) {
|
||||||
{
|
_ctrl_xfer.request = (*request);
|
||||||
_ctrl_xfer.request = (*request);
|
_ctrl_xfer.buffer = (uint8_t*) buffer;
|
||||||
_ctrl_xfer.buffer = (uint8_t*) buffer;
|
|
||||||
_ctrl_xfer.total_xferred = 0U;
|
_ctrl_xfer.total_xferred = 0U;
|
||||||
_ctrl_xfer.data_len = tu_min16(len, request->wLength);
|
_ctrl_xfer.data_len = tu_min16(len, request->wLength);
|
||||||
|
|
||||||
if (request->wLength > 0U)
|
if (request->wLength > 0U) {
|
||||||
{
|
if (_ctrl_xfer.data_len > 0U) {
|
||||||
if(_ctrl_xfer.data_len > 0U)
|
|
||||||
{
|
|
||||||
TU_ASSERT(buffer);
|
TU_ASSERT(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len);
|
// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len);
|
||||||
|
|
||||||
// Data stage
|
// Data stage
|
||||||
TU_ASSERT( _data_stage_xact(rhport) );
|
TU_ASSERT(_data_stage_xact(rhport));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Status stage
|
// Status stage
|
||||||
TU_ASSERT( _status_stage_xact(rhport, request) );
|
TU_ASSERT(_status_stage_xact(rhport, request));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -134,49 +134,42 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBD API
|
// USBD API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void usbd_control_reset(void);
|
void usbd_control_reset(void);
|
||||||
void usbd_control_set_request(tusb_control_request_t const *request);
|
void usbd_control_set_request(tusb_control_request_t const* request);
|
||||||
void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp );
|
void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp);
|
||||||
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||||
|
|
||||||
void usbd_control_reset(void)
|
void usbd_control_reset(void) {
|
||||||
{
|
|
||||||
tu_varclr(&_ctrl_xfer);
|
tu_varclr(&_ctrl_xfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set complete callback
|
// Set complete callback
|
||||||
void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp )
|
void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) {
|
||||||
{
|
|
||||||
_ctrl_xfer.complete_cb = fp;
|
_ctrl_xfer.complete_cb = fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for dcd_set_address where DCD is responsible for status response
|
// for dcd_set_address where DCD is responsible for status response
|
||||||
void usbd_control_set_request(tusb_control_request_t const *request)
|
void usbd_control_set_request(tusb_control_request_t const* request) {
|
||||||
{
|
_ctrl_xfer.request = (*request);
|
||||||
_ctrl_xfer.request = (*request);
|
_ctrl_xfer.buffer = NULL;
|
||||||
_ctrl_xfer.buffer = NULL;
|
|
||||||
_ctrl_xfer.total_xferred = 0;
|
_ctrl_xfer.total_xferred = 0;
|
||||||
_ctrl_xfer.data_len = 0;
|
_ctrl_xfer.data_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback when a transaction complete on
|
// callback when a transaction complete on
|
||||||
// - DATA stage of control endpoint or
|
// - DATA stage of control endpoint or
|
||||||
// - Status stage
|
// - Status stage
|
||||||
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
|
||||||
{
|
|
||||||
(void) result;
|
(void) result;
|
||||||
|
|
||||||
// Endpoint Address is opposite to direction bit, this is Status Stage complete event
|
// Endpoint Address is opposite to direction bit, this is Status Stage complete event
|
||||||
if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction )
|
if (tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction) {
|
||||||
{
|
|
||||||
TU_ASSERT(0 == xferred_bytes);
|
TU_ASSERT(0 == xferred_bytes);
|
||||||
|
|
||||||
// invoke optional dcd hook if available
|
// invoke optional dcd hook if available
|
||||||
if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request);
|
dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request);
|
||||||
|
|
||||||
if (_ctrl_xfer.complete_cb)
|
if (_ctrl_xfer.complete_cb) {
|
||||||
{
|
|
||||||
// TODO refactor with usbd_driver_print_control_complete_name
|
// TODO refactor with usbd_driver_print_control_complete_name
|
||||||
_ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request);
|
_ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request);
|
||||||
}
|
}
|
||||||
@ -184,8 +177,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT )
|
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
|
||||||
{
|
|
||||||
TU_VERIFY(_ctrl_xfer.buffer);
|
TU_VERIFY(_ctrl_xfer.buffer);
|
||||||
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
|
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
|
||||||
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
|
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
|
||||||
@ -196,15 +188,14 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
|
|||||||
|
|
||||||
// Data Stage is complete when all request's length are transferred or
|
// Data Stage is complete when all request's length are transferred or
|
||||||
// a short packet is sent including zero-length packet.
|
// a short packet is sent including zero-length packet.
|
||||||
if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE) )
|
if ((_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) ||
|
||||||
{
|
(xferred_bytes < CFG_TUD_ENDPOINT0_SIZE)) {
|
||||||
// DATA stage is complete
|
// DATA stage is complete
|
||||||
bool is_ok = true;
|
bool is_ok = true;
|
||||||
|
|
||||||
// invoke complete callback if set
|
// invoke complete callback if set
|
||||||
// callback can still stall control in status phase e.g out data does not make sense
|
// callback can still stall control in status phase e.g out data does not make sense
|
||||||
if ( _ctrl_xfer.complete_cb )
|
if (_ctrl_xfer.complete_cb) {
|
||||||
{
|
|
||||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||||
usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
|
usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
|
||||||
#endif
|
#endif
|
||||||
@ -212,21 +203,17 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
|
|||||||
is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request);
|
is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( is_ok )
|
if (is_ok) {
|
||||||
{
|
|
||||||
// Send status
|
// Send status
|
||||||
TU_ASSERT( _status_stage_xact(rhport, &_ctrl_xfer.request) );
|
TU_ASSERT(_status_stage_xact(rhport, &_ctrl_xfer.request));
|
||||||
}else
|
} else {
|
||||||
{
|
|
||||||
// Stall both IN and OUT control endpoint
|
// Stall both IN and OUT control endpoint
|
||||||
dcd_edpt_stall(rhport, EDPT_CTRL_OUT);
|
dcd_edpt_stall(rhport, EDPT_CTRL_OUT);
|
||||||
dcd_edpt_stall(rhport, EDPT_CTRL_IN);
|
dcd_edpt_stall(rhport, EDPT_CTRL_IN);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// More data to transfer
|
// More data to transfer
|
||||||
TU_ASSERT( _data_stage_xact(rhport) );
|
TU_ASSERT(_data_stage_xact(rhport));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -435,9 +435,12 @@ static void hub_port_get_status_complete (tuh_xfer_t* xfer)
|
|||||||
// Other changes are: L1 state
|
// Other changes are: L1 state
|
||||||
// TODO clear change
|
// TODO clear change
|
||||||
|
|
||||||
// prepare for next hub status
|
else
|
||||||
// TODO continue with status_change, or maybe we can do it again with status
|
{
|
||||||
hub_edpt_status_xfer(daddr);
|
// prepare for next hub status
|
||||||
|
// TODO continue with status_change, or maybe we can do it again with status
|
||||||
|
hub_edpt_status_xfer(daddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
128
src/host/usbh.c
128
src/host/usbh.c
@ -36,7 +36,6 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBH Configuration
|
// USBH Configuration
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#ifndef CFG_TUH_TASK_QUEUE_SZ
|
#ifndef CFG_TUH_TASK_QUEUE_SZ
|
||||||
#define CFG_TUH_TASK_QUEUE_SZ 16
|
#define CFG_TUH_TASK_QUEUE_SZ 16
|
||||||
#endif
|
#endif
|
||||||
@ -45,12 +44,19 @@
|
|||||||
#define CFG_TUH_INTERFACE_MAX 8
|
#define CFG_TUH_INTERFACE_MAX 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Callback weak stubs (called if application does not provide)
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
|
||||||
|
(void) rhport;
|
||||||
|
(void) eventid;
|
||||||
|
(void) in_isr;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBH-HCD common data structure
|
// USBH-HCD common data structure
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
typedef struct {
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
// port
|
// port
|
||||||
uint8_t rhport;
|
uint8_t rhport;
|
||||||
uint8_t hub_addr;
|
uint8_t hub_addr;
|
||||||
@ -112,60 +118,58 @@ typedef struct {
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
|
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
|
||||||
#define DRIVER_NAME(_name) .name = _name,
|
#define DRIVER_NAME(_name) .name = _name,
|
||||||
#else
|
#else
|
||||||
#define DRIVER_NAME(_name)
|
#define DRIVER_NAME(_name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static usbh_class_driver_t const usbh_class_drivers[] =
|
static usbh_class_driver_t const usbh_class_drivers[] = {
|
||||||
{
|
#if CFG_TUH_CDC
|
||||||
#if CFG_TUH_CDC
|
|
||||||
{
|
{
|
||||||
DRIVER_NAME("CDC")
|
DRIVER_NAME("CDC")
|
||||||
.init = cdch_init,
|
.init = cdch_init,
|
||||||
.open = cdch_open,
|
.open = cdch_open,
|
||||||
.set_config = cdch_set_config,
|
.set_config = cdch_set_config,
|
||||||
.xfer_cb = cdch_xfer_cb,
|
.xfer_cb = cdch_xfer_cb,
|
||||||
.close = cdch_close
|
.close = cdch_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_MSC
|
#if CFG_TUH_MSC
|
||||||
{
|
{
|
||||||
DRIVER_NAME("MSC")
|
DRIVER_NAME("MSC")
|
||||||
.init = msch_init,
|
.init = msch_init,
|
||||||
.open = msch_open,
|
.open = msch_open,
|
||||||
.set_config = msch_set_config,
|
.set_config = msch_set_config,
|
||||||
.xfer_cb = msch_xfer_cb,
|
.xfer_cb = msch_xfer_cb,
|
||||||
.close = msch_close
|
.close = msch_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_HID
|
#if CFG_TUH_HID
|
||||||
{
|
{
|
||||||
DRIVER_NAME("HID")
|
DRIVER_NAME("HID")
|
||||||
.init = hidh_init,
|
.init = hidh_init,
|
||||||
.open = hidh_open,
|
.open = hidh_open,
|
||||||
.set_config = hidh_set_config,
|
.set_config = hidh_set_config,
|
||||||
.xfer_cb = hidh_xfer_cb,
|
.xfer_cb = hidh_xfer_cb,
|
||||||
.close = hidh_close
|
.close = hidh_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_HUB
|
#if CFG_TUH_HUB
|
||||||
{
|
{
|
||||||
DRIVER_NAME("HUB")
|
DRIVER_NAME("HUB")
|
||||||
.init = hub_init,
|
.init = hub_init,
|
||||||
.open = hub_open,
|
.open = hub_open,
|
||||||
.set_config = hub_set_config,
|
.set_config = hub_set_config,
|
||||||
.xfer_cb = hub_xfer_cb,
|
.xfer_cb = hub_xfer_cb,
|
||||||
.close = hub_close
|
.close = hub_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUH_VENDOR
|
#if CFG_TUH_VENDOR
|
||||||
{
|
{
|
||||||
DRIVER_NAME("VENDOR")
|
DRIVER_NAME("VENDOR")
|
||||||
.init = cush_init,
|
.init = cush_init,
|
||||||
@ -173,7 +177,7 @@ static usbh_class_driver_t const usbh_class_drivers[] =
|
|||||||
.xfer_cb = cush_isr,
|
.xfer_cb = cush_isr,
|
||||||
.close = cush_close
|
.close = cush_close
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) };
|
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) };
|
||||||
@ -233,8 +237,7 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE];
|
|||||||
// Control transfers: since most controllers do not support multiple control transfers
|
// Control transfers: since most controllers do not support multiple control transfers
|
||||||
// on multiple devices concurrently and control transfers are not used much except for
|
// on multiple devices concurrently and control transfers are not used much except for
|
||||||
// enumeration, we will only execute control transfers one at a time.
|
// enumeration, we will only execute control transfers one at a time.
|
||||||
CFG_TUH_MEM_SECTION struct
|
CFG_TUH_MEM_SECTION struct {
|
||||||
{
|
|
||||||
CFG_TUH_MEM_ALIGN tusb_control_request_t request;
|
CFG_TUH_MEM_ALIGN tusb_control_request_t request;
|
||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
tuh_xfer_cb_t complete_cb;
|
tuh_xfer_cb_t complete_cb;
|
||||||
@ -268,7 +271,7 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) {
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) {
|
TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) {
|
||||||
bool ret = osal_queue_send(_usbh_q, event, in_isr);
|
bool ret = osal_queue_send(_usbh_q, event, in_isr);
|
||||||
if (tuh_event_hook_cb) tuh_event_hook_cb(event->rhport, event->event_id, in_isr);
|
tuh_event_hook_cb(event->rhport, event->event_id, in_isr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,17 +370,14 @@ bool tuh_init(uint8_t controller_id) {
|
|||||||
tu_memclr(_usbh_devices, sizeof(_usbh_devices));
|
tu_memclr(_usbh_devices, sizeof(_usbh_devices));
|
||||||
tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer));
|
tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer));
|
||||||
|
|
||||||
for(uint8_t i=0; i<TOTAL_DEVICES; i++)
|
for(uint8_t i=0; i<TOTAL_DEVICES; i++) {
|
||||||
{
|
|
||||||
clear_device(&_usbh_devices[i]);
|
clear_device(&_usbh_devices[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class drivers
|
// Class drivers
|
||||||
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++)
|
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
|
||||||
{
|
usbh_class_driver_t const* driver = get_driver(drv_id);
|
||||||
usbh_class_driver_t const * driver = get_driver(drv_id);
|
if (driver) {
|
||||||
if ( driver )
|
|
||||||
{
|
|
||||||
TU_LOG_USBH("%s init\r\n", driver->name);
|
TU_LOG_USBH("%s init\r\n", driver->name);
|
||||||
driver->init();
|
driver->init();
|
||||||
}
|
}
|
||||||
@ -456,7 +456,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
|
|||||||
|
|
||||||
#if CFG_TUH_HUB
|
#if CFG_TUH_HUB
|
||||||
// TODO remove
|
// TODO remove
|
||||||
if ( event.connection.hub_addr != 0) {
|
if ( event.connection.hub_addr != 0 && event.connection.hub_port != 0) {
|
||||||
// done with hub, waiting for next data on status pipe
|
// done with hub, waiting for next data on status pipe
|
||||||
(void) hub_edpt_status_xfer( event.connection.hub_addr );
|
(void) hub_edpt_status_xfer( event.connection.hub_addr );
|
||||||
}
|
}
|
||||||
@ -545,8 +545,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
|
|||||||
// Control transfer
|
// Control transfer
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
static void _control_blocking_complete_cb(tuh_xfer_t* xfer)
|
static void _control_blocking_complete_cb(tuh_xfer_t* xfer) {
|
||||||
{
|
|
||||||
// update result
|
// update result
|
||||||
*((xfer_result_t*) xfer->user_data) = xfer->result;
|
*((xfer_result_t*) xfer->user_data) = xfer->result;
|
||||||
}
|
}
|
||||||
@ -625,21 +624,18 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage)
|
TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) {
|
||||||
{
|
|
||||||
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
|
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
|
||||||
_ctrl_xfer.stage = stage;
|
_ctrl_xfer.stage = stage;
|
||||||
(void) osal_mutex_unlock(_usbh_mutex);
|
(void) osal_mutex_unlock(_usbh_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _xfer_complete(uint8_t daddr, xfer_result_t result)
|
static void _xfer_complete(uint8_t daddr, xfer_result_t result) {
|
||||||
{
|
|
||||||
TU_LOG_USBH("\r\n");
|
TU_LOG_USBH("\r\n");
|
||||||
|
|
||||||
// duplicate xfer since user can execute control transfer within callback
|
// duplicate xfer since user can execute control transfer within callback
|
||||||
tusb_control_request_t const request = _ctrl_xfer.request;
|
tusb_control_request_t const request = _ctrl_xfer.request;
|
||||||
tuh_xfer_t xfer_temp =
|
tuh_xfer_t xfer_temp = {
|
||||||
{
|
|
||||||
.daddr = daddr,
|
.daddr = daddr,
|
||||||
.ep_addr = 0,
|
.ep_addr = 0,
|
||||||
.result = result,
|
.result = result,
|
||||||
@ -652,8 +648,7 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result)
|
|||||||
|
|
||||||
_set_control_xfer_stage(CONTROL_STAGE_IDLE);
|
_set_control_xfer_stage(CONTROL_STAGE_IDLE);
|
||||||
|
|
||||||
if (xfer_temp.complete_cb)
|
if (xfer_temp.complete_cb) {
|
||||||
{
|
|
||||||
xfer_temp.complete_cb(&xfer_temp);
|
xfer_temp.complete_cb(&xfer_temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,17 +705,16 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
|
|||||||
//
|
//
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
bool tuh_edpt_xfer(tuh_xfer_t* xfer)
|
bool tuh_edpt_xfer(tuh_xfer_t* xfer) {
|
||||||
{
|
uint8_t const daddr = xfer->daddr;
|
||||||
uint8_t const daddr = xfer->daddr;
|
|
||||||
uint8_t const ep_addr = xfer->ep_addr;
|
uint8_t const ep_addr = xfer->ep_addr;
|
||||||
|
|
||||||
TU_VERIFY(daddr && ep_addr);
|
TU_VERIFY(daddr && ep_addr);
|
||||||
|
|
||||||
TU_VERIFY(usbh_edpt_claim(daddr, ep_addr));
|
TU_VERIFY(usbh_edpt_claim(daddr, ep_addr));
|
||||||
|
|
||||||
if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) )
|
if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen,
|
||||||
{
|
xfer->complete_cb, xfer->user_data)) {
|
||||||
usbh_edpt_release(daddr, ep_addr);
|
usbh_edpt_release(daddr, ep_addr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr);
|
|||||||
TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr);
|
TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr);
|
||||||
|
|
||||||
// Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext()
|
// Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext()
|
||||||
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
|
void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// APPLICATION API
|
// APPLICATION API
|
||||||
|
@ -157,6 +157,7 @@ static ohci_ed_t * const p_ed_head[] =
|
|||||||
|
|
||||||
static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed);
|
static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed);
|
||||||
static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr);
|
static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr);
|
||||||
|
static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBH-HCD API
|
// USBH-HCD API
|
||||||
@ -345,7 +346,7 @@ static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes)
|
|||||||
tu_memclr(p_td, sizeof(ohci_gtd_t));
|
tu_memclr(p_td, sizeof(ohci_gtd_t));
|
||||||
|
|
||||||
p_td->used = 1;
|
p_td->used = 1;
|
||||||
p_td->expected_bytes = total_bytes;
|
gtd_get_extra_data(p_td)->expected_bytes = total_bytes;
|
||||||
|
|
||||||
p_td->buffer_rounding = 1; // less than queued length is not a error
|
p_td->buffer_rounding = 1; // less than queued length is not a error
|
||||||
p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
|
p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
|
||||||
@ -610,6 +611,15 @@ static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd) {
|
||||||
|
if ( gtd_is_control(gtd) ) {
|
||||||
|
uint8_t idx = ((uintptr_t)gtd - (uintptr_t)&ohci_data.control->gtd) / sizeof(ohci_data.control[0]);
|
||||||
|
return &ohci_data.gtd_extra_control[idx];
|
||||||
|
}else {
|
||||||
|
return &ohci_data.gtd_extra[gtd - ohci_data.gtd_pool];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer)
|
static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer)
|
||||||
{
|
{
|
||||||
// 5.2.9 OHCI sample code
|
// 5.2.9 OHCI sample code
|
||||||
@ -641,8 +651,7 @@ static void done_queue_isr(uint8_t hostid)
|
|||||||
if ( (qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) )
|
if ( (qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) )
|
||||||
{
|
{
|
||||||
ohci_ed_t * const ed = gtd_get_ed(qtd);
|
ohci_ed_t * const ed = gtd_get_ed(qtd);
|
||||||
|
uint32_t const xferred_bytes = gtd_get_extra_data(qtd)->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer);
|
||||||
uint32_t const xferred_bytes = qtd->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer);
|
|
||||||
|
|
||||||
// NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs.
|
// NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs.
|
||||||
// When there is a error resulting this ED is halted, and this EP still has other queued TD
|
// When there is a error resulting this ED is halted, and this EP still has other queued TD
|
||||||
@ -651,7 +660,7 @@ static void done_queue_isr(uint8_t hostid)
|
|||||||
// --> HC will not process Control list (due to service ratio when Bulk list not empty)
|
// --> HC will not process Control list (due to service ratio when Bulk list not empty)
|
||||||
// To walk-around this, the halted ED will have TailP = HeadP (empty list condition), when clearing halt
|
// To walk-around this, the halted ED will have TailP = HeadP (empty list condition), when clearing halt
|
||||||
// the TailP must be set back to NULL for processing remaining TDs
|
// the TailP must be set back to NULL for processing remaining TDs
|
||||||
if ((event != XFER_RESULT_SUCCESS))
|
if (event != XFER_RESULT_SUCCESS)
|
||||||
{
|
{
|
||||||
ed->td_tail &= 0x0Ful;
|
ed->td_tail &= 0x0Ful;
|
||||||
ed->td_tail |= tu_align16(ed->td_head.address); // mark halted EP as empty queue
|
ed->td_tail |= tu_align16(ed->td_head.address); // mark halted EP as empty queue
|
||||||
|
@ -45,6 +45,9 @@ enum {
|
|||||||
#define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
|
#define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX)
|
||||||
#define GTD_MAX ED_MAX
|
#define GTD_MAX ED_MAX
|
||||||
|
|
||||||
|
// tinyUSB's OHCI implementation caps number of EDs to 8 bits
|
||||||
|
TU_VERIFY_STATIC (ED_MAX <= 256, "Reduce CFG_TUH_DEVICE_MAX or CFG_TUH_ENDPOINT_MAX");
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// OHCI Data Structure
|
// OHCI Data Structure
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -70,9 +73,8 @@ 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 : 8; // endpoint index the gtd belongs to, or device address in case of control xfer
|
||||||
uint32_t expected_bytes : 13; // TODO available for hcd
|
uint32_t : 9; // can be used
|
||||||
|
|
||||||
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;
|
||||||
@ -152,9 +154,12 @@ typedef struct TU_ATTR_ALIGNED(32)
|
|||||||
|
|
||||||
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
|
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t expected_bytes; // up to 8192 bytes so max is 13 bits
|
||||||
|
} gtd_extra_data_t;
|
||||||
|
|
||||||
// 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)
|
||||||
@ -164,14 +169,17 @@ typedef struct TU_ATTR_ALIGNED(256)
|
|||||||
struct {
|
struct {
|
||||||
ohci_ed_t ed;
|
ohci_ed_t ed;
|
||||||
ohci_gtd_t gtd;
|
ohci_gtd_t gtd;
|
||||||
}control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1];
|
} control[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 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[ED_MAX];
|
ohci_ed_t ed_pool[ED_MAX];
|
||||||
ohci_gtd_t gtd_pool[GTD_MAX];
|
ohci_gtd_t gtd_pool[GTD_MAX];
|
||||||
|
|
||||||
volatile uint16_t frame_number_hi;
|
// extra data needed by TDs that can't fit in the TD struct
|
||||||
|
gtd_extra_data_t gtd_extra_control[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1];
|
||||||
|
gtd_extra_data_t gtd_extra[GTD_MAX];
|
||||||
|
|
||||||
|
volatile uint16_t frame_number_hi;
|
||||||
} ohci_data_t;
|
} ohci_data_t;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
@ -128,8 +128,8 @@
|
|||||||
# define DCD_STM32_BTABLE_BASE 0U
|
# define DCD_STM32_BTABLE_BASE 0U
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DCD_STM32_BTABLE_LENGTH
|
#ifndef DCD_STM32_BTABLE_SIZE
|
||||||
# define DCD_STM32_BTABLE_LENGTH (PMA_LENGTH - DCD_STM32_BTABLE_BASE)
|
# define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/***************************************************
|
/***************************************************
|
||||||
@ -137,7 +137,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware");
|
TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware");
|
||||||
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LENGTH), "BTABLE does not fit in PMA RAM");
|
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM");
|
||||||
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes");
|
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes");
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -559,7 +559,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
|
|||||||
// Must reset EP to NAK (in case it had been stalling) (though, maybe too late here)
|
// Must reset EP to NAK (in case it had been stalling) (though, maybe too late here)
|
||||||
pcd_set_ep_rx_status(USB,0u,USB_EP_RX_NAK);
|
pcd_set_ep_rx_status(USB,0u,USB_EP_RX_NAK);
|
||||||
pcd_set_ep_tx_status(USB,0u,USB_EP_TX_NAK);
|
pcd_set_ep_tx_status(USB,0u,USB_EP_TX_NAK);
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
dcd_event_setup_received(0, (uint8_t*)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true);
|
dcd_event_setup_received(0, (uint8_t*)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true);
|
||||||
#else
|
#else
|
||||||
// The setup_received function uses memcpy, so this must first copy the setup data into
|
// The setup_received function uses memcpy, so this must first copy the setup data into
|
||||||
@ -673,13 +673,13 @@ void dcd_int_handler(uint8_t rhport) {
|
|||||||
|
|
||||||
/* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */
|
/* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */
|
||||||
if(int_status & USB_ISTR_SOF) {
|
if(int_status & USB_ISTR_SOF) {
|
||||||
USB->ISTR &=~USB_ISTR_SOF;
|
USB->ISTR = (fsdev_bus_t)~USB_ISTR_SOF;
|
||||||
dcd_event_sof(0, USB->FNR & USB_FNR_FN, true);
|
dcd_event_sof(0, USB->FNR & USB_FNR_FN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(int_status & USB_ISTR_RESET) {
|
if(int_status & USB_ISTR_RESET) {
|
||||||
// USBRST is start of reset.
|
// USBRST is start of reset.
|
||||||
USB->ISTR &=~USB_ISTR_RESET;
|
USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET;
|
||||||
dcd_handle_bus_reset();
|
dcd_handle_bus_reset();
|
||||||
dcd_event_bus_reset(0, TUSB_SPEED_FULL, true);
|
dcd_event_bus_reset(0, TUSB_SPEED_FULL, true);
|
||||||
return; // Don't do the rest of the things here; perhaps they've been cleared?
|
return; // Don't do the rest of the things here; perhaps they've been cleared?
|
||||||
@ -697,7 +697,7 @@ void dcd_int_handler(uint8_t rhport) {
|
|||||||
USB->CNTR &= ~USB_CNTR_LPMODE;
|
USB->CNTR &= ~USB_CNTR_LPMODE;
|
||||||
USB->CNTR &= ~USB_CNTR_FSUSP;
|
USB->CNTR &= ~USB_CNTR_FSUSP;
|
||||||
|
|
||||||
USB->ISTR &=~USB_ISTR_WKUP;
|
USB->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP;
|
||||||
dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
|
dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,7 +711,7 @@ void dcd_int_handler(uint8_t rhport) {
|
|||||||
USB->CNTR |= USB_CNTR_LPMODE;
|
USB->CNTR |= USB_CNTR_LPMODE;
|
||||||
|
|
||||||
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
|
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
|
||||||
USB->ISTR &=~USB_ISTR_SUSP;
|
USB->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP;
|
||||||
dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
|
dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +724,7 @@ void dcd_int_handler(uint8_t rhport) {
|
|||||||
{
|
{
|
||||||
remoteWakeCountdown--;
|
remoteWakeCountdown--;
|
||||||
}
|
}
|
||||||
USB->ISTR &=~USB_ISTR_ESOF;
|
USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,7 +786,7 @@ static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure allocated buffer is aligned
|
// Ensure allocated buffer is aligned
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
length = (length + 3) & ~0x03;
|
length = (length + 3) & ~0x03;
|
||||||
#else
|
#else
|
||||||
length = (length + 1) & ~0x01;
|
length = (length + 1) & ~0x01;
|
||||||
@ -798,7 +798,7 @@ static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length)
|
|||||||
ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer
|
ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer
|
||||||
|
|
||||||
// Verify no overflow
|
// Verify no overflow
|
||||||
TU_ASSERT(ep_buf_ptr <= PMA_LENGTH, 0xFFFF);
|
TU_ASSERT(ep_buf_ptr <= FSDEV_PMA_SIZE, 0xFFFF);
|
||||||
|
|
||||||
epXferCtl->pma_ptr = addr;
|
epXferCtl->pma_ptr = addr;
|
||||||
epXferCtl->pma_alloc_size = length;
|
epXferCtl->pma_alloc_size = length;
|
||||||
@ -1227,7 +1227,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes)
|
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes)
|
||||||
{
|
{
|
||||||
const uint8_t* srcVal = src;
|
const uint8_t* srcVal = src;
|
||||||
@ -1283,7 +1283,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui
|
|||||||
__IO uint16_t *pdwVal;
|
__IO uint16_t *pdwVal;
|
||||||
|
|
||||||
srcVal = src;
|
srcVal = src;
|
||||||
pdwVal = &pma[PMA_STRIDE*(dst>>1)];
|
pdwVal = &pma[FSDEV_PMA_STRIDE * (dst >> 1)];
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
{
|
{
|
||||||
@ -1291,7 +1291,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui
|
|||||||
srcVal++;
|
srcVal++;
|
||||||
temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)) ;
|
temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)) ;
|
||||||
*pdwVal = temp2;
|
*pdwVal = temp2;
|
||||||
pdwVal += PMA_STRIDE;
|
pdwVal += FSDEV_PMA_STRIDE;
|
||||||
srcVal++;
|
srcVal++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1323,7 +1323,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN
|
|||||||
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
||||||
// last lin byte will be combined with wrapped part
|
// last lin byte will be combined with wrapped part
|
||||||
// To ensure PMA is always access aligned (dst aligned to 16 or 32 bit)
|
// To ensure PMA is always access aligned (dst aligned to 16 or 32 bit)
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
if((cnt_lin & 0x03) && cnt_wrap)
|
if((cnt_lin & 0x03) && cnt_wrap)
|
||||||
{
|
{
|
||||||
// Copy first linear part
|
// Copy first linear part
|
||||||
@ -1386,7 +1386,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes)
|
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes)
|
||||||
{
|
{
|
||||||
uint8_t* dstVal = dst;
|
uint8_t* dstVal = dst;
|
||||||
@ -1434,13 +1434,13 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t
|
|||||||
__IO const uint16_t *pdwVal;
|
__IO const uint16_t *pdwVal;
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
|
|
||||||
pdwVal = &pma[PMA_STRIDE*(src>>1)];
|
pdwVal = &pma[FSDEV_PMA_STRIDE * (src >> 1)];
|
||||||
uint8_t *dstVal = (uint8_t*)dst;
|
uint8_t *dstVal = (uint8_t*)dst;
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
{
|
{
|
||||||
temp = *pdwVal;
|
temp = *pdwVal;
|
||||||
pdwVal += PMA_STRIDE;
|
pdwVal += FSDEV_PMA_STRIDE;
|
||||||
*dstVal++ = ((temp >> 0) & 0xFF);
|
*dstVal++ = ((temp >> 0) & 0xFF);
|
||||||
*dstVal++ = ((temp >> 8) & 0xFF);
|
*dstVal++ = ((temp >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
@ -1448,7 +1448,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t
|
|||||||
if (wNBytes & 0x01)
|
if (wNBytes & 0x01)
|
||||||
{
|
{
|
||||||
temp = *pdwVal;
|
temp = *pdwVal;
|
||||||
pdwVal += PMA_STRIDE;
|
pdwVal += FSDEV_PMA_STRIDE;
|
||||||
*dstVal++ = ((temp >> 0) & 0xFF);
|
*dstVal++ = ((temp >> 0) & 0xFF);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1475,7 +1475,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB
|
|||||||
// We want to read from PMA and write it into the FIFO, if LIN part is ODD and has WRAPPED part,
|
// We want to read from PMA and write it into the FIFO, if LIN part is ODD and has WRAPPED part,
|
||||||
// last lin byte will be combined with wrapped part
|
// last lin byte will be combined with wrapped part
|
||||||
// To ensure PMA is always access aligned (src aligned to 16 or 32 bit)
|
// To ensure PMA is always access aligned (src aligned to 16 or 32 bit)
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
if((cnt_lin & 0x03) && cnt_wrap)
|
if((cnt_lin & 0x03) && cnt_wrap)
|
||||||
{
|
{
|
||||||
// Copy first linear part
|
// Copy first linear part
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
// This file contains source copied from ST's HAL, and thus should have their copyright statement.
|
// This file contains source copied from ST's HAL, and thus should have their copyright statement.
|
||||||
|
|
||||||
// PMA_LENGTH is PMA buffer size in bytes.
|
// FSDEV_PMA_SIZE is PMA buffer size in bytes.
|
||||||
// On 512-byte devices, access with a stride of two words (use every other 16-bit address)
|
// On 512-byte devices, access with a stride of two words (use every other 16-bit address)
|
||||||
// On 1024-byte devices, access with a stride of one word (use every 16-bit address)
|
// On 1024-byte devices, access with a stride of one word (use every 16-bit address)
|
||||||
|
|
||||||
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F0
|
#if CFG_TUSB_MCU == OPT_MCU_STM32F0
|
||||||
#include "stm32f0xx.h"
|
#include "stm32f0xx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
// F0x2 models are crystal-less
|
// F0x2 models are crystal-less
|
||||||
// All have internal D+ pull-up
|
// All have internal D+ pull-up
|
||||||
// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support
|
// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support
|
||||||
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
|
||||||
#include "stm32f1xx.h"
|
#include "stm32f1xx.h"
|
||||||
#define PMA_LENGTH (512u)
|
#define FSDEV_PMA_SIZE (512u)
|
||||||
// NO internal Pull-ups
|
// NO internal Pull-ups
|
||||||
// *B, and *C: 2 x 16 bits/word
|
// *B, and *C: 2 x 16 bits/word
|
||||||
|
|
||||||
@ -56,7 +56,7 @@
|
|||||||
defined(STM32F303xB) || defined(STM32F303xC) || \
|
defined(STM32F303xB) || defined(STM32F303xC) || \
|
||||||
defined(STM32F373xC)
|
defined(STM32F373xC)
|
||||||
#include "stm32f3xx.h"
|
#include "stm32f3xx.h"
|
||||||
#define PMA_LENGTH (512u)
|
#define FSDEV_PMA_SIZE (512u)
|
||||||
// NO internal Pull-ups
|
// NO internal Pull-ups
|
||||||
// *B, and *C: 1 x 16 bits/word
|
// *B, and *C: 1 x 16 bits/word
|
||||||
// PMA dedicated to USB (no sharing with CAN)
|
// PMA dedicated to USB (no sharing with CAN)
|
||||||
@ -65,27 +65,27 @@
|
|||||||
defined(STM32F302xD) || defined(STM32F302xE) || \
|
defined(STM32F302xD) || defined(STM32F302xE) || \
|
||||||
defined(STM32F303xD) || defined(STM32F303xE)
|
defined(STM32F303xD) || defined(STM32F303xE)
|
||||||
#include "stm32f3xx.h"
|
#include "stm32f3xx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
// NO internal Pull-ups
|
// NO internal Pull-ups
|
||||||
// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support
|
// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support
|
||||||
// When CAN clock is enabled, USB can use first 768 bytes ONLY.
|
// When CAN clock is enabled, USB can use first 768 bytes ONLY.
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
|
||||||
#include "stm32l0xx.h"
|
#include "stm32l0xx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
|
||||||
#include "stm32l1xx.h"
|
#include "stm32l1xx.h"
|
||||||
#define PMA_LENGTH (512u)
|
#define FSDEV_PMA_SIZE (512u)
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
|
||||||
#include "stm32g4xx.h"
|
#include "stm32g4xx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
|
||||||
#include "stm32g0xx.h"
|
#include "stm32g0xx.h"
|
||||||
#define PMA_32BIT_ACCESS
|
#define FSDEV_BUS_32BIT
|
||||||
#define PMA_LENGTH (2048u)
|
#define FSDEV_PMA_SIZE (2048u)
|
||||||
#undef USB_PMAADDR
|
#undef USB_PMAADDR
|
||||||
#define USB_PMAADDR USB_DRD_PMAADDR
|
#define USB_PMAADDR USB_DRD_PMAADDR
|
||||||
#define USB_TypeDef USB_DRD_TypeDef
|
#define USB_TypeDef USB_DRD_TypeDef
|
||||||
@ -112,8 +112,8 @@
|
|||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
|
||||||
#include "stm32h5xx.h"
|
#include "stm32h5xx.h"
|
||||||
#define PMA_32BIT_ACCESS
|
#define FSDEV_BUS_32BIT
|
||||||
#define PMA_LENGTH (2048u)
|
#define FSDEV_PMA_SIZE (2048u)
|
||||||
#undef USB_PMAADDR
|
#undef USB_PMAADDR
|
||||||
#define USB_PMAADDR USB_DRD_PMAADDR
|
#define USB_PMAADDR USB_DRD_PMAADDR
|
||||||
#define USB_TypeDef USB_DRD_TypeDef
|
#define USB_TypeDef USB_DRD_TypeDef
|
||||||
@ -141,18 +141,18 @@
|
|||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
|
||||||
#include "stm32wbxx.h"
|
#include "stm32wbxx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
/* ST provided header has incorrect value */
|
/* ST provided header has incorrect value */
|
||||||
#undef USB_PMAADDR
|
#undef USB_PMAADDR
|
||||||
#define USB_PMAADDR USB1_PMAADDR
|
#define USB_PMAADDR USB1_PMAADDR
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
|
||||||
#include "stm32l4xx.h"
|
#include "stm32l4xx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
|
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
|
||||||
#include "stm32l5xx.h"
|
#include "stm32l5xx.h"
|
||||||
#define PMA_LENGTH (1024u)
|
#define FSDEV_PMA_SIZE (1024u)
|
||||||
|
|
||||||
#ifndef USB_PMAADDR
|
#ifndef USB_PMAADDR
|
||||||
#define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
|
#define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
|
||||||
@ -164,24 +164,28 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For purposes of accessing the packet
|
// For purposes of accessing the packet
|
||||||
#if ((PMA_LENGTH) == 512u)
|
#if ((FSDEV_PMA_SIZE) == 512u)
|
||||||
#define PMA_STRIDE (2u)
|
#define FSDEV_PMA_STRIDE (2u)
|
||||||
#elif ((PMA_LENGTH) == 1024u)
|
#elif ((FSDEV_PMA_SIZE) == 1024u)
|
||||||
#define PMA_STRIDE (1u)
|
#define FSDEV_PMA_STRIDE (1u)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// The fsdev_bus_t type can be used for both register and PMA access necessities
|
||||||
// For type-safety create a new macro for the volatile address of PMAADDR
|
// For type-safety create a new macro for the volatile address of PMAADDR
|
||||||
// The compiler should warn us if we cast it to a non-volatile type?
|
// The compiler should warn us if we cast it to a non-volatile type?
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
|
typedef uint32_t fsdev_bus_t;
|
||||||
static __IO uint32_t * const pma32 = (__IO uint32_t*)USB_PMAADDR;
|
static __IO uint32_t * const pma32 = (__IO uint32_t*)USB_PMAADDR;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
typedef uint16_t fsdev_bus_t;
|
||||||
// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden)
|
// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden)
|
||||||
static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR;
|
static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR;
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x)
|
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x)
|
||||||
{
|
{
|
||||||
size_t total_word_offset = (((USBx)->BTABLE)>>1) + x;
|
size_t total_word_offset = (((USBx)->BTABLE)>>1) + x;
|
||||||
total_word_offset *= PMA_STRIDE;
|
total_word_offset *= FSDEV_PMA_STRIDE;
|
||||||
return &(pma[total_word_offset]);
|
return &(pma[total_word_offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +216,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t si
|
|||||||
/* SetENDPOINT */
|
/* SetENDPOINT */
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue)
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
__O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
__O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
||||||
*reg = wRegValue;
|
*reg = wRegValue;
|
||||||
@ -224,7 +228,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, ui
|
|||||||
|
|
||||||
/* GetENDPOINT */
|
/* GetENDPOINT */
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
__I uint32_t *reg = (__I uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
__I uint32_t *reg = (__I uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
||||||
#else
|
#else
|
||||||
@ -279,7 +283,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx,
|
|||||||
*/
|
*/
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx)
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
return (pma32[2*bEpIdx] & 0x03FF0000) >> 16;
|
return (pma32[2*bEpIdx] & 0x03FF0000) >> 16;
|
||||||
#else
|
#else
|
||||||
@ -290,7 +294,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USB
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx)
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16;
|
return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16;
|
||||||
#else
|
#else
|
||||||
@ -317,7 +321,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx,
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx)
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
return pma32[2*bEpIdx] & 0x0000FFFFu ;
|
return pma32[2*bEpIdx] & 0x0000FFFFu ;
|
||||||
#else
|
#else
|
||||||
@ -327,7 +331,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef *
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx)
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
return pma32[2*bEpIdx + 1] & 0x0000FFFFu;
|
return pma32[2*bEpIdx + 1] & 0x0000FFFFu;
|
||||||
#else
|
#else
|
||||||
@ -337,7 +341,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef *
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr)
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
||||||
#else
|
#else
|
||||||
@ -347,7 +351,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USB
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr)
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
||||||
#else
|
#else
|
||||||
@ -357,7 +361,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
|
pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
|
||||||
#else
|
#else
|
||||||
@ -368,7 +372,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, u
|
|||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
|
||||||
{
|
{
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
|
pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
|
||||||
#else
|
#else
|
||||||
@ -380,7 +384,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, u
|
|||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t blocksize, uint32_t numblocks)
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t blocksize, uint32_t numblocks)
|
||||||
{
|
{
|
||||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||||
#ifdef PMA_32BIT_ACCESS
|
#ifdef FSDEV_BUS_32BIT
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26);
|
pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26);
|
||||||
#else
|
#else
|
||||||
|
@ -149,7 +149,7 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) {
|
|||||||
// https://community.st.com/t5/stm32cubemx-mcus/why-stm32h743-usb-fs-doesn-t-work-if-freertos-tickless-idle/m-p/349480#M18867
|
// https://community.st.com/t5/stm32cubemx-mcus/why-stm32h743-usb-fs-doesn-t-work-if-freertos-tickless-idle/m-p/349480#M18867
|
||||||
// H7 running on full-speed phy need to disable ULPI clock in sleep mode.
|
// H7 running on full-speed phy need to disable ULPI clock in sleep mode.
|
||||||
// Otherwise, USB won't work when mcu executing WFI/WFE instruction i.e tick-less RTOS.
|
// Otherwise, USB won't work when mcu executing WFI/WFE instruction i.e tick-less RTOS.
|
||||||
// Note: there may be other family that is affected by this, but only H7 is tested so far
|
// Note: there may be other family that is affected by this, but only H7 and F7 is tested so far
|
||||||
#if defined(USB_OTG_FS_PERIPH_BASE) && defined(RCC_AHB1LPENR_USB2OTGFSULPILPEN)
|
#if defined(USB_OTG_FS_PERIPH_BASE) && defined(RCC_AHB1LPENR_USB2OTGFSULPILPEN)
|
||||||
if ( USB_OTG_FS_PERIPH_BASE == (uint32_t) dwc2 ) {
|
if ( USB_OTG_FS_PERIPH_BASE == (uint32_t) dwc2 ) {
|
||||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB2OTGFSULPILPEN;
|
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB2OTGFSULPILPEN;
|
||||||
@ -161,6 +161,13 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) {
|
|||||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB1OTGHSULPILPEN;
|
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB1OTGHSULPILPEN;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USB_OTG_HS_PERIPH_BASE) && defined(RCC_AHB1LPENR_OTGHSULPILPEN)
|
||||||
|
if ( USB_OTG_HS_PERIPH_BASE == (uint32_t) dwc2 ) {
|
||||||
|
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_OTGHSULPILPEN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
#if CFG_TUSB_MCU != OPT_MCU_STM32U5
|
#if CFG_TUSB_MCU != OPT_MCU_STM32U5
|
||||||
// Disable FS PHY, TODO on U5A5 (dwc2 4.11a) 16th bit is 'Host CDP behavior enable'
|
// Disable FS PHY, TODO on U5A5 (dwc2 4.11a) 16th bit is 'Host CDP behavior enable'
|
||||||
|
@ -453,10 +453,12 @@
|
|||||||
#define CFG_TUH_CDC_FTDI 0
|
#define CFG_TUH_CDC_FTDI 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUH_CDC_FTDI_PID_LIST
|
#ifndef CFG_TUH_CDC_FTDI_VID_PID_LIST
|
||||||
// List of product IDs that can use the FTDI CDC driver
|
// List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID
|
||||||
#define CFG_TUH_CDC_FTDI_PID_LIST \
|
#define CFG_TUH_CDC_FTDI_VID_PID_LIST \
|
||||||
0x6001, 0x6006, 0x6010, 0x6011, 0x6014, 0x6015, 0x8372, 0xFBFA, 0xCD18
|
{0x0403, 0x6001}, {0x0403, 0x6006}, {0x0403, 0x6010}, {0x0403, 0x6011}, \
|
||||||
|
{0x0403, 0x6014}, {0x0403, 0x6015}, {0x0403, 0x8372}, {0x0403, 0xFBFA}, \
|
||||||
|
{0x0403, 0xCD18}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUH_CDC_CP210X
|
#ifndef CFG_TUH_CDC_CP210X
|
||||||
@ -464,10 +466,27 @@
|
|||||||
#define CFG_TUH_CDC_CP210X 0
|
#define CFG_TUH_CDC_CP210X 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUH_CDC_CP210X_PID_LIST
|
#ifndef CFG_TUH_CDC_CP210X_VID_PID_LIST
|
||||||
// List of product IDs that can use the CP210X CDC driver
|
// List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID
|
||||||
#define CFG_TUH_CDC_CP210X_PID_LIST \
|
#define CFG_TUH_CDC_CP210X_VID_PID_LIST \
|
||||||
0xEA60, 0xEA70
|
{0x10C4, 0xEA60}, {0x10C4, 0xEA70}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUH_CDC_CH34X
|
||||||
|
// CH34X is not part of CDC class, only to re-use CDC driver API
|
||||||
|
#define CFG_TUH_CDC_CH34X 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUH_CDC_CH34X_VID_PID_LIST
|
||||||
|
// List of product IDs that can use the CH34X CDC driver
|
||||||
|
#define CFG_TUH_CDC_CH34X_VID_PID_LIST \
|
||||||
|
{ 0x1a86, 0x5523 }, /* ch341 chip */ \
|
||||||
|
{ 0x1a86, 0x7522 }, /* ch340k chip */ \
|
||||||
|
{ 0x1a86, 0x7523 }, /* ch340 chip */ \
|
||||||
|
{ 0x1a86, 0xe523 }, /* ch330 chip */ \
|
||||||
|
{ 0x4348, 0x5523 }, /* ch340 custom chip */ \
|
||||||
|
{ 0x2184, 0x0057 }, /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ \
|
||||||
|
{ 0x9986, 0x7523 } /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUH_HID
|
#ifndef CFG_TUH_HID
|
||||||
|
@ -364,8 +364,15 @@ def main(config_file, board):
|
|||||||
|
|
||||||
print(f' {test} ...', end='')
|
print(f' {test} ...', end='')
|
||||||
|
|
||||||
# flash firmware
|
# flash firmware. It may fail randomly, retry a few times
|
||||||
ret = globals()[f'flash_{flasher}'](item, fw)
|
for i in range(3):
|
||||||
|
ret = globals()[f'flash_{flasher}'](item, fw)
|
||||||
|
if ret.returncode == 0:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f'Flashing failed, retry {i+1}')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode()
|
assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode()
|
||||||
|
|
||||||
# run test
|
# run test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user