Files
tinyUSB/src/portable/st/stm32_fsdev/fsdev_stm32.h
hathach 91e5a066c5 more fsdev clean up
hil test boards in parallel
2024-08-02 17:12:28 +07:00

331 lines
10 KiB
C

/*
* The MIT License (MIT)
*
* Copyright(c) N Conrad
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* 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.
*
* This file is part of the TinyUSB stack.
*/
#ifndef TUSB_FSDEV_STM32_H
#define TUSB_FSDEV_STM32_H
#if CFG_TUSB_MCU == OPT_MCU_STM32F0
#include "stm32f0xx.h"
#define FSDEV_PMA_SIZE (1024u)
#define FSDEV_REG_BASE USB_BASE
// F0x2 models are crystal-less
// All have internal D+ pull-up
// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support
// PMA dedicated to USB (no sharing with CAN)
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
#include "stm32f1xx.h"
#define FSDEV_PMA_SIZE (512u)
// NO internal Pull-ups
// *B, and *C: 2 x 16 bits/word
// F1 names this differently from the rest
#define USB_CNTR_LPMODE USB_CNTR_LP_MODE
#elif defined(STM32F302xB) || defined(STM32F302xC) || \
defined(STM32F303xB) || defined(STM32F303xC) || \
defined(STM32F373xC)
#include "stm32f3xx.h"
#define FSDEV_PMA_SIZE (512u)
// NO internal Pull-ups
// *B, and *C: 1 x 16 bits/word
// PMA dedicated to USB (no sharing with CAN)
#elif defined(STM32F302x6) || defined(STM32F302x8) || \
defined(STM32F302xD) || defined(STM32F302xE) || \
defined(STM32F303xD) || defined(STM32F303xE)
#include "stm32f3xx.h"
#define FSDEV_PMA_SIZE (1024u)
// NO internal Pull-ups
// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support
// When CAN clock is enabled, USB can use first 768 bytes ONLY.
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
#include "stm32l0xx.h"
#define FSDEV_PMA_SIZE (1024u)
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
#include "stm32l1xx.h"
#define FSDEV_PMA_SIZE (512u)
#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
#include "stm32g4xx.h"
#define FSDEV_PMA_SIZE (1024u)
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
#include "stm32g0xx.h"
#define FSDEV_PMA_SIZE (2048u)
#define USB USB_DRD_FS
#define USB_EP_CTR_RX USB_EP_VTRX
#define USB_EP_CTR_TX USB_EP_VTTX
#define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
#define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
#define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
#define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
#define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
#define USB_EPRX_STAT USB_CH_RX_VALID
#define USB_EPKIND_MASK USB_EP_KIND_MASK
#define USB_CNTR_FRES USB_CNTR_USBRST
#define USB_CNTR_RESUME USB_CNTR_L2RES
#define USB_ISTR_EP_ID USB_ISTR_IDN
#define USB_EPADDR_FIELD USB_CHEP_ADDR
#define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
#define USB_CNTR_FSUSP USB_CNTR_SUSPEN
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
#include "stm32h5xx.h"
#define FSDEV_PMA_SIZE (2048u)
#define USB USB_DRD_FS
#define USB_EP_CTR_RX USB_EP_VTRX
#define USB_EP_CTR_TX USB_EP_VTTX
#define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
#define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
#define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
#define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
#define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
#define USB_EPRX_STAT USB_CH_RX_VALID
#define USB_EPKIND_MASK USB_EP_KIND_MASK
#define USB_CNTR_FRES USB_CNTR_USBRST
#define USB_CNTR_RESUME USB_CNTR_L2RES
#define USB_ISTR_EP_ID USB_ISTR_IDN
#define USB_EPADDR_FIELD USB_CHEP_ADDR
#define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
#define USB_CNTR_FSUSP USB_CNTR_SUSPEN
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
#include "stm32wbxx.h"
#define FSDEV_PMA_SIZE (1024u)
/* ST provided header has incorrect value of USB_PMAADDR */
#define FSDEV_PMA_BASE USB1_PMAADDR
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
#include "stm32l4xx.h"
#define FSDEV_PMA_SIZE (1024u)
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
#include "stm32l5xx.h"
#define FSDEV_PMA_SIZE (1024u)
#ifndef USB_PMAADDR
#define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
#endif
#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
#include "stm32u5xx.h"
#define FSDEV_PMA_SIZE (2048u)
#define USB USB_DRD_FS
#define USB_EP_CTR_RX USB_EP_VTRX
#define USB_EP_CTR_TX USB_EP_VTTX
#define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
#define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
#define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
#define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
#define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
#define USB_EPRX_STAT USB_CH_RX_VALID
#define USB_EPKIND_MASK USB_EP_KIND_MASK
#define USB_CNTR_FRES USB_CNTR_USBRST
#define USB_CNTR_RESUME USB_CNTR_L2RES
#define USB_ISTR_EP_ID USB_ISTR_IDN
#define USB_EPADDR_FIELD USB_CHEP_ADDR
#define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
#define USB_CNTR_FSUSP USB_CNTR_SUSPEN
#else
#error You are using an untested or unimplemented STM32 variant. Please update the driver.
// This includes U0
#endif
//--------------------------------------------------------------------+
// Register and PMA Base Address
//--------------------------------------------------------------------+
#ifndef FSDEV_REG_BASE
#if defined(USB_BASE)
#define FSDEV_REG_BASE USB_BASE
#elif defined(USB_DRD_BASE)
#define FSDEV_REG_BASE USB_DRD_BASE
#elif defined(USB_DRD_FS_BASE)
#define FSDEV_REG_BASE USB_DRD_FS_BASE
#else
#error "FSDEV_REG_BASE not defined"
#endif
#endif
#ifndef FSDEV_PMA_BASE
#if defined(USB_PMAADDR)
#define FSDEV_PMA_BASE USB_PMAADDR
#elif defined(USB_DRD_PMAADDR)
#define FSDEV_PMA_BASE USB_DRD_PMAADDR
#else
#error "FSDEV_PMA_BASE not defined"
#endif
#endif
// This checks if the device has "LPM"
#if defined(USB_ISTR_L1REQ)
#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ)
#else
#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U)
#endif
#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \
USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED )
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
#if TU_CHECK_MCU(OPT_MCU_STM32L1) && !defined(USBWakeUp_IRQn)
#define USBWakeUp_IRQn USB_FS_WKUP_IRQn
#endif
static const IRQn_Type fsdev_irq[] = {
#if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4)
USB_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
USB_HP_CAN1_TX_IRQn,
USB_LP_CAN1_RX0_IRQn,
USBWakeUp_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32F3
// USB remap handles dcd functions
USB_HP_CAN_TX_IRQn,
USB_LP_CAN_RX0_IRQn,
USBWakeUp_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
#ifdef STM32G0B0xx
USB_IRQn,
#else
USB_UCPD1_2_IRQn,
#endif
#elif TU_CHECK_MCU(OPT_MCU_STM32G4, OPT_MCU_STM32L1)
USB_HP_IRQn,
USB_LP_IRQn,
USBWakeUp_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
USB_DRD_FS_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
USB_FS_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
USB_HP_IRQn,
USB_LP_IRQn,
#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
USB_IRQn,
#else
#error Unknown arch in USB driver
#endif
};
enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
void dcd_int_enable(uint8_t rhport) {
(void)rhport;
// forces write to RAM before allowing ISR to execute
__DSB(); __ISB();
#if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP)
// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from
// shared USB/CAN IRQs to separate CAN and USB IRQs.
// This dynamically checks if this remap is active to enable the right IRQs.
if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) {
NVIC_EnableIRQ(USB_HP_IRQn);
NVIC_EnableIRQ(USB_LP_IRQn);
NVIC_EnableIRQ(USBWakeUp_RMP_IRQn);
} else
#endif
{
for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) {
NVIC_EnableIRQ(fsdev_irq[i]);
}
}
}
void dcd_int_disable(uint8_t rhport) {
(void)rhport;
#if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP)
// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from
// shared USB/CAN IRQs to separate CAN and USB IRQs.
// This dynamically checks if this remap is active to enable the right IRQs.
if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) {
NVIC_DisableIRQ(USB_HP_IRQn);
NVIC_DisableIRQ(USB_LP_IRQn);
NVIC_DisableIRQ(USBWakeUp_RMP_IRQn);
} else
#endif
{
for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) {
NVIC_DisableIRQ(fsdev_irq[i]);
}
}
// CMSIS has a membar after disabling interrupts
}
// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU.
#if defined(USB_BCDR_DPPU)
void dcd_disconnect(uint8_t rhport) {
(void)rhport;
USB->BCDR &= ~(USB_BCDR_DPPU);
}
void dcd_connect(uint8_t rhport) {
(void)rhport;
USB->BCDR |= USB_BCDR_DPPU;
}
#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151
void dcd_disconnect(uint8_t rhport) {
(void)rhport;
SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU);
}
void dcd_connect(uint8_t rhport) {
(void)rhport;
SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
}
#endif
#endif /* TUSB_FSDEV_STM32_H */