Merge pull request #1163 from hathach/generalize-synopsys-dwc2

Generalize synopsys dwc2
This commit is contained in:
Ha Thach 2021-11-04 13:41:25 +07:00 committed by GitHub
commit fc59515bfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 8193 additions and 1828 deletions

67
.github/workflows/build_aarch64.yml vendored Normal file
View File

@ -0,0 +1,67 @@
name: Build AArch64
on:
pull_request:
push:
release:
types:
- created
jobs:
# ---------------------------------------
# Build AARCH64 family
# ---------------------------------------
build-arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
family:
# Alphabetical order
- 'raspberrypi4'
steps:
- name: Setup Python
uses: actions/setup-python@v2
- name: Checkout TinyUSB
uses: actions/checkout@v2
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel
- name: Checkout hathach/linkermap
uses: actions/checkout@v2
with:
repository: hathach/linkermap
path: linkermap
- name: Set Toolchain URL
run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
- name: Cache Toolchain
uses: actions/cache@v2
id: cache-toolchain
with:
path: ~/cache/
key: ${{ runner.os }}-21-11-02-${{ env.TOOLCHAIN_URL }}
- name: Install Toolchain
if: steps.cache-toolchain.outputs.cache-hit != 'true'
run: |
mkdir -p ~/cache/toolchain
wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz
tar -C ~/cache/toolchain -xaf toolchain.tar.gz
- name: Set Toolchain Path
run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin`
- name: Build
run: python3 tools/build_family.py ${{ matrix.family }}
- name: Linker Map
run: |
pip install linkermap/
for ex in `ls -d examples/device/*/`; do \
find ${ex} -name *.map -print -quit | \
xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \
done

View File

@ -56,6 +56,7 @@ jobs:
- 'stm32f4'
- 'stm32f7'
- 'stm32h7'
- 'stm32l4'
steps:
- name: Setup Python
uses: actions/setup-python@v2

4
.gitmodules vendored
View File

@ -127,3 +127,7 @@
[submodule "hw/mcu/mindmotion/mm32sdk"]
path = hw/mcu/mindmotion/mm32sdk
url = https://github.com/hathach/mm32sdk.git
[submodule "hw/mcu/broadcom"]
path = hw/mcu/broadcom
url = https://github.com/adafruit/broadcom-peripherals.git
branch = main-build

View File

@ -35,7 +35,7 @@ The stack supports the following MCUs:
- **Dialog:** DA1469x
- **Espressif:** ESP32-S2, ESP32-S3
- **MicroChip:** SAMD11, SAMD21, SAMD51, SAME5x, SAMG55, SAML21, SAML22, SAME7x
- **NordicSemi:** nRF52833, nRF52840
- **NordicSemi:** nRF52833, nRF52840, nRF5340
- **Nuvoton:** NUC120, NUC121/NUC125, NUC126, NUC505
- **NXP:**
@ -45,9 +45,9 @@ The stack supports the following MCUs:
- **Raspberry Pi:** RP2040
- **Renesas:** RX63N, RX65N
- **Silabs:** EFM32GG12
- **Silabs:** EFM32GG
- **Sony:** CXD56
- **ST:** STM32 series: L0, L1, F0, F1, F2, F3, F4, F7, H7 both FullSpeed and HighSpeed
- **ST:** STM32 series: L0, L1, L4, L4+, F0, F1, F2, F3, F4, F7, H7
- **TI:** MSP430
- **ValentyUSB:** eptri

View File

@ -305,29 +305,58 @@ Sony
ST STM32
--------
- `Adafruit Feather STM32F405 <https://www.adafruit.com/product/4382>`__
- `Micro Python PyBoard v1.1 <https://store.micropython.org/product/PYBv1.1>`__
- `STLink-V3 Mini <https://www.st.com/en/development-tools/stlink-v3mini.html>`__
- `STM32 L035c8 Discovery <https://www.st.com/en/evaluation-tools/32l0538discovery.html>`__
- `STM32 L4R5zi Nucleo <https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html>`__
F0
^^
- `STM32 F070rb Nucleo <https://www.st.com/en/evaluation-tools/nucleo-f070rb.html>`__
- `STM32 F072 Evaluation <https://www.st.com/en/evaluation-tools/stm32072b-eval.html>`__
- `STM32 F072rb Discovery <https://www.st.com/en/evaluation-tools/32f072bdiscovery.html>`__
F1
^^
- `STM32 F103c8 Blue Pill <https://stm32-base.org/boards/STM32F103C8T6-Blue-Pill>`__
- `STM32 F103rc Mini v2.0 <https://stm32-base.org/boards/STM32F103RCT6-STM32-Mini-V2.0>`__
F2
^^
- `STM32 F207zg Nucleo <https://www.st.com/en/evaluation-tools/nucleo-f207zg.html>`__
F3
^^
- `STM32 F303vc Discovery <https://www.st.com/en/evaluation-tools/stm32f3discovery.html>`__
F4
^^
- `Adafruit Feather STM32F405 <https://www.adafruit.com/product/4382>`__
- `Micro Python PyBoard v1.1 <https://store.micropython.org/product/PYBv1.1>`__
- `STM32 F401cc Black Pill <https://stm32-base.org/boards/STM32F401CCU6-WeAct-Black-Pill-V1.2>`__
- `STM32 F407vg Discovery <https://www.st.com/en/evaluation-tools/stm32f4discovery.html>`__
- `STM32 F411ce Black Pill <https://www.adafruit.com/product/4877>`__
- `STM32 F411ve Discovery <https://www.st.com/en/evaluation-tools/32f411ediscovery.html>`__
- `STM32 F412zg Discovery <https://www.st.com/en/evaluation-tools/32f412gdiscovery.html>`__
- `STM32 F412zg Nucleo <https://www.st.com/en/evaluation-tools/nucleo-f412zg.html>`__
F7
^^
- `STLink-V3 Mini <https://www.st.com/en/development-tools/stlink-v3mini.html>`__
- `STM32 F723e Discovery <https://www.st.com/en/evaluation-tools/32f723ediscovery.html>`__
- `STM32 F746zg Nucleo <https://www.st.com/en/evaluation-tools/nucleo-f746zg.html>`__
- `STM32 F746g Discovery <https://www.st.com/en/evaluation-tools/32f746gdiscovery.html>`__
- `STM32 F767zi Nucleo <https://www.st.com/en/evaluation-tools/nucleo-f767zi.html>`__
- `STM32 F769i Discovery <https://www.st.com/en/evaluation-tools/32f769idiscovery.html>`__
L0
^^
- `STM32 L035c8 Discovery <https://www.st.com/en/evaluation-tools/32l0538discovery.html>`__
L4
^^
- `STM32 L476vg Discovery <https://www.st.com/en/evaluation-tools/32l476gdiscovery.html>`__
- `STM32 L4P5zg Nucleo <https://www.st.com/en/evaluation-tools/nucleo-l4p5zg.html>`__
- `STM32 L4R5zi Nucleo <https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html>`__
H7
^^
- `STM32 H743zi Nucleo <https://www.st.com/en/evaluation-tools/nucleo-h743zi.html>`__
- `STM32 H743i Evaluation <https://www.st.com/en/evaluation-tools/stm32h743i-eval.html>`__
- `STM32 H745i Discovery <https://www.st.com/en/evaluation-tools/stm32h745i-disco.html>`__

View File

@ -141,7 +141,7 @@ void tud_resume_cb(void)
void audio_task(void)
{
// Yet to be filled - e.g. put meas data into TX FIFOs etc.
asm("nop");
// asm("nop");
}
//--------------------------------------------------------------------+

View File

@ -81,12 +81,12 @@ enum
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN)
#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_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
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_AUDIO 0x03
#elif TU_CHECK_MCU(NRF5X)
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08
@ -96,11 +96,11 @@ enum
uint8_t const desc_configuration[] =
{
// Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN)
// Interface number, string index, EP Out & EP In address, EP size
TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN)
};
// Invoked when received GET CONFIGURATION DESCRIPTOR

View File

@ -142,7 +142,7 @@ void tud_resume_cb(void)
void audio_task(void)
{
// Yet to be filled - e.g. put meas data into TX FIFOs etc.
asm("nop");
// asm("nop");
}
//--------------------------------------------------------------------+

View File

@ -86,7 +86,7 @@ enum
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_AUDIO 0x03
#elif TU_CHECK_MCU(NRF5X)
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08

View File

@ -47,8 +47,8 @@
// RHPort max operational speed can defined by board.mk
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
#ifndef BOARD_DEVICE_RHPORT_SPEED
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X)
#if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\
TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711)
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
#else
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED

View File

@ -27,5 +27,5 @@ target_sources(${COMPONENT_TARGET} PUBLIC
"${TOP}/src/class/net/ncm_device.c"
"${TOP}/src/class/usbtmc/usbtmc_device.c"
"${TOP}/src/class/vendor/vendor_device.c"
"${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c"
"${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c"
)

View File

@ -30,7 +30,7 @@
#include "bsp/board.h"
#include "tusb.h"
#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
// ESP-IDF need "freertos/" prefix in include path.
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
#include "freertos/FreeRTOS.h"
@ -105,14 +105,14 @@ int main(void)
(void) xTaskCreateStatic( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
#if !( TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) )
#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
vTaskStartScheduler();
#endif
return 0;
}
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
void app_main(void)
{
main();

View File

@ -68,7 +68,7 @@
#define CFG_TUSB_OS OPT_OS_FREERTOS
// Espressif IDF requires "freertos/" prefix in include path
#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
#define CFG_TUSB_OS_INC_PATH freertos/
#endif

View File

@ -47,8 +47,8 @@
// RHPort max operational speed can defined by board.mk
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
#ifndef BOARD_DEVICE_RHPORT_SPEED
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X)
#if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\
TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711)
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
#else
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED

View File

@ -31,7 +31,7 @@
#include "tusb.h"
#include "usb_descriptors.h"
#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
// ESP-IDF need "freertos/" prefix in include path.
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
#include "freertos/FreeRTOS.h"
@ -105,14 +105,14 @@ int main(void)
(void) xTaskCreateStatic( hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef);
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
#if !( TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) )
#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
vTaskStartScheduler();
#endif
return 0;
}
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
void app_main(void)
{
main();

View File

@ -68,7 +68,7 @@
#define CFG_TUSB_OS OPT_OS_FREERTOS
// Espressif IDF requires "freertos/" prefix in include path
#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
#define CFG_TUSB_OS_INC_PATH freertos/
#endif

View File

@ -0,0 +1 @@
tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t'

View File

@ -77,12 +77,12 @@ uint8_t const * tud_descriptor_device_cb(void)
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_LEN)
#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_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
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
#define EPNUM_VIDEO_IN 0x83
#elif TU_CHECK_MCU(NRF5X)
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
// nRF5x ISO can only be endpoint 8
#define EPNUM_VIDEO_IN 0x88

View File

@ -96,7 +96,7 @@ void board_led_task(void)
TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count)
{
(void) fhdl;
SEGGER_RTT_Write(0, (char*) buf, (int) count);
SEGGER_RTT_Write(0, (const char*) buf, (int) count);
return count;
}

View File

@ -125,7 +125,7 @@
#elif CFG_TUSB_MCU == OPT_MCU_RP2040
#include "pico.h"
#elif CFG_TUSB_MCU == OPT_MCU_EFM32GG || CFG_TUSB_MCU == OPT_MCU_EFM32GG11 || CFG_TUSB_MCU == OPT_MCU_EFM32GG12
#elif CFG_TUSB_MCU == OPT_MCU_EFM32GG
#include "em_device.h"
#elif CFG_TUSB_MCU == OPT_MCU_RX63X || CFG_TUSB_MCU == OPT_MCU_RX65X

View File

@ -28,14 +28,13 @@ CFLAGS += \
-mstrict-align \
-nostdlib -nostartfiles \
-DCFG_TUSB_MCU=OPT_MCU_GD32VF103 \
-DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP \
-DGD32VF103
-DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP
# mcu driver cause following warnings
CFLAGS += -Wno-error=unused-parameter
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(GD32VF103_SDK_DRIVER)/gd32vf103_rcu.c \
$(GD32VF103_SDK_DRIVER)/gd32vf103_gpio.c \
$(GD32VF103_SDK_DRIVER)/Usb/gd32vf103_usb_hw.c \

View File

@ -0,0 +1,38 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020, 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
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@ -0,0 +1,144 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "bsp/board.h"
#include "board.h"
#include "broadcom/interrupts.h"
#include "broadcom/io.h"
#include "broadcom/mmu.h"
#include "broadcom/caches.h"
#include "broadcom/vcmailbox.h"
// LED
#define LED_PIN 18
#define LED_STATE_ON 1
// Button
#define BUTTON_PIN 16
#define BUTTON_STATE_ACTIVE 0
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void)
{
tud_int_handler(0);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_init(void)
{
setup_mmu_flat_map();
init_caches();
// LED
gpio_initOutputPinWithPullNone(LED_PIN);
board_led_write(true);
// Button
// TODO
// Uart
uart_init();
// Turn on USB peripheral.
vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true);
// Timer 1/1024 second tick
SYSTMR->CS_b.M1 = 1;
SYSTMR->C1 = SYSTMR->CLO + 977;
BP_EnableIRQ(TIMER_1_IRQn);
BP_SetPriority(USB_IRQn, 0x00);
BP_ClearPendingIRQ(USB_IRQn);
BP_EnableIRQ(USB_IRQn);
BP_EnableIRQs();
}
void board_led_write(bool state)
{
gpio_setPinOutputBool(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
uint32_t board_button_read(void)
{
return 0;
}
int board_uart_read(uint8_t* buf, int len)
{
(void) buf; (void) len;
return 0;
}
int board_uart_write(void const * buf, int len)
{
for (int i = 0; i < len; i++) {
const char* cbuf = buf;
while (!UART1->STAT_b.TX_READY) {}
if (cbuf[i] == '\n') {
UART1->IO = '\r';
while (!UART1->STAT_b.TX_READY) {}
}
UART1->IO = cbuf[i];
}
return len;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void TIMER_1_IRQHandler(void)
{
system_ticks++;
SYSTMR->C1 += 977;
SYSTMR->CS_b.M1 = 1;
}
uint32_t board_millis(void)
{
return system_ticks;
}
#endif
void HardFault_Handler (void)
{
// asm("bkpt");
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void)
{
}

View File

@ -0,0 +1,51 @@
MCU_DIR = hw/mcu/broadcom
DEPS_SUBMODULES += $(MCU_DIR)
include $(TOP)/$(BOARD_PATH)/board.mk
CC = clang
CFLAGS += \
-mcpu=cortex-a72 \
-Wall \
-O0 \
-ffreestanding \
-nostdlib \
-nostartfiles \
-std=c17 \
-mgeneral-regs-only \
-DCFG_TUSB_MCU=OPT_MCU_BCM2711
# mcu driver cause following warnings
CFLAGS += -Wno-error=cast-qual
SRC_C += \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(MCU_DIR)/broadcom/gen/interrupt_handlers.c \
$(MCU_DIR)/broadcom/interrupts.c \
$(MCU_DIR)/broadcom/io.c \
$(MCU_DIR)/broadcom/mmu.c \
$(MCU_DIR)/broadcom/caches.c \
$(MCU_DIR)/broadcom/vcmailbox.c
CROSS_COMPILE = aarch64-none-elf-
SKIP_NANOLIB = 1
LD_FILE = $(MCU_DIR)/broadcom/link.ld
INC += \
$(TOP)/$(BOARD_PATH) \
$(TOP)/$(MCU_DIR) \
$(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include
SRC_S += $(MCU_DIR)/broadcom/boot.S
$(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf
$(OBJCOPY) -O binary $^ $@
# Copy to kernel to netboot drive or SD card
# Change destinaation to fit your need
flash: $(BUILD)/kernel8.img
$(CP) $< /home/$(USER)/Documents/code/pi4_tinyusb/boot_cpy

View File

@ -8,7 +8,7 @@ CFLAGS += \
-D__STARTUP_CLEAR_BSS \
-D__START=main \
-DEFM32GG12B810F1024GM64 \
-DCFG_TUSB_MCU=OPT_MCU_EFM32GG12
-DCFG_TUSB_MCU=OPT_MCU_EFM32GG
# mcu driver cause following warnings
#CFLAGS += -Wno-error=unused-parameter
@ -24,7 +24,7 @@ LD_FILE = $(SILABS_CMSIS)/Source/GCC/$(SILABS_FAMILY).ld
SRC_C += \
$(SILABS_CMSIS)/Source/system_$(SILABS_FAMILY).c \
src/portable/silabs/efm32/dcd_efm32.c
src/portable/synopsys/dwc2/dcd_dwc2.c
SRC_S += \
$(SILABS_CMSIS)/Source/GCC/startup_$(SILABS_FAMILY).S
@ -34,12 +34,8 @@ INC += \
$(TOP)/$(SILABS_CMSIS)/Include \
$(TOP)/hw/bsp/$(BOARD)
# For TinyUSB port source
VENDOR = silabs
CHIP_FAMILY = efm32
# For freeRTOS port source
FREERTOS_PORT = ARM_CM4
FREERTOS_PORT = ARM_CM3
# For flash-jlink target
JLINK_DEVICE = EFM32GG12B810F1024

View File

@ -21,7 +21,7 @@ CFLAGS += -Wno-error=sign-compare
LD_FILE = hw/bsp/$(BOARD)/STM32F207ZGTx_FLASH.ld
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \

View File

@ -36,6 +36,11 @@ void OTG_FS_IRQHandler(void)
tud_int_handler(0);
}
void OTG_HS_IRQHandler(void)
{
tud_int_handler(1);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
@ -134,6 +139,8 @@ void board_init(void)
// Enable USB OTG clock
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
// __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
board_vbus_sense_init();
}

View File

@ -21,7 +21,7 @@ CFLAGS += \
CFLAGS += -Wno-error=cast-align
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \

View File

@ -10,3 +10,6 @@ SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f723xx.s
# flash target using on-board stlink
flash: flash-stlink
# For flash-jlink target
JLINK_DEVICE = stm32f723ie

View File

@ -8,5 +8,8 @@ CFLAGS += \
LD_FILE = $(BOARD_PATH)/STM32F767ZITx_FLASH.ld
SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f767xx.s
# For flash-jlink target
JLINK_DEVICE = stm32f767zi
# flash target using on-board stlink
flash: flash-stlink

View File

@ -34,7 +34,7 @@ endif
CFLAGS += -Wno-error=shadow -Wno-error=cast-align
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \

View File

@ -2,6 +2,7 @@ CFLAGS += -DSTM32H743xx -DHSE_VALUE=25000000
# Default is Highspeed port
PORT ?= 1
SPEED ?= high
SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h743xx.s
LD_FILE = $(BOARD_PATH)/stm32h743xx_flash.ld

View File

@ -19,18 +19,24 @@ CFLAGS += \
-DBOARD_DEVICE_RHPORT_NUM=$(PORT)
ifeq ($(PORT), 1)
CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED
$(info "PORT1 High Speed")
ifeq ($(SPEED), high)
CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED
$(info "Using OTG_HS in HighSpeed mode")
else
CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED
$(info "Using OTG_HS in FullSpeed mode")
endif
else
$(info "PORT0 Full Speed")
$(info "Using OTG_FS")
endif
# suppress warning caused by vendor mcu driver
CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align
# All source paths should be relative to the top level.
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \

View File

@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
* Copyright (c) 2020, 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
@ -24,21 +24,12 @@
* This file is part of the TinyUSB stack.
*/
#include "../board.h"
#ifndef BOARD_H_
#define BOARD_H_
#include "stm32l4xx_hal.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void OTG_FS_IRQHandler(void)
{
tud_int_handler(0);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
#ifdef __cplusplus
extern "C" {
#endif
#define LED_PORT GPIOB
#define LED_PIN GPIO_PIN_2
@ -48,15 +39,16 @@ void OTG_FS_IRQHandler(void)
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_STATE_ACTIVE 1
#define UART_DEV USART2
#define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE
#define UART_GPIO_PORT GPIOD
#define UART_GPIO_AF GPIO_AF7_USART2
#define UART_TX_PIN GPIO_PIN_5
#define UART_RX_PIN GPIO_PIN_6
// enable all LED, Button, Uart, USB clock
static void all_rcc_clk_enable(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D-, Button
__HAL_RCC_GPIOB_CLK_ENABLE(); // LED
__HAL_RCC_GPIOC_CLK_ENABLE(); // VBUS pin
}
//--------------------------------------------------------------------+
// RCC Clock
//--------------------------------------------------------------------+
/**
* @brief System Clock Configuration
@ -80,7 +72,7 @@ static void all_rcc_clk_enable(void)
* @param None
* @retval None
*/
static void SystemClock_Config(void)
static inline void board_clock_init(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
@ -131,112 +123,17 @@ static void SystemClock_Config(void)
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
}
void board_init(void)
static inline void board_vbus_sense_init(void)
{
SystemClock_Config();
all_rcc_clk_enable();
// L476Disco use general GPIO PC11 for VBUS sensing instead of dedicated PA9 as others
// Disable VBUS Sense and force device mode
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
//NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN | USB_OTG_GOTGCTL_BVALOVAL;
}
#ifdef __cplusplus
}
#endif
/* Enable Power Clock*/
__HAL_RCC_PWR_CLK_ENABLE();
/* Enable USB power on Pwrctrl CR2 register */
HAL_PWREx_EnableVddUSB();
GPIO_InitTypeDef GPIO_InitStruct;
// LED
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
board_led_write(false);
// Button
GPIO_InitStruct.Pin = BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
// USB
/* Configure DM DP Pins */
GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure VBUS Pin */
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* Enable USB FS Clock */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
// Enable VBUS sense (B device) via pin PA9
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN;
}
//--------------------------------------------------------------------+
// board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state)
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
uint32_t board_button_read(void)
{
return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
}
int board_uart_read(uint8_t* buf, int len)
{
(void) buf; (void) len;
return 0;
}
int board_uart_write(void const * buf, int len)
{
(void) buf; (void) len;
return 0;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler (void)
{
system_ticks++;
}
uint32_t board_millis(void)
{
return system_ticks;
}
#endif
void HardFault_Handler (void)
{
asm("bkpt");
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void)
{
}
#endif /* BOARD_H_ */

View File

@ -0,0 +1,10 @@
CFLAGS += \
-DSTM32L476xx \
# All source paths should be relative to the top level.
LD_FILE = $(BOARD_PATH)/STM32L476VGTx_FLASH.ld
SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l476xx.s
# For flash-jlink target
JLINK_DEVICE = stm32l476vg

View File

@ -0,0 +1,200 @@
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : Auto-generated by STM32CubeIDE
**
** Abstract : Linker script for STM32L4P5ZGTx Device from STM32L4PLUS series
** 1024Kbytes ROM
** 320Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** 1. Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** 3. Neither the name of STMicroelectronics nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
}
/* Sections */
SECTIONS
{
/* The startup code into "ROM" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >ROM
/* The program code and other data into "ROM" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >ROM
/* Constant data into "ROM" Rom type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >ROM
.ARM.extab : {
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >ROM
.ARM : {
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >ROM
.preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >ROM
.init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >ROM
.fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >ROM
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> ROM
/* Uninitialized data section into "RAM" Ram type memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -0,0 +1,137 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020, 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 GPIOB
#define LED_PIN GPIO_PIN_14
#define LED_STATE_ON 1
#define BUTTON_PORT GPIOC
#define BUTTON_PIN GPIO_PIN_13
#define BUTTON_STATE_ACTIVE 1
#define UART_DEV LPUART1
#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE
#define UART_GPIO_PORT GPIOG
#define UART_GPIO_AF GPIO_AF8_LPUART1
#define UART_TX_PIN GPIO_PIN_7
#define UART_RX_PIN GPIO_PIN_8
//--------------------------------------------------------------------+
// RCC Clock
//--------------------------------------------------------------------+
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (MSI)
* SYSCLK(Hz) = 120000000
* HCLK(Hz) = 120000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 1
* MSI Frequency(Hz) = 48000000
* PLL_M = 12
* PLL_N = 60
* PLL_P = 2
* PLL_Q = 2
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* The USB clock configuration from PLLSAI:
* PLLSAIP = 8 FIXME
* PLLSAIN = 384 FIXME
* PLLSAIQ = 7 FIXME
* @param None
* @retval None
*/
static inline void board_clock_init(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* Activate PLL with MSI , stabilizied via PLL by LSE */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 12;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Enable MSI Auto-calibration through LSE */
HAL_RCCEx_EnableMSIPLLMode();
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
// Avoid overshoot and start with HCLK 60 MHz
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
/* AHB prescaler divider at 1 as second step */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
static inline void board_vbus_sense_init(void)
{
// Enable VBUS sense (B device) via pin PA9
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN;
}
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@ -0,0 +1,10 @@
CFLAGS += \
-DSTM32L4P5xx \
# All source paths should be relative to the top level.
LD_FILE = $(BOARD_PATH)/STM32L4P5ZGTX_FLASH.ld
SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4p5xx.s
# For flash-jlink target
JLINK_DEVICE = stm32l4p5zg

View File

@ -0,0 +1,137 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020, 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 GPIOB
#define LED_PIN GPIO_PIN_14
#define LED_STATE_ON 1
#define BUTTON_PORT GPIOC
#define BUTTON_PIN GPIO_PIN_13
#define BUTTON_STATE_ACTIVE 1
#define UART_DEV LPUART1
#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE
#define UART_GPIO_PORT GPIOG
#define UART_GPIO_AF GPIO_AF8_LPUART1
#define UART_TX_PIN GPIO_PIN_7
#define UART_RX_PIN GPIO_PIN_8
//--------------------------------------------------------------------+
// RCC Clock
//--------------------------------------------------------------------+
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (MSI)
* SYSCLK(Hz) = 120000000
* HCLK(Hz) = 120000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 1
* MSI Frequency(Hz) = 48000000
* PLL_M = 12
* PLL_N = 60
* PLL_P = 2
* PLL_Q = 2
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* The USB clock configuration from PLLSAI:
* PLLSAIP = 8 FIXME
* PLLSAIN = 384 FIXME
* PLLSAIQ = 7 FIXME
* @param None
* @retval None
*/
static inline void board_clock_init(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* Activate PLL with MSI , stabilizied via PLL by LSE */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 12;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Enable MSI Auto-calibration through LSE */
HAL_RCCEx_EnableMSIPLLMode();
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
// Avoid overshoot and start with HCLK 60 MHz
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
/* AHB prescaler divider at 1 as second step */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
static inline void board_vbus_sense_init(void)
{
// Enable VBUS sense (B device) via pin PA9
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN;
}
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@ -0,0 +1,14 @@
CFLAGS += \
-DHSE_VALUE=8000000 \
-DSTM32L4R5xx \
# All source paths should be relative to the top level.
LD_FILE = $(BOARD_PATH)/STM32L4RXxI_FLASH.ld
SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4r5xx.s
# For flash-jlink target
JLINK_DEVICE = stm32l4r5zi
# flash target using on-board stlink
flash: flash-stlink

View File

@ -26,9 +26,9 @@
* This file is part of the TinyUSB stack.
*/
#include "../board.h"
#include "stm32l4xx_hal.h"
#include "bsp/board.h"
#include "board.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
@ -42,119 +42,22 @@ void OTG_FS_IRQHandler(void)
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
#define LED_PORT GPIOB
#define LED_PIN GPIO_PIN_14
#define LED_STATE_ON 1
#define BUTTON_PORT GPIOC
#define BUTTON_PIN GPIO_PIN_13
#define BUTTON_STATE_ACTIVE 1
#define UARTx LPUART1
#define UART_GPIO_PORT GPIOG
#define UART_GPIO_AF GPIO_AF8_LPUART1
#define UART_TX_PIN GPIO_PIN_7
#define UART_RX_PIN GPIO_PIN_8
UART_HandleTypeDef UartHandle;
// enable all LED, Button, Uart, USB clock
static void all_rcc_clk_enable(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D-
__HAL_RCC_GPIOB_CLK_ENABLE(); // LED
__HAL_RCC_GPIOC_CLK_ENABLE(); // Button
__HAL_RCC_GPIOG_CLK_ENABLE(); // Uart TX, RX
__HAL_RCC_LPUART1_CLK_ENABLE(); // LPUart1 module
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (MSI)
* SYSCLK(Hz) = 120000000
* HCLK(Hz) = 120000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 1
* MSI Frequency(Hz) = 48000000
* PLL_M = 12
* PLL_N = 60
* PLL_P = 2
* PLL_Q = 2
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* The USB clock configuration from PLLSAI:
* PLLSAIP = 8 FIXME
* PLLSAIN = 384 FIXME
* PLLSAIQ = 7 FIXME
* @param None
* @retval None
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* Activate PLL with MSI , stabilizied via PLL by LSE */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 12;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Enable MSI Auto-calibration through LSE */
HAL_RCCEx_EnableMSIPLLMode();
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select MSI output as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
// Avoid overshoot and start with HCLK 60 MHz
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
/* AHB prescaler divider at 1 as second step */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
void board_init(void)
{
/* Enable Power Clock*/
__HAL_RCC_PWR_CLK_ENABLE();
/* Enable voltage range 1 boost mode for frequency above 80 Mhz */
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
board_clock_init();
/* Set tick interrupt priority, default HAL value is intentionally invalid
and that prevents PLL initialization in HAL_RCC_OscConfig() */
HAL_InitTick((1UL << __NVIC_PRIO_BITS) - 1UL);
SystemClock_Config();
all_rcc_clk_enable();
// Enable All GPIOs clocks
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
UART_CLK_EN();
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
@ -164,6 +67,15 @@ void board_init(void)
//NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
#endif
/* Enable USB power on Pwrctrl CR2 register */
/* Enable Power Clock*/
__HAL_RCC_PWR_CLK_ENABLE();
#if defined(PWR_CR5_R1MODE)
/* Enable voltage range 1 boost mode for frequency above 80 Mhz */
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
#endif
/* Enable USB power on Pwrctrl CR2 register */
HAL_PWREx_EnableVddUSB();
@ -192,7 +104,7 @@ void board_init(void)
GPIO_InitStruct.Alternate = UART_GPIO_AF;
HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct);
UartHandle.Instance = UARTx;
UartHandle.Instance = UART_DEV;
UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
@ -201,7 +113,7 @@ void board_init(void)
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1;
//UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1;
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&UartHandle);
@ -231,8 +143,7 @@ void board_init(void)
/* Enable USB FS Clocks */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
// Enable VBUS sense (B device) via pin PA9
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN;
board_vbus_sense_init();
}
//--------------------------------------------------------------------+

View File

@ -4,6 +4,8 @@ DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm
ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY)
ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver
include $(TOP)/$(BOARD_PATH)/board.mk
CFLAGS += \
-flto \
-mthumb \
@ -12,18 +14,14 @@ CFLAGS += \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16 \
-nostdlib -nostartfiles \
-DHSE_VALUE=8000000 \
-DSTM32L4R5xx \
-DCFG_TUSB_MCU=OPT_MCU_STM32L4
# suppress warning caused by vendor mcu driver
CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align
# All source paths should be relative to the top level.
LD_FILE = hw/bsp/$(BOARD)/STM32L4RXxI_FLASH.ld
#src/portable/st/synopsys/dcd_synopsys.c
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
@ -34,14 +32,11 @@ SRC_C += \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c
SRC_S += \
$(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4r5xx.s
INC += \
$(TOP)/lib/CMSIS_5/CMSIS/Core/Include \
$(TOP)/$(ST_CMSIS)/Include \
$(TOP)/$(ST_HAL_DRIVER)/Inc \
$(TOP)/hw/bsp/$(BOARD)
$(TOP)/$(BOARD_PATH)
# For freeRTOS port source
FREERTOS_PORT = ARM_CM4F

View File

@ -1,56 +0,0 @@
ST_FAMILY = l4
DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver
ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY)
ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver
CFLAGS += \
-flto \
-mthumb \
-mabi=aapcs \
-mcpu=cortex-m4 \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16 \
-nostdlib -nostartfiles \
-DSTM32L476xx \
-DCFG_TUSB_MCU=OPT_MCU_STM32L4
# suppress warning caused by vendor mcu driver
CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align
# All source paths should be relative to the top level.
LD_FILE = hw/bsp/$(BOARD)/STM32L476VGTx_FLASH.ld
SRC_C += \
src/portable/st/synopsys/dcd_synopsys.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c
SRC_S += \
$(ST_CMSIS)/Source/Templates/gcc/startup_stm32l476xx.s
INC += \
$(TOP)/lib/CMSIS_5/CMSIS/Core/Include \
$(TOP)/$(ST_CMSIS)/Include \
$(TOP)/$(ST_HAL_DRIVER)/Inc \
$(TOP)/hw/bsp/$(BOARD)
# For freeRTOS port source
FREERTOS_PORT = ARM_CM4F
# For flash-jlink target
JLINK_DEVICE = stm32l476vg
# Path to STM32 Cube Programmer CLI, should be added into system path
STM32Prog = STM32_Programmer_CLI
# flash target using on-board stlink
flash: $(BUILD)/$(PROJECT).elf
$(STM32Prog) --connect port=swd --write $< --go

View File

@ -1,419 +0,0 @@
/**
******************************************************************************
* @file stm32l4xx_hal_conf.h
* @author MCD Application Team
* @brief HAL configuration template file.
* This file should be copied to the application folder and renamed
* to stm32l4xx_hal_conf.h.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L4xx_HAL_CONF_H
#define __STM32L4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CAN_MODULE_ENABLED */
/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
/* #define HAL_COMP_MODULE_ENABLED */
#define HAL_CORTEX_MODULE_ENABLED
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_DFSDM_MODULE_ENABLED */
#define HAL_DMA_MODULE_ENABLED
/* #define HAL_FIREWALL_MODULE_ENABLED */
#define HAL_FLASH_MODULE_ENABLED
/* #define HAL_NAND_MODULE_ENABLED */
// #define HAL_NOR_MODULE_ENABLED
// #define HAL_SRAM_MODULE_ENABLED
/* #define HAL_HCD_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
//#define HAL_I2C_MODULE_ENABLED
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
//#define HAL_LCD_MODULE_ENABLED
/* #define HAL_LPTIM_MODULE_ENABLED */
/* #define HAL_OPAMP_MODULE_ENABLED */
//#define HAL_PCD_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
/* #define HAL_QSPI_MODULE_ENABLED */
#define HAL_RCC_MODULE_ENABLED
/* #define HAL_RNG_MODULE_ENABLED */
/* #define HAL_RTC_MODULE_ENABLED */
//#define HAL_SAI_MODULE_ENABLED
//#define HAL_SD_MODULE_ENABLED
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_SWPMI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
/* #define HAL_TSC_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal Multiple Speed oscillator (MSI) default value.
* This value is the default MSI range value after Reset.
*/
#if !defined (MSI_VALUE)
#define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG.
* This internal oscillator is mainly dedicated to provide a high precision clock to
* the USB peripheral by means of a special Clock Recovery System (CRS) circuitry.
* When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
* which is subject to manufacturing process variations.
*/
#if !defined (HSI48_VALUE)
#define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz.
The real value my vary depending on manufacturing process variations.*/
#endif /* HSI48_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for SAI1 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
#define EXTERNAL_SAI1_CLOCK_VALUE 48000U /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/**
* @brief External clock source for SAI2 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI2_CLOCK_VALUE)
#define EXTERNAL_SAI2_CLOCK_VALUE 48000U /*!< Value of the SAI2 External clock source in Hz*/
#endif /* EXTERNAL_SAI2_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 0U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */
#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 1U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32l4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32l4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32l4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
#include "stm32l4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32l4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32l4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32l4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
#include "Legacy/stm32l4xx_hal_can_legacy.h"
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32l4xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32l4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32l4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32l4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_FIREWALL_MODULE_ENABLED
#include "stm32l4xx_hal_firewall.h"
#endif /* HAL_FIREWALL_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32l4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32l4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32l4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32l4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32l4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32l4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LCD_MODULE_ENABLED
#include "stm32l4xx_hal_lcd.h"
#endif /* HAL_LCD_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32l4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_OPAMP_MODULE_ENABLED
#include "stm32l4xx_hal_opamp.h"
#endif /* HAL_OPAMP_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32l4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32l4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32l4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32l4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32l4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32l4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32l4xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32l4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_SWPMI_MODULE_ENABLED
#include "stm32l4xx_hal_swpmi.h"
#endif /* HAL_SWPMI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32l4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED
#include "stm32l4xx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32l4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32l4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32l4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32l4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32l4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32l4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32l4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t *file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32L4xx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

1
hw/mcu/broadcom Submodule

@ -0,0 +1 @@
Subproject commit d126323fc77e81d1f18677a439685a4754ea02aa

View File

@ -481,7 +481,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if (p_cbw->total_bytes)
{
// 6.7 The 13 Cases: case 4 (Hi > Dn)
TU_LOG(MSC_DEBUG, " SCSI case 4 (Hi > Dn): %lu\r\n", p_cbw->total_bytes);
// TU_LOG(MSC_DEBUG, " SCSI case 4 (Hi > Dn): %lu\r\n", p_cbw->total_bytes);
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
}else
{
@ -494,7 +494,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if ( p_cbw->total_bytes == 0 )
{
// 6.7 The 13 Cases: case 2 (Hn < Di)
TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di): %lu\r\n", p_cbw->total_bytes);
// TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di): %lu\r\n", p_cbw->total_bytes);
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
}else
{
@ -609,7 +609,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if ( (p_cbw->total_bytes > p_msc->xferred_len) && is_data_in(p_cbw->dir) )
{
// 6.7 The 13 Cases: case 5 (Hi > Di): STALL before status
TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len);
// TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len);
usbd_edpt_stall(rhport, p_msc->ep_in);
}else
{
@ -617,7 +617,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
}
}
#if TU_CHECK_MCU(CXD56)
#if TU_CHECK_MCU(OPT_MCU_CXD56)
// WORKAROUND: cxd56 has its own nuttx usb stack which does not forward Set/ClearFeature(Endpoint) to DCD.
// There is no way for us to know when EP is un-stall, therefore we will unconditionally un-stall here and
// hope everything will work

View File

@ -111,6 +111,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t ui32) { return (uint16_t) (ui32 >> 16); }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t ui32) { return (uint16_t) (ui32 & 0x0000ffffu); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); }
@ -235,37 +238,6 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, ui
#endif
/*------------------------------------------------------------------*/
/* Count number of arguments of __VA_ARGS__
* - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s
* - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
* - _RSEQ_N() is reverse sequential to N to add padding to have
* Nth position is the same as the number of arguments
* - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
*------------------------------------------------------------------*/
#ifndef TU_ARGS_NUM
#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N())
#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__)
#define _GET_NTH_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define _RSEQ_N() \
62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#endif
// To be removed
//------------- Binary constant -------------//
#if defined(__GNUC__) && !defined(__CC_ARM)
@ -334,8 +306,8 @@ void tu_print_var(uint8_t const* buf, uint32_t bufsize)
#define TU_LOG1 tu_printf
#define TU_LOG1_MEM tu_print_mem
#define TU_LOG1_VAR(_x) tu_print_var((uint8_t const*)(_x), sizeof(*(_x)))
#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (uint32_t) (_x) )
#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (uint32_t) (_x) )
#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) )
#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) )
// Log Level 2: Warn
#if CFG_TUSB_DEBUG >= 2

View File

@ -67,6 +67,46 @@
#define TU_LITTLE_ENDIAN (0x12u)
#define TU_BIG_ENDIAN (0x21u)
/*------------------------------------------------------------------*/
/* Count number of arguments of __VA_ARGS__
* - reference https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
* - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
* - _RSEQ_N() is reverse sequential to N to add padding to have
* Nth position is the same as the number of arguments
* - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
*------------------------------------------------------------------*/
#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N())
#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__)
#define _GET_NTH_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define _RSEQ_N() \
62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
// Apply an macro X to each of the arguments with an separated of choice
#define TU_ARGS_APPLY(_X, _s, ...) TU_XSTRCAT(_TU_ARGS_APPLY_, TU_ARGS_NUM(__VA_ARGS__))(_X, _s, __VA_ARGS__)
#define _TU_ARGS_APPLY_1(_X, _s, _a1) _X(_a1)
#define _TU_ARGS_APPLY_2(_X, _s, _a1, _a2) _X(_a1) _s _X(_a2)
#define _TU_ARGS_APPLY_3(_X, _s, _a1, _a2, _a3) _X(_a1) _s _TU_ARGS_APPLY_2(_X, _s, _a2, _a3)
#define _TU_ARGS_APPLY_4(_X, _s, _a1, _a2, _a3, _a4) _X(_a1) _s _TU_ARGS_APPLY_3(_X, _s, _a2, _a3, _a4)
#define _TU_ARGS_APPLY_5(_X, _s, _a1, _a2, _a3, _a4, _a5) _X(_a1) _s _TU_ARGS_APPLY_4(_X, _s, _a2, _a3, _a4, _a5)
#define _TU_ARGS_APPLY_6(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1) _s _TU_ARGS_APPLY_5(_X, _s, _a2, _a3, _a4, _a5, _a6)
#define _TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s _TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7)
#define _TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s _TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8)
//--------------------------------------------------------------------+
// Compiler porting with Attribute and Endian
//--------------------------------------------------------------------+

View File

@ -47,8 +47,8 @@
typedef enum
{
TUSB_SPEED_FULL = 0,
TUSB_SPEED_LOW ,
TUSB_SPEED_HIGH,
TUSB_SPEED_LOW = 1,
TUSB_SPEED_HIGH = 2,
TUSB_SPEED_INVALID = 0xff,
}tusb_speed_t;

View File

@ -36,124 +36,155 @@
// - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on.
//------------- NXP -------------//
#if TU_CHECK_MCU(LPC11UXX) || TU_CHECK_MCU(LPC13XX) || TU_CHECK_MCU(LPC15XX)
#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX)
#define DCD_ATTR_ENDPOINT_MAX 5
#elif TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX)
#elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
#define DCD_ATTR_ENDPOINT_MAX 16
#elif TU_CHECK_MCU(LPC18XX) || TU_CHECK_MCU(LPC43XX)
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
// TODO USB0 has 6, USB1 has 4
#define DCD_ATTR_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(LPC51UXX)
#elif TU_CHECK_MCU(OPT_MCU_LPC51UXX)
#define DCD_ATTR_ENDPOINT_MAX 5
#elif TU_CHECK_MCU(LPC54XXX)
#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX)
// TODO USB0 has 5, USB1 has 6
#define DCD_ATTR_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(LPC55XX)
#elif TU_CHECK_MCU(OPT_MCU_LPC55XX)
// TODO USB0 has 5, USB1 has 6
#define DCD_ATTR_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(MIMXRT10XX)
#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(MKL25ZXX) || TU_CHECK_MCU(K32L2BXX)
#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX)
#define DCD_ATTR_ENDPOINT_MAX 16
#elif TU_CHECK_MCU(MM32F327X)
#elif TU_CHECK_MCU(OPT_MCU_MM32F327X)
#define DCD_ATTR_ENDPOINT_MAX 16
//------------- Nordic -------------//
#elif TU_CHECK_MCU(NRF5X)
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
// 8 CBI + 1 ISO
#define DCD_ATTR_ENDPOINT_MAX 9
//------------- Microchip -------------//
#elif TU_CHECK_MCU(SAMD21) || TU_CHECK_MCU(SAMD51) || TU_CHECK_MCU(SAME5X) || \
TU_CHECK_MCU(SAMD11) || TU_CHECK_MCU(SAML21) || TU_CHECK_MCU(SAML22)
#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \
TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(SAMG)
#elif TU_CHECK_MCU(OPT_MCU_SAMG)
#define DCD_ATTR_ENDPOINT_MAX 6
#define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER
#elif TU_CHECK_MCU(SAMX7X)
#elif TU_CHECK_MCU(OPT_MCU_SAMX7X)
#define DCD_ATTR_ENDPOINT_MAX 10
#define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER
//------------- ST -------------//
#elif TU_CHECK_MCU(STM32F0) || TU_CHECK_MCU(STM32F1) || TU_CHECK_MCU(STM32F3) || \
TU_CHECK_MCU(STM32L0) || TU_CHECK_MCU(STM32L1) || TU_CHECK_MCU(STM32L4)
// F1: F102, F103
// L4: L4x2, L4x3
#elif TU_CHECK_MCU(OPT_MCU_STM32F0)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(STM32F2) || TU_CHECK_MCU(STM32F4) || TU_CHECK_MCU(STM32F3)
// F1: F105, F107 only has 4
// L4: L4x5, L4x6 has 6
// For most mcu, FS has 4, HS has 6
#define DCD_ATTR_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(OPT_MCU_STM32F1)
#if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \
defined (STM32F107xB) || defined (STM32F107xC)
#define DCD_ATTR_ENDPOINT_MAX 4
#define DCD_ATTR_DWC2_STM32
#else
#define DCD_ATTR_ENDPOINT_MAX 8
#endif
#elif TU_CHECK_MCU(STM32F7)
#elif TU_CHECK_MCU(OPT_MCU_STM32F2)
// FS has 4 ep, HS has 5 ep
#define DCD_ATTR_ENDPOINT_MAX 6
#define DCD_ATTR_DWC2_STM32
#elif TU_CHECK_MCU(OPT_MCU_STM32F3)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(OPT_MCU_STM32F4)
// For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9
#define DCD_ATTR_ENDPOINT_MAX 6
#define DCD_ATTR_DWC2_STM32
#elif TU_CHECK_MCU(OPT_MCU_STM32F7)
// FS has 6, HS has 9
#define DCD_ATTR_ENDPOINT_MAX 9
#define DCD_ATTR_DWC2_STM32
#elif TU_CHECK_MCU(STM32H7)
#elif TU_CHECK_MCU(OPT_MCU_STM32H7)
#define DCD_ATTR_ENDPOINT_MAX 9
#define DCD_ATTR_DWC2_STM32
#elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(OPT_MCU_STM32L4)
#if defined (STM32L475xx) || defined (STM32L476xx) || \
defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \
defined (STM32L4A6xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \
defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
#define DCD_ATTR_ENDPOINT_MAX 6
#define DCD_ATTR_DWC2_STM32
#else
#define DCD_ATTR_ENDPOINT_MAX 8
#endif
//------------- Sony -------------//
#elif TU_CHECK_MCU(CXD56)
#elif TU_CHECK_MCU(OPT_MCU_CXD56)
#define DCD_ATTR_ENDPOINT_MAX 7
#define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER
//------------- TI -------------//
#elif TU_CHECK_MCU(MSP430x5xx)
#elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx)
#define DCD_ATTR_ENDPOINT_MAX 8
//------------- ValentyUSB -------------//
#elif TU_CHECK_MCU(VALENTYUSB_EPTRI)
#elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI)
#define DCD_ATTR_ENDPOINT_MAX 16
//------------- Nuvoton -------------//
#elif TU_CHECK_MCU(NUC121) || TU_CHECK_MCU(NUC126)
#elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(NUC120)
#elif TU_CHECK_MCU(OPT_MCU_NUC120)
#define DCD_ATTR_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(NUC505)
#elif TU_CHECK_MCU(OPT_MCU_NUC505)
#define DCD_ATTR_ENDPOINT_MAX 12
//------------- Espressif -------------//
#elif TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
#define DCD_ATTR_ENDPOINT_MAX 6
//------------- Dialog -------------//
#elif TU_CHECK_MCU(DA1469X)
#elif TU_CHECK_MCU(OPT_MCU_DA1469X)
#define DCD_ATTR_ENDPOINT_MAX 4
//------------- Raspberry Pi -------------//
#elif TU_CHECK_MCU(RP2040)
#elif TU_CHECK_MCU(OPT_MCU_RP2040)
#define DCD_ATTR_ENDPOINT_MAX 16
//------------- Silabs -------------//
#elif TU_CHECK_MCU(EFM32GG) || TU_CHECK_MCU(EFM32GG11) || TU_CHECK_MCU(EFM32GG12)
#elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
#define DCD_ATTR_ENDPOINT_MAX 7
//------------- Renesas -------------//
#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X) || TU_CHECK_MCU(RX72N)
#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
#define DCD_ATTR_ENDPOINT_MAX 10
//#elif TU_CHECK_MCU(MM32F327X)
// #define DCD_ATTR_ENDPOINT_MAX not known yet
//------------- GigaDevice -------------//
#elif TU_CHECK_MCU(GD32VF103)
#elif TU_CHECK_MCU(OPT_MCU_GD32VF103)
#define DCD_ATTR_ENDPOINT_MAX 4
//------------- Broadcom -------------//
#elif TU_CHECK_MCU(OPT_MCU_BCM2711)
#define DCD_ATTR_ENDPOINT_MAX 8
#else
#warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8"
#define DCD_ATTR_ENDPOINT_MAX 8

View File

@ -34,64 +34,64 @@
// - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on.
//------------- NXP -------------//
#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX)
#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
#define HCD_ATTR_OHCI
#elif TU_CHECK_MCU(LPC18XX) || TU_CHECK_MCU(LPC43XX)
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
#define HCD_ATTR_EHCI_TRANSDIMENSION
#elif TU_CHECK_MCU(LPC54XXX)
#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX)
// #define HCD_ATTR_EHCI_NXP_PTD
#elif TU_CHECK_MCU(LPC55XX)
#elif TU_CHECK_MCU(OPT_MCU_LPC55XX)
// #define HCD_ATTR_EHCI_NXP_PTD
#elif TU_CHECK_MCU(MIMXRT10XX)
#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX)
#define HCD_ATTR_EHCI_TRANSDIMENSION
#elif TU_CHECK_MCU(MKL25ZXX)
#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX)
//------------- Microchip -------------//
#elif TU_CHECK_MCU(SAMD21) || TU_CHECK_MCU(SAMD51) || TU_CHECK_MCU(SAME5X) || \
TU_CHECK_MCU(SAMD11) || TU_CHECK_MCU(SAML21) || TU_CHECK_MCU(SAML22)
#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \
TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22)
#elif TU_CHECK_MCU(SAMG)
#elif TU_CHECK_MCU(OPT_MCU_SAMG)
#elif TU_CHECK_MCU(SAMX7X)
#elif TU_CHECK_MCU(OPT_MCU_SAMX7X)
//------------- ST -------------//
#elif TU_CHECK_MCU(STM32F0) || TU_CHECK_MCU(STM32F1) || TU_CHECK_MCU(STM32F3) || \
TU_CHECK_MCU(STM32L0) || TU_CHECK_MCU(STM32L1) || TU_CHECK_MCU(STM32L4)
#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1, OPT_MCU_STM32F3) || \
TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32L4)
#elif TU_CHECK_MCU(STM32F2) || TU_CHECK_MCU(STM32F4) || TU_CHECK_MCU(STM32F3)
#elif TU_CHECK_MCU(OPT_MCU_STM32F2, OPT_MCU_STM32F3, OPT_MCU_STM32F4)
#elif TU_CHECK_MCU(STM32F7)
#elif TU_CHECK_MCU(OPT_MCU_STM32F7)
#elif TU_CHECK_MCU(STM32H7)
#elif TU_CHECK_MCU(OPT_MCU_STM32H7)
//------------- Sony -------------//
#elif TU_CHECK_MCU(CXD56)
#elif TU_CHECK_MCU(OPT_MCU_CXD56)
//------------- Nuvoton -------------//
#elif TU_CHECK_MCU(NUC505)
#elif TU_CHECK_MCU(OPT_MCU_NUC505)
//------------- Espressif -------------//
#elif TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
//------------- Raspberry Pi -------------//
#elif TU_CHECK_MCU(RP2040)
#elif TU_CHECK_MCU(OPT_MCU_RP2040)
//------------- Silabs -------------//
#elif TU_CHECK_MCU(EFM32GG) || TU_CHECK_MCU(EFM32GG11) || TU_CHECK_MCU(EFM32GG12)
#elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
//------------- Renesas -------------//
#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X) || TU_CHECK_MCU(RX72N)
#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
//#elif TU_CHECK_MCU(MM32F327X)
//#elif TU_CHECK_MCU(OPT_MCU_MM32F327X)
// #define DCD_ATTR_ENDPOINT_MAX not known yet
//------------- GigaDevice -------------//
#elif TU_CHECK_MCU(GD32VF103)
#elif TU_CHECK_MCU(OPT_MCU_GD32VF103)
#else
// #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,936 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Rafael Silva (@perigoso)
* 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.
*/
#include "tusb_option.h"
#if TUSB_OPT_DEVICE_ENABLED && ( \
(CFG_TUSB_MCU == OPT_MCU_EFM32GG) || \
(CFG_TUSB_MCU == OPT_MCU_EFM32GG11) || \
(CFG_TUSB_MCU == OPT_MCU_EFM32GG12) )
/* Silabs */
#include "em_device.h"
#include "device/dcd.h"
/*
* Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval)
* We disable SOF for now until needed later on
*/
#define USE_SOF 0
/*
* Number of endpoints
* 12 software-configurable endpoints (6 IN, 6 OUT) in addition to endpoint 0
*/
#define EP_COUNT 7
/* FIFO size in bytes */
#define EP_FIFO_SIZE 2048
/* Max number of IN EP FIFOs */
#define EP_FIFO_NUM 7
/* */
typedef struct {
uint8_t *buffer;
uint16_t total_len;
uint16_t queued_len;
uint16_t max_size;
bool short_packet;
} xfer_ctl_t;
static uint32_t _setup_packet[2];
#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir]
static xfer_ctl_t xfer_status[EP_COUNT][2];
/* Keep count of how many FIFOs are in use */
static uint8_t _allocated_fifos = 1; /* FIFO0 is always in use */
static volatile uint32_t* tx_fifo[EP_FIFO_NUM] = {
USB->FIFO0D,
USB->FIFO1D,
USB->FIFO2D,
USB->FIFO3D,
USB->FIFO4D,
USB->FIFO5D,
USB->FIFO6D,
};
/* Register Helpers */
#define DCTL_WO_BITMASK (USB_DCTL_CGOUTNAK | USB_DCTL_SGOUTNAK | USB_DCTL_CGNPINNAK | USB_DCTL_SGNPINNAK)
#define GUSBCFG_WO_BITMASK (USB_GUSBCFG_CORRUPTTXPKT)
#define DEPCTL_WO_BITMASK (USB_DIEP_CTL_CNAK | USB_DIEP_CTL_SNAK | USB_DIEP_CTL_SETD0PIDEF | USB_DIEP_CTL_SETD1PIDOF)
/* Will either return an unused FIFO number, or 0 if all are used. */
static uint8_t get_free_fifo(void)
{
if(_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++;
return 0;
}
/*
static void flush_rx_fifo(void)
{
USB->GRSTCTL = USB_GRSTCTL_RXFFLSH;
while(USB->GRSTCTL & USB_GRSTCTL_RXFFLSH);
}
*/
static void flush_tx_fifo(uint8_t fifo_num)
{
USB->GRSTCTL = USB_GRSTCTL_TXFFLSH | (fifo_num << _USB_GRSTCTL_TXFNUM_SHIFT);
while(USB->GRSTCTL & USB_GRSTCTL_TXFFLSH);
}
/* Setup the control endpoint 0. */
static void bus_reset(void)
{
USB->DOEP0CTL |= USB_DIEP_CTL_SNAK;
for(uint8_t i = 0; i < EP_COUNT - 1; i++)
{
USB->DOEP[i].CTL |= USB_DIEP_CTL_SNAK;
}
/* reset address */
USB->DCFG &= ~_USB_DCFG_DEVADDR_MASK;
USB->DAINTMSK |= USB_DAINTMSK_OUTEPMSK0 | USB_DAINTMSK_INEPMSK0;
USB->DOEPMSK |= USB_DOEPMSK_SETUPMSK | USB_DOEPMSK_XFERCOMPLMSK;
USB->DIEPMSK |= USB_DIEPMSK_TIMEOUTMSK | USB_DIEPMSK_XFERCOMPLMSK;
/*
* - All EP OUT shared a unique OUT FIFO which uses
* * 10 locations in hardware for setup packets + setup control words (up to 3 setup packets).
* * 2 locations for OUT endpoint control words.
* * 16 for largest packet size of 64 bytes. ( TODO Highspeed is 512 bytes)
* * 1 location for global NAK (not required/used here).
* * It is recommended to allocate 2 times the largest packet size, therefore
* Recommended value = 10 + 1 + 2 x (16+2) = 47 --> Let's make it 52
*/
flush_tx_fifo(_USB_GRSTCTL_TXFNUM_FALL); // Flush All
USB->GRXFSIZ = 52;
/* Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) */
USB->GNPTXFSIZ = (16 << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT) | (USB->GRXFSIZ & _USB_GNPTXFSIZ_NPTXFSTADDR_MASK);
/* Ready to receive SETUP packet */
USB->DOEP0TSIZ |= (1 << _USB_DOEP0TSIZ_SUPCNT_SHIFT);
USB->GINTMSK |= USB_GINTMSK_IEPINTMSK | USB_GINTMSK_OEPINTMSK;
}
static void enum_done_processing(void)
{
/* Maximum packet size for EP 0 is set for both directions by writing DIEPCTL */
if((USB->DSTS & _USB_DSTS_ENUMSPD_MASK) == USB_DSTS_ENUMSPD_FS)
{
/* Full Speed (PHY on 48 MHz) */
USB->DOEP0CTL = (USB->DOEP0CTL & ~_USB_DOEP0CTL_MPS_MASK) | _USB_DOEP0CTL_MPS_64B; /* Maximum Packet Size 64 bytes */
USB->DOEP0CTL &= ~_USB_DOEP0CTL_STALL_MASK; /* clear Stall */
xfer_status[0][TUSB_DIR_OUT].max_size = 64;
xfer_status[0][TUSB_DIR_IN].max_size = 64;
}
else
{
/* Low Speed (PHY on 6 MHz) */
USB->DOEP0CTL = (USB->DOEP0CTL & ~_USB_DOEP0CTL_MPS_MASK) | _USB_DOEP0CTL_MPS_8B; /* Maximum Packet Size 64 bytes */
USB->DOEP0CTL &= ~_USB_DOEP0CTL_STALL_MASK; /* clear Stall */
xfer_status[0][TUSB_DIR_OUT].max_size = 8;
xfer_status[0][TUSB_DIR_IN].max_size = 8;
}
}
/*------------------------------------------------------------------*/
/* Controller API */
/*------------------------------------------------------------------*/
void dcd_init(uint8_t rhport)
{
(void) rhport;
/* Reset Core */
USB->PCGCCTL &= ~USB_PCGCCTL_STOPPCLK;
USB->PCGCCTL &= ~(USB_PCGCCTL_PWRCLMP | USB_PCGCCTL_RSTPDWNMODULE);
/* Core Soft Reset */
USB->GRSTCTL |= USB_GRSTCTL_CSFTRST;
while(USB->GRSTCTL & USB_GRSTCTL_CSFTRST);
while(!(USB->GRSTCTL & USB_GRSTCTL_AHBIDLE));
/* Enable PHY pins */
USB->ROUTE = USB_ROUTE_PHYPEN;
dcd_disconnect(rhport);
/*
* Set device speed (Full speed PHY)
* Stall on non-zero len status OUT packets (ctrl transfers)
* periodic frame interval to 80%
*/
USB->DCFG = (USB->DCFG & ~(_USB_DCFG_DEVSPD_MASK | _USB_DCFG_PERFRINT_MASK)) | USB_DCFG_DEVSPD_FS | USB_DCFG_NZSTSOUTHSHK;
/* Enable Global Interrupts */
USB->GAHBCFG = (USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK) | USB_GAHBCFG_GLBLINTRMSK;
/* Force Device Mode */
USB->GUSBCFG = (USB->GUSBCFG & ~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEHSTMODE)) | USB_GUSBCFG_FORCEDEVMODE;
/* No Overrides */
USB->GOTGCTL &= ~(USB_GOTGCTL_BVALIDOVVAL | USB_GOTGCTL_BVALIDOVEN | USB_GOTGCTL_VBVALIDOVVAL);
/* Ignore frame numbers on ISO transfers. */
USB->DCTL = (USB->DCTL & ~DCTL_WO_BITMASK) | USB_DCTL_IGNRFRMNUM;
/* Setting SNAKs */
USB->DOEP0CTL |= USB_DIEP_CTL_SNAK;
for(uint8_t i = 0; i < EP_COUNT - 1; i++)
{
USB->DOEP[i].CTL |= USB_DIEP_CTL_SNAK;
}
/* D. Interruption masking */
/* Disable all device interrupts */
USB->DIEPMSK = 0;
USB->DOEPMSK = 0;
USB->DAINTMSK = 0;
USB->DIEPEMPMSK = 0;
USB->GINTMSK = 0;
USB->GOTGINT = ~0U; /* clear OTG ints */
USB->GINTSTS = ~0U; /* clear pending ints */
USB->GINTMSK = USB_GINTMSK_MODEMISMSK |
#if USE_SOF
USB_GINTMSK_SOFMSK |
#endif
USB_GINTMSK_ERLYSUSPMSK |
USB_GINTMSK_USBSUSPMSK |
USB_GINTMSK_USBRSTMSK |
USB_GINTMSK_ENUMDONEMSK |
USB_GINTMSK_RESETDETMSK |
USB_GINTMSK_DISCONNINTMSK;
NVIC_ClearPendingIRQ(USB_IRQn);
dcd_connect(rhport);
}
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
{
(void) rhport;
USB->DCFG = (USB->DCFG & ~_USB_DCFG_DEVADDR_MASK) | (dev_addr << _USB_DCFG_DEVADDR_SHIFT);
/* Response with status after changing device address */
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
}
void dcd_remote_wakeup(uint8_t rhport)
{
(void) rhport;
}
void dcd_connect(uint8_t rhport)
{
(void) rhport;
/* connect by enabling internal pull-up resistor on D+/D- */
USB->DCTL &= ~(DCTL_WO_BITMASK | USB_DCTL_SFTDISCON);
}
void dcd_disconnect(uint8_t rhport)
{
(void) rhport;
/* disconnect by disabling internal pull-up resistor on D+/D- */
USB->DCTL = (USB->DCTL & ~(DCTL_WO_BITMASK)) | USB_DCTL_SFTDISCON;
}
/*------------------------------------------------------------------*/
/* DCD Endpoint Port */
/*------------------------------------------------------------------*/
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
if(dir == TUSB_DIR_IN)
{
if(epnum == 0)
{
USB->DIEP0CTL = (USB->DIEP0CTL & ~DEPCTL_WO_BITMASK) | USB_DIEP0CTL_SNAK | USB_DIEP0CTL_STALL;
flush_tx_fifo(_USB_GRSTCTL_TXFNUM_F0);
}
else
{
/* Only disable currently enabled non-control endpoint */
if(USB->DIEP[epnum - 1].CTL & USB_DIEP_CTL_EPENA)
{
USB->DIEP[epnum - 1].CTL = (USB->DIEP[epnum - 1].CTL & ~DEPCTL_WO_BITMASK) | USB_DIEP_CTL_EPDIS | USB_DIEP_CTL_SNAK | USB_DIEP_CTL_STALL;
while(!(USB->DIEP[epnum - 1].INT & USB_DIEP_INT_EPDISBLD));
USB->DIEP[epnum - 1].INT |= USB_DIEP_INT_EPDISBLD;
}
else
{
USB->DIEP[epnum - 1].CTL = (USB->DIEP[epnum - 1].CTL & ~DEPCTL_WO_BITMASK) | USB_DIEP_CTL_SNAK | USB_DIEP_CTL_STALL;
}
/* Flush the FIFO */
uint8_t const fifo_num = ((USB->DIEP[epnum - 1].CTL & _USB_DIEP_CTL_TXFNUM_MASK) >> _USB_DIEP_CTL_TXFNUM_SHIFT);
flush_tx_fifo(fifo_num);
}
}
else
{
if(epnum == 0)
{
USB->DOEP0CTL = (USB->DOEP0CTL & ~DEPCTL_WO_BITMASK) | USB_DIEP0CTL_STALL;
}
else
{
/* Only disable currently enabled non-control endpoint */
if(USB->DOEP[epnum - 1].CTL & USB_DIEP_CTL_EPENA)
{
/* Asserting GONAK is required to STALL an OUT endpoint. */
USB->DCTL |= USB_DCTL_SGOUTNAK;
while(!(USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF));
/* Disable the endpoint. Note that only STALL and not SNAK is set here. */
USB->DOEP[epnum - 1].CTL = (USB->DOEP[epnum - 1].CTL & ~DEPCTL_WO_BITMASK) | USB_DIEP_CTL_EPDIS | USB_DIEP_CTL_STALL;
while(USB->DOEP[epnum - 1].INT & USB_DIEP_INT_EPDISBLD);
USB->DOEP[epnum - 1].INT |= USB_DIEP_INT_EPDISBLD;
/* Allow other OUT endpoints to keep receiving. */
USB->DCTL |= USB_DCTL_CGOUTNAK;
}
else
{
USB->DIEP[epnum - 1].CTL = (USB->DIEP[epnum - 1].CTL & ~DEPCTL_WO_BITMASK) | USB_DIEP_CTL_STALL;
}
}
}
}
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
if(dir == TUSB_DIR_IN)
{
if(epnum == 0)
{
USB->DIEP0CTL &= ~(DEPCTL_WO_BITMASK | USB_DIEP0CTL_STALL);
}
else
{
USB->DIEP[epnum - 1].CTL &= ~(DEPCTL_WO_BITMASK | USB_DIEP_CTL_STALL);
/* Required by USB spec to reset DATA toggle bit to DATA0 on interrupt and bulk endpoints. */
uint8_t eptype = (USB->DIEP[epnum - 1].CTL & _USB_DIEP_CTL_EPTYPE_MASK) >> _USB_DIEP_CTL_EPTYPE_SHIFT;
if((eptype == _USB_DIEP_CTL_EPTYPE_BULK) || (eptype == _USB_DIEP_CTL_EPTYPE_INT))
{
USB->DIEP[epnum - 1].CTL |= USB_DIEP_CTL_SETD0PIDEF;
}
}
}
else
{
if(epnum == 0)
{
USB->DOEP0CTL &= ~(DEPCTL_WO_BITMASK | USB_DOEP0CTL_STALL);
}
else
{
USB->DOEP[epnum - 1].CTL &= ~(DEPCTL_WO_BITMASK | USB_DOEP_CTL_STALL);
/* Required by USB spec to reset DATA toggle bit to DATA0 on interrupt and bulk endpoints. */
uint8_t eptype = (USB->DOEP[epnum - 1].CTL & _USB_DOEP_CTL_EPTYPE_MASK) >> _USB_DOEP_CTL_EPTYPE_SHIFT;
if((eptype == _USB_DOEP_CTL_EPTYPE_BULK) || (eptype == _USB_DOEP_CTL_EPTYPE_INT))
{
USB->DOEP[epnum - 1].CTL |= USB_DOEP_CTL_SETD0PIDEF;
}
}
}
}
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
{
(void)rhport;
uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
TU_ASSERT(epnum < EP_COUNT);
TU_ASSERT(epnum != 0);
xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir);
xfer->max_size = tu_edpt_packet_size(p_endpoint_desc);
if(dir == TUSB_DIR_OUT)
{
USB->DOEP[epnum - 1].CTL |= USB_DOEP_CTL_USBACTEP |
(p_endpoint_desc->bmAttributes.xfer << _USB_DOEP_CTL_EPTYPE_SHIFT) |
(xfer->max_size << _USB_DOEP_CTL_MPS_SHIFT);
USB->DAINTMSK |= (1 << (_USB_DAINTMSK_OUTEPMSK0_SHIFT + epnum));
}
else
{
uint8_t fifo_num = get_free_fifo();
TU_ASSERT(fifo_num != 0);
USB->DIEP[epnum - 1].CTL &= ~(_USB_DIEP_CTL_TXFNUM_MASK | _USB_DIEP_CTL_EPTYPE_MASK | USB_DIEP_CTL_SETD0PIDEF | _USB_DIEP_CTL_MPS_MASK);
USB->DIEP[epnum - 1].CTL |= USB_DIEP_CTL_USBACTEP |
(fifo_num << _USB_DIEP_CTL_TXFNUM_SHIFT) |
(p_endpoint_desc->bmAttributes.xfer << _USB_DIEP_CTL_EPTYPE_SHIFT) |
((p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) ? USB_DIEP_CTL_SETD0PIDEF : 0) |
(xfer->max_size << 0);
USB->DAINTMSK |= (1 << epnum);
/* Both TXFD and TXSA are in unit of 32-bit words. */
/* IN FIFO 0 was configured during enumeration, hence the "+ 16". */
uint16_t const allocated_size = (USB->GRXFSIZ & _USB_GRXFSIZ_RXFDEP_MASK) + 16;
uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1);
uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1);
/* DIEPTXF starts at FIFO #1. */
volatile uint32_t* usb_dieptxf = &USB->DIEPTXF1;
usb_dieptxf[epnum - 1] = (fifo_size << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT) | fifo_offset;
}
return true;
}
void dcd_edpt_close_all (uint8_t rhport)
{
(void) rhport;
// TODO implement dcd_edpt_close_all()
}
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
{
(void)rhport;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
xfer->buffer = buffer;
xfer->total_len = total_bytes;
xfer->queued_len = 0;
xfer->short_packet = false;
uint16_t num_packets = (total_bytes / xfer->max_size);
uint8_t short_packet_size = total_bytes % xfer->max_size;
// Zero-size packet is special case.
if(short_packet_size > 0 || (total_bytes == 0))
{
num_packets++;
}
// IN and OUT endpoint xfers are interrupt-driven, we just schedule them
// here.
if(dir == TUSB_DIR_IN)
{
if(epnum == 0)
{
// A full IN transfer (multiple packets, possibly) triggers XFRC.
USB->DIEP0TSIZ = (num_packets << _USB_DIEP0TSIZ_PKTCNT_SHIFT) | total_bytes;
USB->DIEP0CTL |= USB_DIEP0CTL_EPENA | USB_DIEP0CTL_CNAK; // Enable | CNAK
}
else
{
// A full IN transfer (multiple packets, possibly) triggers XFRC.
USB->DIEP[epnum - 1].TSIZ = (num_packets << _USB_DIEP_TSIZ_PKTCNT_SHIFT) | total_bytes;
USB->DIEP[epnum - 1].CTL |= USB_DIEP_CTL_EPENA | USB_DIEP_CTL_CNAK; // Enable | CNAK
}
// Enable fifo empty interrupt only if there are something to put in the fifo.
if(total_bytes != 0)
{
USB->DIEPEMPMSK |= (1 << epnum);
}
}
else
{
if(epnum == 0)
{
// A full IN transfer (multiple packets, possibly) triggers XFRC.
USB->DOEP0TSIZ |= (1 << _USB_DOEP0TSIZ_PKTCNT_SHIFT) | ((xfer->max_size & _USB_DOEP0TSIZ_XFERSIZE_MASK) << _USB_DOEP0TSIZ_XFERSIZE_SHIFT);
USB->DOEP0CTL |= USB_DOEP0CTL_EPENA | USB_DOEP0CTL_CNAK;
}
else
{
// A full IN transfer (multiple packets, possibly) triggers XFRC.
USB->DOEP[epnum - 1].TSIZ |= (1 << _USB_DOEP_TSIZ_PKTCNT_SHIFT) | ((xfer->max_size & _USB_DOEP_TSIZ_XFERSIZE_MASK) << _USB_DOEP_TSIZ_XFERSIZE_SHIFT);
USB->DOEP[epnum - 1].CTL |= USB_DOEP_CTL_EPENA | USB_DOEP_CTL_CNAK;
}
}
return true;
}
/*------------------------------------------------------------------*/
/* IRQ */
/*------------------------------------------------------------------*/
void dcd_int_enable(uint8_t rhport)
{
(void) rhport;
NVIC_EnableIRQ(USB_IRQn);
}
void dcd_int_disable(uint8_t rhport)
{
(void) rhport;
NVIC_DisableIRQ(USB_IRQn);
}
static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size)
{
uint16_t remaining = xfer->total_len - xfer->queued_len;
uint16_t to_recv_size;
if(remaining <= xfer->max_size)
{
/* Avoid buffer overflow. */
to_recv_size = (xfer_size > remaining) ? remaining : xfer_size;
}
else
{
/* Room for full packet, choose recv_size based on what the microcontroller claims. */
to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size;
}
uint8_t to_recv_rem = to_recv_size % 4;
uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
/* Do not assume xfer buffer is aligned. */
uint8_t *base = (xfer->buffer + xfer->queued_len);
/* This for loop always runs at least once- skip if less than 4 bytes to collect. */
if(to_recv_size >= 4)
{
for(uint16_t i = 0; i < to_recv_size_aligned; i += 4)
{
uint32_t tmp = (*USB->FIFO0D);
base[i] = tmp & 0x000000FF;
base[i + 1] = (tmp & 0x0000FF00) >> 8;
base[i + 2] = (tmp & 0x00FF0000) >> 16;
base[i + 3] = (tmp & 0xFF000000) >> 24;
}
}
/* Do not read invalid bytes from RX FIFO. */
if(to_recv_rem != 0)
{
uint32_t tmp = (*USB->FIFO0D);
uint8_t *last_32b_bound = base + to_recv_size_aligned;
last_32b_bound[0] = tmp & 0x000000FF;
if(to_recv_rem > 1)
{
last_32b_bound[1] = (tmp & 0x0000FF00) >> 8;
}
if(to_recv_rem > 2)
{
last_32b_bound[2] = (tmp & 0x00FF0000) >> 16;
}
}
xfer->queued_len += xfer_size;
/* Per USB spec, a short OUT packet (including length 0) is always */
/* indicative of the end of a transfer (at least for ctl, bulk, int). */
xfer->short_packet = (xfer_size < xfer->max_size);
}
static void transmit_packet(xfer_ctl_t *xfer, uint8_t fifo_num)
{
uint16_t remaining;
if(fifo_num == 0)
{
remaining = (USB->DIEP0TSIZ & 0x7FFFFU) >> _USB_DIEP0TSIZ_XFERSIZE_SHIFT;
}
else
{
remaining = (USB->DIEP[fifo_num - 1].TSIZ & 0x7FFFFU) >> _USB_DIEP_TSIZ_XFERSIZE_SHIFT;
}
xfer->queued_len = xfer->total_len - remaining;
uint16_t to_xfer_size = (remaining > xfer->max_size) ? xfer->max_size : remaining;
uint8_t to_xfer_rem = to_xfer_size % 4;
uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
/* Buffer might not be aligned to 32b, so we need to force alignment by copying to a temp var. */
uint8_t *base = (xfer->buffer + xfer->queued_len);
/* This for loop always runs at least once- skip if less than 4 bytes to send off. */
if(to_xfer_size >= 4)
{
for(uint16_t i = 0; i < to_xfer_size_aligned; i += 4)
{
uint32_t tmp = base[i] | (base[i + 1] << 8) | (base[i + 2] << 16) | (base[i + 3] << 24);
*tx_fifo[fifo_num] = tmp;
}
}
/* Do not read beyond end of buffer if not divisible by 4. */
if(to_xfer_rem != 0)
{
uint32_t tmp = 0;
uint8_t *last_32b_bound = base + to_xfer_size_aligned;
tmp |= last_32b_bound[0];
if(to_xfer_rem > 1)
{
tmp |= (last_32b_bound[1] << 8);
}
if(to_xfer_rem > 2)
{
tmp |= (last_32b_bound[2] << 16);
}
*tx_fifo[fifo_num] = tmp;
}
}
static void read_rx_fifo(void)
{
/*
* Pop control word off FIFO (completed xfers will have 2 control words,
* we only pop one ctl word each interrupt).
*/
uint32_t const ctl_word = USB->GRXSTSP;
uint8_t const pktsts = (ctl_word & _USB_GRXSTSP_PKTSTS_MASK) >> _USB_GRXSTSP_PKTSTS_SHIFT;
uint8_t const epnum = (ctl_word & _USB_GRXSTSP_CHNUM_MASK ) >> _USB_GRXSTSP_CHNUM_SHIFT;
uint16_t const bcnt = (ctl_word & _USB_GRXSTSP_BCNT_MASK ) >> _USB_GRXSTSP_BCNT_SHIFT;
switch(pktsts)
{
case 0x01: /* Global OUT NAK (Interrupt) */
break;
case 0x02:
{
/* Out packet recvd */
xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
receive_packet(xfer, bcnt);
}
break;
case 0x03:
/* Out packet done (Interrupt) */
break;
case 0x04:
/* Step 2: Setup transaction completed (Interrupt) */
/* After this event, OEPINT interrupt will occur with SETUP bit set */
if(epnum == 0)
{
USB->DOEP0TSIZ |= (1 << _USB_DOEP0TSIZ_SUPCNT_SHIFT);
}
break;
case 0x06:
{
/* Step1: Setup data packet received */
/*
* We can receive up to three setup packets in succession, but
* only the last one is valid. Therefore we just overwrite it
*/
_setup_packet[0] = (*USB->FIFO0D);
_setup_packet[1] = (*USB->FIFO0D);
}
break;
default:
/* Invalid, breakpoint. */
TU_BREAKPOINT();
break;
}
}
static void handle_epout_ints(void)
{
// GINTSTS will be cleared with DAINT == 0
// DAINT for a given EP clears when DOEPINTx is cleared.
// DOEPINT will be cleared when DAINT's out bits are cleared.
for(uint8_t n = 0; n < EP_COUNT; n++)
{
xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT);
if(n == 0)
{
if(USB->DAINT & (1 << (_USB_DAINT_OUTEPINT0_SHIFT + n)))
{
// SETUP packet Setup Phase done.
if((USB->DOEP0INT & USB_DOEP0INT_SETUP))
{
USB->DOEP0INT = USB_DOEP0INT_STUPPKTRCVD | USB_DOEP0INT_SETUP; // clear
dcd_event_setup_received(0, (uint8_t *)&_setup_packet[0], true);
}
// OUT XFER complete (single packet).q
if(USB->DOEP0INT & USB_DOEP0INT_XFERCOMPL)
{
USB->DOEP0INT = USB_DOEP0INT_XFERCOMPL;
// Transfer complete if short packet or total len is transferred
if(xfer->short_packet || (xfer->queued_len == xfer->total_len))
{
xfer->short_packet = false;
dcd_event_xfer_complete(0, n, xfer->queued_len, XFER_RESULT_SUCCESS, true);
}
else
{
// Schedule another packet to be received.
USB->DOEP0TSIZ |= (1 << _USB_DOEP0TSIZ_PKTCNT_SHIFT) | ((xfer->max_size & _USB_DOEP0TSIZ_XFERSIZE_MASK) << _USB_DOEP0TSIZ_XFERSIZE_SHIFT);
USB->DOEP0CTL |= USB_DOEP0CTL_EPENA | USB_DOEP0CTL_CNAK;
}
}
}
}
else
{
if(USB->DAINT & (1 << (_USB_DAINT_OUTEPINT0_SHIFT + n)))
{
// SETUP packet Setup Phase done.
if((USB->DOEP[n - 1].INT & USB_DOEP_INT_SETUP))
{
USB->DOEP[n - 1].INT = USB_DOEP_INT_STUPPKTRCVD | USB_DOEP_INT_SETUP; // clear
dcd_event_setup_received(0, (uint8_t *)&_setup_packet[0], true);
}
// OUT XFER complete (single packet).q
if(USB->DOEP[n - 1].INT & USB_DOEP_INT_XFERCOMPL)
{
USB->DOEP[n - 1].INT = USB_DOEP_INT_XFERCOMPL;
// Transfer complete if short packet or total len is transferred
if(xfer->short_packet || (xfer->queued_len == xfer->total_len))
{
xfer->short_packet = false;
dcd_event_xfer_complete(0, n, xfer->queued_len, XFER_RESULT_SUCCESS, true);
}
else
{
// Schedule another packet to be received.
USB->DOEP[n - 1].TSIZ |= (1 << _USB_DOEP_TSIZ_PKTCNT_SHIFT) | ((xfer->max_size & _USB_DOEP_TSIZ_XFERSIZE_MASK) << _USB_DOEP_TSIZ_XFERSIZE_SHIFT);
USB->DOEP[n - 1].CTL |= USB_DOEP_CTL_EPENA | USB_DOEP_CTL_CNAK;
}
}
}
}
}
}
static void handle_epin_ints(void)
{
for(uint32_t n = 0; n < EP_COUNT; n++)
{
xfer_ctl_t *xfer = &xfer_status[n][TUSB_DIR_IN];
if(n == 0)
{
if(USB->DAINT & (1 << n))
{
/* IN XFER complete (entire xfer). */
if(USB->DIEP0INT & USB_DIEP0INT_XFERCOMPL)
{
USB->DIEP0INT = USB_DIEP0INT_XFERCOMPL;
dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true);
}
/* XFER FIFO empty */
if(USB->DIEP0INT & USB_DIEP0INT_TXFEMP)
{
USB->DIEP0INT = USB_DIEP0INT_TXFEMP;
transmit_packet(xfer, n);
/* Turn off TXFE if all bytes are written. */
if(xfer->queued_len == xfer->total_len)
{
USB->DIEPEMPMSK &= ~(1 << n);
}
}
/* XFER Timeout */
if(USB->DIEP0INT & USB_DIEP0INT_TIMEOUT)
{
/* Clear interrupt or enpoint will hang. */
USB->DIEP0INT = USB_DIEP0INT_TIMEOUT;
}
}
}
else
{
if(USB->DAINT & (1 << n))
{
/* IN XFER complete (entire xfer). */
if(USB->DIEP[n - 1].INT & USB_DIEP_INT_XFERCOMPL)
{
USB->DIEP[n - 1].INT = USB_DIEP_INT_XFERCOMPL;
dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true);
}
/* XFER FIFO empty */
if(USB->DIEP[n - 1].INT & USB_DIEP_INT_TXFEMP)
{
USB->DIEP[n - 1].INT = USB_DIEP_INT_TXFEMP;
transmit_packet(xfer, n);
/* Turn off TXFE if all bytes are written. */
if(xfer->queued_len == xfer->total_len)
{
USB->DIEPEMPMSK &= ~(1 << n);
}
}
/* XFER Timeout */
if(USB->DIEP[n - 1].INT & USB_DIEP_INT_TIMEOUT)
{
/* Clear interrupt or enpoint will hang. */
USB->DIEP[n - 1].INT = USB_DIEP_INT_TIMEOUT;
}
}
}
}
}
void dcd_int_handler(uint8_t rhport)
{
(void) rhport;
const uint32_t int_status = USB->GINTSTS;
/* USB Reset */
if(int_status & USB_GINTSTS_USBRST)
{
/* start of reset */
USB->GINTSTS = USB_GINTSTS_USBRST;
/* FIFOs will be reassigned when the endpoints are reopen */
_allocated_fifos = 1;
bus_reset();
}
/* Reset detected Interrupt */
if(int_status & USB_GINTSTS_RESETDET)
{
USB->GINTSTS = USB_GINTSTS_RESETDET;
bus_reset();
}
/* Enumeration Done */
if(int_status & USB_GINTSTS_ENUMDONE)
{
/* This interrupt is considered the end of reset. */
USB->GINTSTS = USB_GINTSTS_ENUMDONE;
enum_done_processing();
dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true);
}
/* OTG Interrupt */
if(int_status & USB_GINTSTS_OTGINT)
{
/* OTG INT bit is read-only */
uint32_t const otg_int = USB->GOTGINT;
if(otg_int & USB_GOTGINT_SESENDDET)
{
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true);
}
USB->GOTGINT = otg_int;
}
#if USE_SOF
if(int_status & USB_GINTSTS_SOF)
{
USB->GINTSTS = USB_GINTSTS_SOF;
dcd_event_bus_signal(0, DCD_EVENT_SOF, true);
}
#endif
/* RxFIFO Non-Empty */
if(int_status & USB_GINTSTS_RXFLVL)
{
/* RXFLVL bit is read-only */
/* Mask out RXFLVL while reading data from FIFO */
USB->GINTMSK &= ~USB_GINTMSK_RXFLVLMSK;
read_rx_fifo();
USB->GINTMSK |= USB_GINTMSK_RXFLVLMSK;
}
/* OUT Endpoints Interrupt */
if(int_status & USB_GINTMSK_OEPINTMSK)
{
/* OEPINT is read-only */
handle_epout_ints();
}
/* IN Endpoints Interrupt */
if(int_status & USB_GINTMSK_IEPINTMSK)
{
/* IEPINT bit read-only */
handle_epin_ints();
}
/* unhandled */
USB->GINTSTS |= USB_GINTSTS_CURMOD |
USB_GINTSTS_MODEMIS |
USB_GINTSTS_OTGINT |
USB_GINTSTS_NPTXFEMP |
USB_GINTSTS_GINNAKEFF |
USB_GINTSTS_GOUTNAKEFF |
USB_GINTSTS_ERLYSUSP |
USB_GINTSTS_USBSUSP |
USB_GINTSTS_ISOOUTDROP |
USB_GINTSTS_EOPF |
USB_GINTSTS_EPMIS |
USB_GINTSTS_INCOMPISOIN |
USB_GINTSTS_INCOMPLP |
USB_GINTSTS_FETSUSP |
USB_GINTSTS_PTXFEMP;
}
#endif

View File

@ -109,13 +109,10 @@
#define STM32F1_FSDEV
#endif
#if (TUSB_OPT_DEVICE_ENABLED) && ( \
(CFG_TUSB_MCU == OPT_MCU_STM32F0 ) || \
(CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_FSDEV)) || \
(CFG_TUSB_MCU == OPT_MCU_STM32F3 ) || \
(CFG_TUSB_MCU == OPT_MCU_STM32L0 ) || \
(CFG_TUSB_MCU == OPT_MCU_STM32L1 ) \
)
#if TUSB_OPT_DEVICE_ENABLED && \
( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1) || \
(TU_CHECK_MCU(OPT_MCU_STM32F1) && defined(STM32F1_FSDEV)) \
)
// In order to reduce the dependance on HAL, we undefine this.
// Some definitions are copied to our private include file.

View File

@ -370,7 +370,7 @@ static bool USB_HS_PHYCInit(void)
{
USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE;
// Enable LDO
// Enable LDO: Note STM32F72/3xx Reference Manual rev 3 June 2018 incorrectly defined this bit as Disabled !!
usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
// Wait until LDO ready

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,89 @@
/*
* 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 _TUSB_DWC2_BCM_H_
#define _TUSB_DWC2_BCM_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "broadcom/interrupts.h"
#include "broadcom/caches.h"
#define DWC2_REG_BASE 0xFE980000UL
#define DWC2_EP_MAX 8
#define DWC2_EP_FIFO_SIZE 4096
#define dcache_clean(_addr, _size) data_clean(_addr, _size)
#define dcache_invalidate(_addr, _size) data_invalidate(_addr, _size)
#define dcache_clean_invalidate(_addr, _size) data_clean_and_invalidate(_addr, _size)
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_enable(uint8_t rhport)
{
(void) rhport;
BP_EnableIRQ(USB_IRQn);
__asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !?
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_disable (uint8_t rhport)
{
(void) rhport;
BP_DisableIRQ(USB_IRQn);
__asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !?
}
static inline void dwc2_remote_wakeup_delay(void)
{
// try to delay for 1 ms
// TODO implement later
}
// MCU specific PHY init, called BEFORE core reset
static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// nothing to do
}
// MCU specific PHY update, it is called AFTER init() and core reset
static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// nothing to do
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,87 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Rafael Silva (@perigoso)
* 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 _DWC2_EFM32_H_
#define _DWC2_EFM32_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "em_device.h"
// EFM32 has custom control register before DWC registers
#define DWC2_REG_BASE (USB_BASE + offsetof(USB_TypeDef, GOTGCTL))
#define DWC2_EP_MAX 7
#define DWC2_EP_FIFO_SIZE 2048
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_enable(uint8_t rhport)
{
(void) rhport;
NVIC_EnableIRQ(USB_IRQn);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_disable (uint8_t rhport)
{
(void) rhport;
NVIC_DisableIRQ(USB_IRQn);
}
static inline void dwc2_remote_wakeup_delay(void)
{
// try to delay for 1 ms
// uint32_t count = SystemCoreClock / 1000;
// while ( count-- ) __NOP();
}
// MCU specific PHY init, called BEFORE core reset
static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// Enable PHY
USB->ROUTE = USB_ROUTE_PHYPEN;
}
// MCU specific PHY update, it is called AFTER init() and core reset
static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// EFM32 Manual: turn around must be 5 (reset & default value)
// dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,94 @@
/*
* 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 _DWC2_ESP32_H_
#define _DWC2_ESP32_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_intr_alloc.h"
#include "soc/periph_defs.h"
//#include "soc/usb_periph.h"
#define DWC2_REG_BASE 0x60080000UL
#define DWC2_EP_MAX 5 // USB_OUT_EP_NUM
#define DWC2_EP_FIFO_SIZE 1024
// #define EP_FIFO_NUM 5
static intr_handle_t usb_ih;
static void dcd_int_handler_wrap(void* arg)
{
(void) arg;
dcd_int_handler(0);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_enable (uint8_t rhport)
{
(void) rhport;
esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_disable (uint8_t rhport)
{
(void) rhport;
esp_intr_free(usb_ih);
}
static inline void dwc2_remote_wakeup_delay(void)
{
vTaskDelay(pdMS_TO_TICKS(1));
}
// MCU specific PHY init, called BEFORE core reset
static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// nothing to do
}
// MCU specific PHY update, it is called AFTER init() and core reset
static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// nothing to do
}
#ifdef __cplusplus
}
#endif
#endif /* _DWC2_ESP32_H_ */

View File

@ -0,0 +1,100 @@
/*
* 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 DWC2_GD32_H_
#define DWC2_GD32_H_
#ifdef __cplusplus
extern "C" {
#endif
#define DWC2_REG_BASE 0x50000000UL
#define DWC2_EP_MAX 4
#define DWC2_EP_FIFO_SIZE 1280
#define RHPORT_IRQn 86
extern uint32_t SystemCoreClock;
// The GD32VF103 is a RISC-V MCU, which implements the ECLIC Core-Local
// Interrupt Controller by Nuclei. It is nearly API compatible to the
// NVIC used by ARM MCUs.
#define ECLIC_INTERRUPT_ENABLE_BASE 0xD2001001UL
TU_ATTR_ALWAYS_INLINE
static inline void __eclic_enable_interrupt (uint32_t irq) {
*(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 1;
}
TU_ATTR_ALWAYS_INLINE
static inline void __eclic_disable_interrupt (uint32_t irq){
*(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 0;
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_enable(uint8_t rhport)
{
(void) rhport;
__eclic_enable_interrupt(RHPORT_IRQn);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_disable (uint8_t rhport)
{
(void) rhport;
__eclic_disable_interrupt(RHPORT_IRQn);
}
static inline void dwc2_remote_wakeup_delay(void)
{
// try to delay for 1 ms
uint32_t count = SystemCoreClock / 1000;
while ( count-- ) __asm volatile ("nop");
}
// MCU specific PHY init, called BEFORE core reset
static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// nothing to do
}
// MCU specific PHY update, it is called AFTER init() and core reset
static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
(void) dwc2;
(void) hs_phy_type;
// nothing to do
}
#ifdef __cplusplus
}
#endif
#endif /* DWC2_GD32_H_ */

View File

@ -0,0 +1,205 @@
/*
* 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 _DWC2_STM32_H_
#define _DWC2_STM32_H_
#ifdef __cplusplus
extern "C" {
#endif
// EP_MAX : Max number of bi-directional endpoints including EP0
// EP_FIFO_SIZE : Size of dedicated USB SRAM
#if CFG_TUSB_MCU == OPT_MCU_STM32F1
#include "stm32f1xx.h"
#define EP_MAX_FS 4
#define EP_FIFO_SIZE_FS 1280
#elif CFG_TUSB_MCU == OPT_MCU_STM32F2
#include "stm32f2xx.h"
#define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS
#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
#elif CFG_TUSB_MCU == OPT_MCU_STM32F4
#include "stm32f4xx.h"
#define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS
#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
#define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS
#define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE
#elif CFG_TUSB_MCU == OPT_MCU_STM32H7
#include "stm32h7xx.h"
#define EP_MAX_FS 9
#define EP_FIFO_SIZE_FS 4096
#define EP_MAX_HS 9
#define EP_FIFO_SIZE_HS 4096
#elif CFG_TUSB_MCU == OPT_MCU_STM32F7
#include "stm32f7xx.h"
#define EP_MAX_FS 6
#define EP_FIFO_SIZE_FS 1280
#define EP_MAX_HS 9
#define EP_FIFO_SIZE_HS 4096
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
#include "stm32l4xx.h"
#define EP_MAX_FS 6
#define EP_FIFO_SIZE_FS 1280
#else
#error "Unsupported MCUs"
#endif
// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS
#if TUD_OPT_RHPORT == 0
#define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE
#define DWC2_EP_MAX EP_MAX_FS
#define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_FS
#define RHPORT_IRQn OTG_FS_IRQn
#else
#define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE
#define DWC2_EP_MAX EP_MAX_HS
#define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_HS
#define RHPORT_IRQn OTG_HS_IRQn
#endif
extern uint32_t SystemCoreClock;
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_enable(uint8_t rhport)
{
(void) rhport;
NVIC_EnableIRQ(RHPORT_IRQn);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_dcd_int_disable (uint8_t rhport)
{
(void) rhport;
NVIC_DisableIRQ(RHPORT_IRQn);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_remote_wakeup_delay(void)
{
// try to delay for 1 ms
uint32_t count = SystemCoreClock / 1000;
while ( count-- ) __NOP();
}
// MCU specific PHY init, called BEFORE core reset
static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
if ( hs_phy_type == HS_PHY_TYPE_NONE )
{
// Enable on-chip FS PHY
dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN;
}else
{
// Disable FS PHY
dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN;
// Enable on-chip HS PHY
if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI)
{
#ifdef USB_HS_PHYC
// Enable UTMI HS PHY
dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN;
// Enable LDO
USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
// Wait until LDO ready
while ( 0 == (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
uint32_t phyc_pll = 0;
// TODO Try to get HSE_VALUE from registers instead of depending CFLAGS
switch ( HSE_VALUE )
{
case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break;
case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break;
case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break;
case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break;
case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break;
case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header
default:
TU_ASSERT(false, );
}
USB_HS_PHYC->USB_HS_PHYC_PLL = phyc_pll;
// Control the tuning interface of the High Speed PHY
// Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver for F7
USB_HS_PHYC->USB_HS_PHYC_TUNE |= 0x00000F13U;
// Enable PLL internal PHY
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
#endif
}
}
}
// MCU specific PHY update, it is called AFTER init() and core reset
static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
{
// used to set turnaround time for fullspeed, nothing to do in highspeed mode
if ( hs_phy_type == HS_PHY_TYPE_NONE )
{
// Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual
uint32_t turnaround;
if ( SystemCoreClock >= 32000000u )
turnaround = 0x6u;
else if ( SystemCoreClock >= 27500000u )
turnaround = 0x7u;
else if ( SystemCoreClock >= 24000000u )
turnaround = 0x8u;
else if ( SystemCoreClock >= 21800000u )
turnaround = 0x9u;
else if ( SystemCoreClock >= 20000000u )
turnaround = 0xAu;
else if ( SystemCoreClock >= 18500000u )
turnaround = 0xBu;
else if ( SystemCoreClock >= 17200000u )
turnaround = 0xCu;
else if ( SystemCoreClock >= 16000000u )
turnaround = 0xDu;
else if ( SystemCoreClock >= 15000000u )
turnaround = 0xEu;
else
turnaround = 0xFu;
dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos);
}
}
#ifdef __cplusplus
}
#endif
#endif /* _DWC2_STM32_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,722 @@
# DWC2 Hardware Configuration Registers
## Broadcom BCM2711 (Pi4)
dwc2->guid = 2708A000
dwc2->gsnpsid = 4F54280A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 228DDD50
hw_cfg2->op_mode = 0
hw_cfg2->arch = 2
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 1
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 7
hw_cfg2->num_host_ch = 7
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 0
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = FF000E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 0
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 0
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 0
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 4080
dwc2->ghwcfg4 = 1FF00020
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 0
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 0
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 15
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## EFM32GG FS
dwc2->guid = 0
dwc2->gsnpsid = 4F54330A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 228F5910
hw_cfg2->op_mode = 0
hw_cfg2->arch = 2
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 6
hw_cfg2->num_host_ch = 13
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 0
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 1F204E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 0
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 1
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 0
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 0
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 498
dwc2->ghwcfg4 = 1BF08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 13
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## ESP32-S2 Fullspeed
dwc2->guid = 0
dwc2->gsnpsid = 4F54400A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 224DD930
hw_cfg2->op_mode = 2
hw_cfg2->arch = 3
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 1
hw_cfg2->fs_phy_type = 2
hw_cfg2->num_dev_ep = 6
hw_cfg2->num_host_ch = 9
hw_cfg2->period_channel_support = 0
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 1
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 22
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = C804B5
hw_cfg3->xfer_size_width = 10
hw_cfg3->packet_size_width = 5
hw_cfg3->otg_enable = 0
hw_cfg3->i2c_enable = 0
hw_cfg3->vendor_ctrl_itf = 1
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 1
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 23130
dwc2->ghwcfg4 = D3F0A030
hw_cfg4->num_dev_period_in_ep = 10
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 0
hw_cfg4->hibernation = 1
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 1
hw_cfg4->acg_enable = 1
hw_cfg4->utmi_phy_data_width = 1
hw_cfg4->dev_ctrl_ep_num = 10
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 0
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 0
hw_cfg4->dedicated_fifos = 0
hw_cfg4->num_dev_in_eps = 13
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 1
## STM32F407 and STM32F207
STM32F407 and STM32F207 are exactly the same
### STM32F407 Fullspeed
dwc2->guid = 1200
dwc2->gsnpsid = 4F54281A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229DCD20
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 1
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 3
hw_cfg2->num_host_ch = 7
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 20001E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 0
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 0
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 512
dwc2->ghwcfg4 = FF08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 7
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
### STM32F407 Highspeed
dwc2->guid = 1100
dwc2->gsnpsid = 4F54281A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229ED590
hw_cfg2->op_mode = 0
hw_cfg2->arch = 2
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 2
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 5
hw_cfg2->num_host_ch = 11
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 3F403E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 1
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 0
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 0
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 1012
dwc2->ghwcfg4 = 17F00030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 0
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 11
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## STM32F411 Fullspeed
dwc2->guid = 1200
dwc2->gsnpsid = 4F54281A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229DCD20
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 1
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 3
hw_cfg2->num_host_ch = 7
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 20001E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 0
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 0
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 512
dwc2->ghwcfg4 = FF08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 7
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## STM32F412 FS
dwc2->guid = 2000
dwc2->gsnpsid = 4F54320A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229ED520
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 1
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 5
hw_cfg2->num_host_ch = 11
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 200D1E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 1
hw_cfg3->total_fifo_size = 512
dwc2->ghwcfg4 = 17F08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 11
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## STM32F723
### STM32F723 HighSpeed
dwc2->guid = 3100
dwc2->gsnpsid = 4F54330A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229FE1D0
hw_cfg2->op_mode = 0
hw_cfg2->arch = 2
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 3
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 8
hw_cfg2->num_host_ch = 15
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 3EED2E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 0
hw_cfg3->vendor_ctrl_itf = 1
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 1
hw_cfg3->total_fifo_size = 1006
dwc2->ghwcfg4 = 23F00030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 0
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 1
hw_cfg4->dma_desc_enable = 1
hw_cfg4->dma_dynamic = 0
### STM32F723 Fullspeed
dwc2->guid = 3000
dwc2->gsnpsid = 4F54330A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229ED520
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 1
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 5
hw_cfg2->num_host_ch = 11
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 200D1E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 1
hw_cfg3->total_fifo_size = 512
dwc2->ghwcfg4 = 17F08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 11
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## STM32F767 FS
dwc2->guid = 2000
dwc2->gsnpsid = 4F54320A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229ED520
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 1
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 5
hw_cfg2->num_host_ch = 11
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 200D1E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 1
hw_cfg3->total_fifo_size = 512
dwc2->ghwcfg4 = 17F08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 11
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## STM32H743 (both cores HS)
dwc2->guid = 2300
dwc2->gsnpsid = 4F54330A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229FE190
hw_cfg2->op_mode = 0
hw_cfg2->arch = 2
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 2
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 8
hw_cfg2->num_host_ch = 15
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 3B8D2E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 0
hw_cfg3->vendor_ctrl_itf = 1
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 1
hw_cfg3->total_fifo_size = 952
dwc2->ghwcfg4 = E3F00030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 0
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 1
hw_cfg4->dma_desc_enable = 1
hw_cfg4->dma_dynamic = 1
## STM32L476 FS
dwc2->guid = 2000
dwc2->gsnpsid = 4F54310A
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 229ED520
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 1
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 1
hw_cfg2->num_dev_ep = 5
hw_cfg2->num_host_ch = 11
hw_cfg2->period_channel_support = 1
hw_cfg2->enable_dynamic_fifo = 1
hw_cfg2->mul_cpu_int = 1
hw_cfg2->nperiod_tx_q_depth = 2
hw_cfg2->host_period_tx_q_depth = 2
hw_cfg2->dev_token_q_depth = 8
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 200D1E8
hw_cfg3->xfer_size_width = 8
hw_cfg3->packet_size_width = 6
hw_cfg3->otg_enable = 1
hw_cfg3->i2c_enable = 1
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 1
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 1
hw_cfg3->lpm_mode = 1
hw_cfg3->total_fifo_size = 512
dwc2->ghwcfg4 = 17F08030
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 1
hw_cfg4->ahb_freq_min = 1
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 2
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 1
hw_cfg4->vbus_valid_filter_enabled = 1
hw_cfg4->a_valid_filter_enabled = 1
hw_cfg4->b_valid_filter_enabled = 1
hw_cfg4->dedicated_fifos = 1
hw_cfg4->num_dev_in_eps = 11
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0
## GD32VF103 Fullspeed
dwc2->guid = 1000
dwc2->gsnpsid = 0
dwc2->ghwcfg1 = 0
dwc2->ghwcfg2 = 0
hw_cfg2->op_mode = 0
hw_cfg2->arch = 0
hw_cfg2->point2point = 0
hw_cfg2->hs_phy_type = 0
hw_cfg2->fs_phy_type = 0
hw_cfg2->num_dev_ep = 0
hw_cfg2->num_host_ch = 0
hw_cfg2->period_channel_support = 0
hw_cfg2->enable_dynamic_fifo = 0
hw_cfg2->mul_cpu_int = 0
hw_cfg2->nperiod_tx_q_depth = 0
hw_cfg2->host_period_tx_q_depth = 0
hw_cfg2->dev_token_q_depth = 0
hw_cfg2->otg_enable_ic_usb = 0
dwc2->ghwcfg3 = 0
hw_cfg3->xfer_size_width = 0
hw_cfg3->packet_size_width = 0
hw_cfg3->otg_enable = 0
hw_cfg3->i2c_enable = 0
hw_cfg3->vendor_ctrl_itf = 0
hw_cfg3->optional_feature_removed = 0
hw_cfg3->synch_reset = 0
hw_cfg3->otg_adp_support = 0
hw_cfg3->otg_enable_hsic = 0
hw_cfg3->battery_charger_support = 0
hw_cfg3->lpm_mode = 0
hw_cfg3->total_fifo_size = 0
dwc2->ghwcfg4 = 0
hw_cfg4->num_dev_period_in_ep = 0
hw_cfg4->power_optimized = 0
hw_cfg4->ahb_freq_min = 0
hw_cfg4->hibernation = 0
hw_cfg4->service_interval_mode = 0
hw_cfg4->ipg_isoc_en = 0
hw_cfg4->acg_enable = 0
hw_cfg4->utmi_phy_data_width = 0
hw_cfg4->dev_ctrl_ep_num = 0
hw_cfg4->iddg_filter_enabled = 0
hw_cfg4->vbus_valid_filter_enabled = 0
hw_cfg4->a_valid_filter_enabled = 0
hw_cfg4->b_valid_filter_enabled = 0
hw_cfg4->dedicated_fifos = 0
hw_cfg4->num_dev_in_eps = 0
hw_cfg4->dma_desc_enable = 0
hw_cfg4->dma_dynamic = 0

View File

@ -27,6 +27,8 @@
#ifndef _TUSB_OPTION_H_
#define _TUSB_OPTION_H_
#include "common/tusb_compiler.h"
#define TUSB_VERSION_MAJOR 0
#define TUSB_VERSION_MINOR 12
#define TUSB_VERSION_REVISION 0
@ -36,7 +38,6 @@
// Supported MCUs
// CFG_TUSB_MCU must be defined to one of following value
//--------------------------------------------------------------------+
#define TU_CHECK_MCU(_m) (CFG_TUSB_MCU == OPT_MCU_##_m)
#define OPT_MCU_NONE 0
@ -112,8 +113,6 @@
// Silabs
#define OPT_MCU_EFM32GG 1300 ///< Silabs EFM32GG
#define OPT_MCU_EFM32GG11 1301 ///< Silabs EFM32GG11
#define OPT_MCU_EFM32GG12 1302 ///< Silabs EFM32GG12
// Renesas RX
#define OPT_MCU_RX63X 1400 ///< Renesas RX63N/631
@ -126,6 +125,14 @@
// GigaDevice
#define OPT_MCU_GD32VF103 1600 ///< GigaDevice GD32VF103
// Broadcom
#define OPT_MCU_BCM2711 1700 ///< Broadcom BCM2711
// Helper to check if configured MCU is one of listed
// Apply _TU_CHECK_MCU with || as separator to list of input
#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m)
#define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__))
//--------------------------------------------------------------------+
// Supported OS
//--------------------------------------------------------------------+