add ch32 support for fsdev driver. v20x can select fsdev or usbfs with make/cmake PORT=0/1. default to fsdev
This commit is contained in:
		@@ -102,25 +102,29 @@
 | 
			
		||||
 | 
			
		||||
#include "tusb_option.h"
 | 
			
		||||
 | 
			
		||||
#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV)
 | 
			
		||||
#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && \
 | 
			
		||||
    !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
 | 
			
		||||
 | 
			
		||||
#include "device/dcd.h"
 | 
			
		||||
 | 
			
		||||
#ifdef TUP_USBIP_FSDEV_STM32
 | 
			
		||||
// Undefine to reduce the dependence on HAL
 | 
			
		||||
#undef USE_HAL_DRIVER
 | 
			
		||||
#include "portable/st/stm32_fsdev/dcd_stm32_fsdev.h"
 | 
			
		||||
#if defined(TUP_USBIP_FSDEV_STM32)
 | 
			
		||||
  // Undefine to reduce the dependence on HAL
 | 
			
		||||
  #undef USE_HAL_DRIVER
 | 
			
		||||
  #include "fsdev_stm32.h"
 | 
			
		||||
#elif defined(TUP_USBIP_FSDEV_CH32)
 | 
			
		||||
  #include "fsdev_ch32.h"
 | 
			
		||||
#else
 | 
			
		||||
  #error "Unknown USB IP"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*****************************************************
 | 
			
		||||
 * Configuration
 | 
			
		||||
 *****************************************************/
 | 
			
		||||
#include "fsdev_common.h"
 | 
			
		||||
 | 
			
		||||
// HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM
 | 
			
		||||
// (8u here would mean 8 IN and 8 OUT)
 | 
			
		||||
#ifndef MAX_EP_COUNT
 | 
			
		||||
#define MAX_EP_COUNT 8U
 | 
			
		||||
#endif
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
// Configuration
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
// hardware limit endpoint
 | 
			
		||||
#define FSDEV_EP_COUNT 8
 | 
			
		||||
 | 
			
		||||
// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it
 | 
			
		||||
// Both of these MUST be a multiple of 2, and are in byte units.
 | 
			
		||||
@@ -132,11 +136,6 @@
 | 
			
		||||
#define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/***************************************************
 | 
			
		||||
 * Checks, structs, defines, function definitions, etc.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware");
 | 
			
		||||
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM");
 | 
			
		||||
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes");
 | 
			
		||||
 | 
			
		||||
@@ -162,9 +161,9 @@ typedef struct {
 | 
			
		||||
  bool allocated[2];
 | 
			
		||||
} ep_alloc_t;
 | 
			
		||||
 | 
			
		||||
static xfer_ctl_t xfer_status[MAX_EP_COUNT][2];
 | 
			
		||||
static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2];
 | 
			
		||||
 | 
			
		||||
static ep_alloc_t ep_alloc_status[STFSDEV_EP_COUNT];
 | 
			
		||||
static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT];
 | 
			
		||||
 | 
			
		||||
static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6];
 | 
			
		||||
 | 
			
		||||
@@ -199,7 +198,7 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr)
 | 
			
		||||
  uint8_t epnum = tu_edpt_number(ep_addr);
 | 
			
		||||
  uint8_t dir = tu_edpt_dir(ep_addr);
 | 
			
		||||
  // Fix -Werror=null-dereference
 | 
			
		||||
  TU_ASSERT(epnum < MAX_EP_COUNT, &xfer_status[0][0]);
 | 
			
		||||
  TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX, &xfer_status[0][0]);
 | 
			
		||||
 | 
			
		||||
  return &xfer_status[epnum][dir];
 | 
			
		||||
}
 | 
			
		||||
@@ -239,7 +238,7 @@ void dcd_init(uint8_t rhport)
 | 
			
		||||
  USB->ISTR = 0; // Clear pending interrupts
 | 
			
		||||
 | 
			
		||||
  // Reset endpoints to disabled
 | 
			
		||||
  for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) {
 | 
			
		||||
  for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) {
 | 
			
		||||
    // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED.
 | 
			
		||||
    pcd_set_endpoint(USB, i, 0u);
 | 
			
		||||
  }
 | 
			
		||||
@@ -248,43 +247,9 @@ void dcd_init(uint8_t rhport)
 | 
			
		||||
  dcd_handle_bus_reset();
 | 
			
		||||
 | 
			
		||||
  // Enable pull-up if supported
 | 
			
		||||
  if (dcd_connect) {
 | 
			
		||||
    dcd_connect(rhport);
 | 
			
		||||
  }
 | 
			
		||||
  dcd_connect(rhport);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU.
 | 
			
		||||
#if defined(USB_BCDR_DPPU)
 | 
			
		||||
 | 
			
		||||
// Disable internal D+ PU
 | 
			
		||||
void dcd_disconnect(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  USB->BCDR &= ~(USB_BCDR_DPPU);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Enable internal D+ PU
 | 
			
		||||
void dcd_connect(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  USB->BCDR |= USB_BCDR_DPPU;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151
 | 
			
		||||
// Disable internal D+ PU
 | 
			
		||||
void dcd_disconnect(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Enable internal D+ PU
 | 
			
		||||
void dcd_connect(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void dcd_sof_enable(uint8_t rhport, bool en)
 | 
			
		||||
{
 | 
			
		||||
@@ -298,126 +263,6 @@ void dcd_sof_enable(uint8_t rhport, bool en)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Enable device interrupt
 | 
			
		||||
void dcd_int_enable(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  // Member here forces write to RAM before allowing ISR to execute
 | 
			
		||||
  __DSB();
 | 
			
		||||
  __ISB();
 | 
			
		||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4
 | 
			
		||||
  NVIC_EnableIRQ(USB_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
 | 
			
		||||
  NVIC_EnableIRQ(USB_LP_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32F3
 | 
			
		||||
// 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.
 | 
			
		||||
#ifdef SYSCFG_CFGR1_USB_IT_RMP
 | 
			
		||||
  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
 | 
			
		||||
  {
 | 
			
		||||
    NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn);
 | 
			
		||||
    NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
 | 
			
		||||
    NVIC_EnableIRQ(USBWakeUp_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
 | 
			
		||||
  NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
 | 
			
		||||
  NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
 | 
			
		||||
  NVIC_EnableIRQ(USBWakeUp_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
 | 
			
		||||
  NVIC_EnableIRQ(USB_HP_IRQn);
 | 
			
		||||
  NVIC_EnableIRQ(USB_LP_IRQn);
 | 
			
		||||
  NVIC_EnableIRQ(USBWakeUp_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
 | 
			
		||||
#ifdef STM32G0B0xx
 | 
			
		||||
  NVIC_EnableIRQ(USB_IRQn);
 | 
			
		||||
#else
 | 
			
		||||
  NVIC_EnableIRQ(USB_UCPD1_2_IRQn);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
 | 
			
		||||
  NVIC_EnableIRQ(USB_DRD_FS_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
 | 
			
		||||
  NVIC_EnableIRQ(USB_HP_IRQn);
 | 
			
		||||
  NVIC_EnableIRQ(USB_LP_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
 | 
			
		||||
  NVIC_EnableIRQ(USB_FS_IRQn);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#error Unknown arch in USB driver
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Disable device interrupt
 | 
			
		||||
void dcd_int_disable(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
 | 
			
		||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4
 | 
			
		||||
  NVIC_DisableIRQ(USB_IRQn);
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
 | 
			
		||||
  NVIC_DisableIRQ(USB_LP_IRQn);
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32F3
 | 
			
		||||
// 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 disable the right IRQs.
 | 
			
		||||
#ifdef SYSCFG_CFGR1_USB_IT_RMP
 | 
			
		||||
  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
 | 
			
		||||
  {
 | 
			
		||||
    NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn);
 | 
			
		||||
    NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn);
 | 
			
		||||
    NVIC_DisableIRQ(USBWakeUp_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
 | 
			
		||||
  NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USBWakeUp_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
 | 
			
		||||
  NVIC_DisableIRQ(USB_HP_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USB_LP_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USBWakeUp_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
 | 
			
		||||
#ifdef STM32G0B0xx
 | 
			
		||||
  NVIC_DisableIRQ(USB_IRQn);
 | 
			
		||||
#else
 | 
			
		||||
  NVIC_DisableIRQ(USB_UCPD1_2_IRQn);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
 | 
			
		||||
  NVIC_DisableIRQ(USB_DRD_FS_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
 | 
			
		||||
  NVIC_DisableIRQ(USB_HP_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USB_LP_IRQn);
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
 | 
			
		||||
  NVIC_DisableIRQ(USB_FS_IRQn);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#error Unknown arch in USB driver
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // CMSIS has a membar after disabling interrupts
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Receive Set Address request, mcu port must also include status IN response
 | 
			
		||||
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
 | 
			
		||||
{
 | 
			
		||||
@@ -461,7 +306,7 @@ static void dcd_handle_bus_reset(void)
 | 
			
		||||
{
 | 
			
		||||
  USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag
 | 
			
		||||
 | 
			
		||||
  for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) {
 | 
			
		||||
  for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) {
 | 
			
		||||
    // Clear EP allocation status
 | 
			
		||||
    ep_alloc_status[i].ep_num = 0xFF;
 | 
			
		||||
    ep_alloc_status[i].ep_type = 0xFF;
 | 
			
		||||
@@ -470,7 +315,7 @@ static void dcd_handle_bus_reset(void)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reset PMA allocation
 | 
			
		||||
  ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT;
 | 
			
		||||
  ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX;
 | 
			
		||||
 | 
			
		||||
  dcd_edpt_open(0, &ep0OUT_desc);
 | 
			
		||||
  dcd_edpt_open(0, &ep0IN_desc);
 | 
			
		||||
@@ -653,7 +498,6 @@ static void dcd_ep_ctr_handler(void)
 | 
			
		||||
 | 
			
		||||
void dcd_int_handler(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
 | 
			
		||||
  uint32_t int_status = USB->ISTR;
 | 
			
		||||
@@ -774,7 +618,7 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
 | 
			
		||||
  uint8_t const epnum = tu_edpt_number(ep_addr);
 | 
			
		||||
  uint8_t const dir = tu_edpt_dir(ep_addr);
 | 
			
		||||
 | 
			
		||||
  for (uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) {
 | 
			
		||||
  for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
 | 
			
		||||
    // Check if already allocated
 | 
			
		||||
    if (ep_alloc_status[i].allocated[dir] &&
 | 
			
		||||
        ep_alloc_status[i].ep_type == ep_type &&
 | 
			
		||||
@@ -818,7 +662,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc)
 | 
			
		||||
  uint16_t pma_addr;
 | 
			
		||||
  uint32_t wType;
 | 
			
		||||
 | 
			
		||||
  TU_ASSERT(ep_idx < STFSDEV_EP_COUNT);
 | 
			
		||||
  TU_ASSERT(ep_idx < FSDEV_EP_COUNT);
 | 
			
		||||
  TU_ASSERT(buffer_size <= 64);
 | 
			
		||||
 | 
			
		||||
  // Set type
 | 
			
		||||
@@ -865,7 +709,7 @@ void dcd_edpt_close_all(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
 | 
			
		||||
  for (uint32_t i = 1; i < STFSDEV_EP_COUNT; i++) {
 | 
			
		||||
  for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) {
 | 
			
		||||
    // Reset endpoint
 | 
			
		||||
    pcd_set_endpoint(USB, i, 0);
 | 
			
		||||
    // Clear EP allocation status
 | 
			
		||||
@@ -876,7 +720,7 @@ void dcd_edpt_close_all(uint8_t rhport)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reset PMA allocation
 | 
			
		||||
  ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE;
 | 
			
		||||
  ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1155,7 +999,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (wNBytes) {
 | 
			
		||||
    temp1 = *srcVal;
 | 
			
		||||
    temp1 = (uint16_t) *srcVal;
 | 
			
		||||
    *pdwVal = temp1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										232
									
								
								src/portable/st/stm32_fsdev/fsdev_ch32.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								src/portable/st/stm32_fsdev/fsdev_ch32.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,232 @@
 | 
			
		||||
/*
 | 
			
		||||
* The MIT License (MIT)
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2024, hathach (tinyusb.org)
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
/** <h2><center>© Copyright (c) 2016 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
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
#ifndef TUSB_FSDEV_CH32_H
 | 
			
		||||
#define TUSB_FSDEV_CH32_H
 | 
			
		||||
 | 
			
		||||
#include "common/tusb_compiler.h"
 | 
			
		||||
 | 
			
		||||
#if CFG_TUSB_MCU == OPT_MCU_CH32V20X
 | 
			
		||||
  #include <ch32v20x.h>
 | 
			
		||||
 | 
			
		||||
#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X
 | 
			
		||||
  #include <ch32f20x.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define FSDEV_PMA_SIZE (512u)
 | 
			
		||||
 | 
			
		||||
// volatile 32-bit aligned
 | 
			
		||||
#define _va32     volatile TU_ATTR_ALIGNED(4)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  _va32 uint16_t EP0R;            // 00: USB Endpoint 0 register
 | 
			
		||||
  _va32 uint16_t EP1R;            // 04: USB Endpoint 1 register
 | 
			
		||||
  _va32 uint16_t EP2R;            // 08: USB Endpoint 2 register
 | 
			
		||||
  _va32 uint16_t EP3R;            // 0C: USB Endpoint 3 register
 | 
			
		||||
  _va32 uint16_t EP4R;            // 10: USB Endpoint 4 register
 | 
			
		||||
  _va32 uint16_t EP5R;            // 14: USB Endpoint 5 register
 | 
			
		||||
  _va32 uint16_t EP6R;            // 18: USB Endpoint 6 register
 | 
			
		||||
  _va32 uint16_t EP7R;            // 1C: USB Endpoint 7 register
 | 
			
		||||
  _va32 uint16_t RESERVED7[16];   // Reserved
 | 
			
		||||
  _va32 uint16_t CNTR;            // 40: Control register
 | 
			
		||||
  _va32 uint16_t ISTR;            // 44: Interrupt status register
 | 
			
		||||
  _va32 uint16_t FNR;             // 48: Frame number register
 | 
			
		||||
  _va32 uint16_t DADDR;           // 4C: Device address register
 | 
			
		||||
  _va32 uint16_t BTABLE;          // 50: Buffer Table address register
 | 
			
		||||
} USB_TypeDef;
 | 
			
		||||
 | 
			
		||||
TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct");
 | 
			
		||||
TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset");
 | 
			
		||||
 | 
			
		||||
#define USB_BASE            (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */
 | 
			
		||||
#define USB_PMAADDR         (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */
 | 
			
		||||
#define USB                 ((USB_TypeDef *)USB_BASE)
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*                                                                            */
 | 
			
		||||
/*                         USB Device General registers                       */
 | 
			
		||||
/*                                                                            */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
#define USB_CNTR                             (USB_BASE + 0x40U)             /*!< Control register */
 | 
			
		||||
#define USB_ISTR                             (USB_BASE + 0x44U)             /*!< Interrupt status register */
 | 
			
		||||
#define USB_FNR                              (USB_BASE + 0x48U)             /*!< Frame number register */
 | 
			
		||||
#define USB_DADDR                            (USB_BASE + 0x4CU)             /*!< Device address register */
 | 
			
		||||
#define USB_BTABLE                           (USB_BASE + 0x50U)             /*!< Buffer Table address register */
 | 
			
		||||
 | 
			
		||||
/****************************  ISTR interrupt events  *************************/
 | 
			
		||||
#define USB_ISTR_CTR                         ((uint16_t)0x8000U)               /*!< Correct TRansfer (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_PMAOVR                      ((uint16_t)0x4000U)               /*!< DMA OVeR/underrun (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_ERR                         ((uint16_t)0x2000U)               /*!< ERRor (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_WKUP                        ((uint16_t)0x1000U)               /*!< WaKe UP (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_SUSP                        ((uint16_t)0x0800U)               /*!< SUSPend (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_RESET                       ((uint16_t)0x0400U)               /*!< RESET (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_SOF                         ((uint16_t)0x0200U)               /*!< Start Of Frame (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_ESOF                        ((uint16_t)0x0100U)               /*!< Expected Start Of Frame (clear-only bit) */
 | 
			
		||||
#define USB_ISTR_DIR                         ((uint16_t)0x0010U)               /*!< DIRection of transaction (read-only bit)  */
 | 
			
		||||
#define USB_ISTR_EP_ID                       ((uint16_t)0x000FU)               /*!< EndPoint IDentifier (read-only bit)  */
 | 
			
		||||
 | 
			
		||||
/* Legacy defines */
 | 
			
		||||
#define USB_ISTR_PMAOVRM USB_ISTR_PMAOVR
 | 
			
		||||
 | 
			
		||||
#define USB_CLR_CTR                          (~USB_ISTR_CTR)             /*!< clear Correct TRansfer bit */
 | 
			
		||||
#define USB_CLR_PMAOVR                       (~USB_ISTR_PMAOVR)          /*!< clear DMA OVeR/underrun bit*/
 | 
			
		||||
#define USB_CLR_ERR                          (~USB_ISTR_ERR)             /*!< clear ERRor bit */
 | 
			
		||||
#define USB_CLR_WKUP                         (~USB_ISTR_WKUP)            /*!< clear WaKe UP bit */
 | 
			
		||||
#define USB_CLR_SUSP                         (~USB_ISTR_SUSP)            /*!< clear SUSPend bit */
 | 
			
		||||
#define USB_CLR_RESET                        (~USB_ISTR_RESET)           /*!< clear RESET bit */
 | 
			
		||||
#define USB_CLR_SOF                          (~USB_ISTR_SOF)             /*!< clear Start Of Frame bit */
 | 
			
		||||
#define USB_CLR_ESOF                         (~USB_ISTR_ESOF)            /*!< clear Expected Start Of Frame bit */
 | 
			
		||||
 | 
			
		||||
/* Legacy defines */
 | 
			
		||||
#define USB_CLR_PMAOVRM USB_CLR_PMAOVR
 | 
			
		||||
 | 
			
		||||
/*************************  CNTR control register bits definitions  ***********/
 | 
			
		||||
#define USB_CNTR_CTRM                        ((uint16_t)0x8000U)               /*!< Correct TRansfer Mask */
 | 
			
		||||
#define USB_CNTR_PMAOVR                      ((uint16_t)0x4000U)               /*!< DMA OVeR/underrun Mask */
 | 
			
		||||
#define USB_CNTR_ERRM                        ((uint16_t)0x2000U)               /*!< ERRor Mask */
 | 
			
		||||
#define USB_CNTR_WKUPM                       ((uint16_t)0x1000U)               /*!< WaKe UP Mask */
 | 
			
		||||
#define USB_CNTR_SUSPM                       ((uint16_t)0x0800U)               /*!< SUSPend Mask */
 | 
			
		||||
#define USB_CNTR_RESETM                      ((uint16_t)0x0400U)               /*!< RESET Mask   */
 | 
			
		||||
#define USB_CNTR_SOFM                        ((uint16_t)0x0200U)               /*!< Start Of Frame Mask */
 | 
			
		||||
#define USB_CNTR_ESOFM                       ((uint16_t)0x0100U)               /*!< Expected Start Of Frame Mask */
 | 
			
		||||
#define USB_CNTR_RESUME                      ((uint16_t)0x0010U)               /*!< RESUME request */
 | 
			
		||||
#define USB_CNTR_FSUSP                       ((uint16_t)0x0008U)               /*!< Force SUSPend */
 | 
			
		||||
#define USB_CNTR_LPMODE                      ((uint16_t)0x0004U)               /*!< Low-power MODE */
 | 
			
		||||
#define USB_CNTR_PDWN                        ((uint16_t)0x0002U)               /*!< Power DoWN */
 | 
			
		||||
#define USB_CNTR_FRES                        ((uint16_t)0x0001U)               /*!< Force USB RESet */
 | 
			
		||||
 | 
			
		||||
/* Legacy defines */
 | 
			
		||||
#define USB_CNTR_PMAOVRM USB_CNTR_PMAOVR
 | 
			
		||||
#define USB_CNTR_LP_MODE USB_CNTR_LPMODE
 | 
			
		||||
 | 
			
		||||
/********************  FNR Frame Number Register bit definitions   ************/
 | 
			
		||||
#define USB_FNR_RXDP                         ((uint16_t)0x8000U)               /*!< status of D+ data line */
 | 
			
		||||
#define USB_FNR_RXDM                         ((uint16_t)0x4000U)               /*!< status of D- data line */
 | 
			
		||||
#define USB_FNR_LCK                          ((uint16_t)0x2000U)               /*!< LoCKed */
 | 
			
		||||
#define USB_FNR_LSOF                         ((uint16_t)0x1800U)               /*!< Lost SOF */
 | 
			
		||||
#define USB_FNR_FN                           ((uint16_t)0x07FFU)               /*!< Frame Number */
 | 
			
		||||
 | 
			
		||||
/********************  DADDR Device ADDRess bit definitions    ****************/
 | 
			
		||||
#define USB_DADDR_EF                         ((uint8_t)0x80U)                  /*!< USB device address Enable Function */
 | 
			
		||||
#define USB_DADDR_ADD                        ((uint8_t)0x7FU)                  /*!< USB device address */
 | 
			
		||||
 | 
			
		||||
/******************************  Endpoint register    *************************/
 | 
			
		||||
#define USB_EP0R                             USB_BASE                    /*!< endpoint 0 register address */
 | 
			
		||||
#define USB_EP1R                             (USB_BASE + 0x04U)           /*!< endpoint 1 register address */
 | 
			
		||||
#define USB_EP2R                             (USB_BASE + 0x08U)           /*!< endpoint 2 register address */
 | 
			
		||||
#define USB_EP3R                             (USB_BASE + 0x0CU)           /*!< endpoint 3 register address */
 | 
			
		||||
#define USB_EP4R                             (USB_BASE + 0x10U)           /*!< endpoint 4 register address */
 | 
			
		||||
#define USB_EP5R                             (USB_BASE + 0x14U)           /*!< endpoint 5 register address */
 | 
			
		||||
#define USB_EP6R                             (USB_BASE + 0x18U)           /*!< endpoint 6 register address */
 | 
			
		||||
#define USB_EP7R                             (USB_BASE + 0x1CU)           /*!< endpoint 7 register address */
 | 
			
		||||
/* bit positions */
 | 
			
		||||
#define USB_EP_CTR_RX                        ((uint16_t)0x8000U)               /*!<  EndPoint Correct TRansfer RX */
 | 
			
		||||
#define USB_EP_DTOG_RX                       ((uint16_t)0x4000U)               /*!<  EndPoint Data TOGGLE RX */
 | 
			
		||||
#define USB_EPRX_STAT                        ((uint16_t)0x3000U)               /*!<  EndPoint RX STATus bit field */
 | 
			
		||||
#define USB_EP_SETUP                         ((uint16_t)0x0800U)               /*!<  EndPoint SETUP */
 | 
			
		||||
#define USB_EP_T_FIELD                       ((uint16_t)0x0600U)               /*!<  EndPoint TYPE */
 | 
			
		||||
#define USB_EP_KIND                          ((uint16_t)0x0100U)               /*!<  EndPoint KIND */
 | 
			
		||||
#define USB_EP_CTR_TX                        ((uint16_t)0x0080U)               /*!<  EndPoint Correct TRansfer TX */
 | 
			
		||||
#define USB_EP_DTOG_TX                       ((uint16_t)0x0040U)               /*!<  EndPoint Data TOGGLE TX */
 | 
			
		||||
#define USB_EPTX_STAT                        ((uint16_t)0x0030U)               /*!<  EndPoint TX STATus bit field */
 | 
			
		||||
#define USB_EPADDR_FIELD                     ((uint16_t)0x000FU)               /*!<  EndPoint ADDRess FIELD */
 | 
			
		||||
 | 
			
		||||
/* EndPoint REGister MASK (no toggle fields) */
 | 
			
		||||
#define USB_EPREG_MASK     (USB_EP_CTR_RX|USB_EP_SETUP|USB_EP_T_FIELD|USB_EP_KIND|USB_EP_CTR_TX|USB_EPADDR_FIELD)
 | 
			
		||||
                                                                               /*!< EP_TYPE[1:0] EndPoint TYPE */
 | 
			
		||||
#define USB_EP_TYPE_MASK                     ((uint16_t)0x0600U)               /*!< EndPoint TYPE Mask */
 | 
			
		||||
#define USB_EP_BULK                          ((uint16_t)0x0000U)               /*!< EndPoint BULK */
 | 
			
		||||
#define USB_EP_CONTROL                       ((uint16_t)0x0200U)               /*!< EndPoint CONTROL */
 | 
			
		||||
#define USB_EP_ISOCHRONOUS                   ((uint16_t)0x0400U)               /*!< EndPoint ISOCHRONOUS */
 | 
			
		||||
#define USB_EP_INTERRUPT                     ((uint16_t)0x0600U)               /*!< EndPoint INTERRUPT */
 | 
			
		||||
#define USB_EP_T_MASK                        ((uint16_t) ~USB_EP_T_FIELD & USB_EPREG_MASK)
 | 
			
		||||
 | 
			
		||||
#define USB_EPKIND_MASK                      ((uint16_t) ~USB_EP_KIND & USB_EPREG_MASK)            /*!< EP_KIND EndPoint KIND */
 | 
			
		||||
                                                                               /*!< STAT_TX[1:0] STATus for TX transfer */
 | 
			
		||||
#define USB_EP_TX_DIS                        ((uint16_t)0x0000U)               /*!< EndPoint TX DISabled */
 | 
			
		||||
#define USB_EP_TX_STALL                      ((uint16_t)0x0010U)               /*!< EndPoint TX STALLed */
 | 
			
		||||
#define USB_EP_TX_NAK                        ((uint16_t)0x0020U)               /*!< EndPoint TX NAKed */
 | 
			
		||||
#define USB_EP_TX_VALID                      ((uint16_t)0x0030U)               /*!< EndPoint TX VALID */
 | 
			
		||||
#define USB_EPTX_DTOG1                       ((uint16_t)0x0010U)               /*!< EndPoint TX Data TOGgle bit1 */
 | 
			
		||||
#define USB_EPTX_DTOG2                       ((uint16_t)0x0020U)               /*!< EndPoint TX Data TOGgle bit2 */
 | 
			
		||||
#define USB_EPTX_DTOGMASK  (USB_EPTX_STAT|USB_EPREG_MASK)
 | 
			
		||||
                                                                               /*!< STAT_RX[1:0] STATus for RX transfer */
 | 
			
		||||
#define USB_EP_RX_DIS                        ((uint16_t)0x0000U)               /*!< EndPoint RX DISabled */
 | 
			
		||||
#define USB_EP_RX_STALL                      ((uint16_t)0x1000U)               /*!< EndPoint RX STALLed */
 | 
			
		||||
#define USB_EP_RX_NAK                        ((uint16_t)0x2000U)               /*!< EndPoint RX NAKed */
 | 
			
		||||
#define USB_EP_RX_VALID                      ((uint16_t)0x3000U)               /*!< EndPoint RX VALID */
 | 
			
		||||
#define USB_EPRX_DTOG1                       ((uint16_t)0x1000U)               /*!< EndPoint RX Data TOGgle bit1 */
 | 
			
		||||
#define USB_EPRX_DTOG2                       ((uint16_t)0x2000U)               /*!< EndPoint RX Data TOGgle bit1 */
 | 
			
		||||
#define USB_EPRX_DTOGMASK  (USB_EPRX_STAT|USB_EPREG_MASK)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
//
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
#if CFG_TUSB_MCU == OPT_MCU_CH32V20X
 | 
			
		||||
static const IRQn_Type fsdev_irq[] = {
 | 
			
		||||
  USB_HP_CAN1_TX_IRQn,
 | 
			
		||||
  USB_LP_CAN1_RX0_IRQn,
 | 
			
		||||
  USBWakeUp_IRQn
 | 
			
		||||
};
 | 
			
		||||
enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
 | 
			
		||||
#else
 | 
			
		||||
  #error "Unsupported MCU"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void dcd_int_enable(uint8_t rhport) {
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
 | 
			
		||||
    NVIC_EnableIRQ(fsdev_irq[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dcd_int_disable(uint8_t rhport) {
 | 
			
		||||
  (void)rhport;
 | 
			
		||||
  for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
 | 
			
		||||
    NVIC_DisableIRQ(fsdev_irq[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dcd_disconnect(uint8_t rhport) {
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
  EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dcd_connect(uint8_t rhport) {
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
  EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,174 +1,43 @@
 | 
			
		||||
/*
 | 
			
		||||
 * The MIT License (MIT)
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright(c) 2016 STMicroelectronics
 | 
			
		||||
 * Copyright(c) N Conrad
 | 
			
		||||
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
 | 
			
		||||
 * Copyright (c) 2024, hathach (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.
 | 
			
		||||
 * 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:
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// This file contains source copied from ST's HAL, and thus should have their copyright statement.
 | 
			
		||||
#ifndef TUSB_FSDEV_COMMON_H
 | 
			
		||||
#define TUSB_FSDEV_COMMON_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
 | 
			
		||||
// FSDEV_PMA_SIZE is PMA buffer size in bytes.
 | 
			
		||||
// On 512-byte devices, access with a stride of two words (use every other 16-bit address)
 | 
			
		||||
// On 1024-byte devices, access with a stride of one word (use every 16-bit address)
 | 
			
		||||
 | 
			
		||||
#ifndef PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_
 | 
			
		||||
#define PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_
 | 
			
		||||
 | 
			
		||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F0
 | 
			
		||||
  #include "stm32f0xx.h"
 | 
			
		||||
  #define FSDEV_PMA_SIZE (1024u)
 | 
			
		||||
  // 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_BUS_32BIT
 | 
			
		||||
  #define FSDEV_PMA_SIZE (2048u)
 | 
			
		||||
  #undef USB_PMAADDR
 | 
			
		||||
  #define USB_PMAADDR USB_DRD_PMAADDR
 | 
			
		||||
  #define USB_TypeDef USB_DRD_TypeDef
 | 
			
		||||
  #define EP0R CHEP0R
 | 
			
		||||
  #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 USB_DRD_FS
 | 
			
		||||
  #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_BUS_32BIT
 | 
			
		||||
 | 
			
		||||
  #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE)
 | 
			
		||||
  #define USB_DRD_BASE USB_DRD_FS_BASE
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #define FSDEV_PMA_SIZE (2048u)
 | 
			
		||||
  #undef USB_PMAADDR
 | 
			
		||||
  #define USB_PMAADDR USB_DRD_PMAADDR
 | 
			
		||||
  #define USB_TypeDef USB_DRD_TypeDef
 | 
			
		||||
  #define EP0R CHEP0R
 | 
			
		||||
  #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 USB_DRD_FS
 | 
			
		||||
  #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 */
 | 
			
		||||
  #undef USB_PMAADDR
 | 
			
		||||
  #define USB_PMAADDR 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
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  #error You are using an untested or unimplemented STM32 variant. Please update the driver.
 | 
			
		||||
  // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// For purposes of accessing the packet
 | 
			
		||||
#if ((FSDEV_PMA_SIZE) == 512u)
 | 
			
		||||
  #define FSDEV_PMA_STRIDE  (2u)
 | 
			
		||||
@@ -181,24 +50,24 @@
 | 
			
		||||
// The compiler should warn us if we cast it to a non-volatile type?
 | 
			
		||||
#ifdef FSDEV_BUS_32BIT
 | 
			
		||||
typedef uint32_t fsdev_bus_t;
 | 
			
		||||
static __IO uint32_t * const pma32 = (__IO uint32_t*)USB_PMAADDR;
 | 
			
		||||
static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
typedef uint16_t fsdev_bus_t;
 | 
			
		||||
// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden)
 | 
			
		||||
static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR;
 | 
			
		||||
static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR;
 | 
			
		||||
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) {
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) {
 | 
			
		||||
  size_t total_word_offset = (((USBx)->BTABLE)>>1) + x;
 | 
			
		||||
  total_word_offset *= FSDEV_PMA_STRIDE;
 | 
			
		||||
  return &(pma[total_word_offset]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
 | 
			
		||||
  return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
 | 
			
		||||
  return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -218,10 +87,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t si
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) {
 | 
			
		||||
#ifdef FSDEV_BUS_32BIT
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  __O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4);
 | 
			
		||||
  volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4);
 | 
			
		||||
  *reg = wRegValue;
 | 
			
		||||
#else
 | 
			
		||||
  __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
 | 
			
		||||
  volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
 | 
			
		||||
  *reg = (uint16_t)wRegValue;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -229,9 +98,9 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, ui
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
 | 
			
		||||
#ifdef FSDEV_BUS_32BIT
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  __I uint32_t *reg = (__I uint32_t *)(USB_DRD_BASE + bEpIdx*4);
 | 
			
		||||
  volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4);
 | 
			
		||||
#else
 | 
			
		||||
  __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
 | 
			
		||||
  volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
 | 
			
		||||
#endif
 | 
			
		||||
  return *reg;
 | 
			
		||||
}
 | 
			
		||||
@@ -283,7 +152,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USB
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  return (pma32[2*bEpIdx] & 0x03FF0000) >> 16;
 | 
			
		||||
#else
 | 
			
		||||
  __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  return *regPtr & 0x3ffU;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -293,7 +162,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16;
 | 
			
		||||
#else
 | 
			
		||||
  __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  return *regPtr & 0x3ffU;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -363,7 +232,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, u
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
 | 
			
		||||
#else
 | 
			
		||||
  __IO uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -375,7 +244,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * U
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
 | 
			
		||||
#else
 | 
			
		||||
  __IO uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  volatile uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
 | 
			
		||||
  *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -387,7 +256,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDe
 | 
			
		||||
  (void) USBx;
 | 
			
		||||
  pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26);
 | 
			
		||||
#else
 | 
			
		||||
  __IO uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u);
 | 
			
		||||
  volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u);
 | 
			
		||||
  *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -472,13 +341,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef *
 | 
			
		||||
  return (regVal & USB_EPRX_STAT) >> (12u);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
 | 
			
		||||
  * @param  USBx USB peripheral instance register address.
 | 
			
		||||
  * @param  bEpIdx Endpoint Number.
 | 
			
		||||
  * @retval None
 | 
			
		||||
  */
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx,  uint32_t bEpIdx) {
 | 
			
		||||
  uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
 | 
			
		||||
  regVal &= USB_EPREG_MASK;
 | 
			
		||||
@@ -493,12 +355,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx,  uint32
 | 
			
		||||
  pcd_set_endpoint(USBx, bEpIdx, regVal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register.
 | 
			
		||||
  * @param  USBx USB peripheral instance register address.
 | 
			
		||||
  * @param  bEpIdx Endpoint Number.
 | 
			
		||||
  * @retval None
 | 
			
		||||
  */
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx,  uint32_t bEpIdx) {
 | 
			
		||||
  uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
 | 
			
		||||
  if((regVal & USB_EP_DTOG_RX) != 0) {
 | 
			
		||||
@@ -513,12 +369,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  set & clear EP_KIND bit.
 | 
			
		||||
  * @param  USBx USB peripheral instance register address.
 | 
			
		||||
  * @param  bEpIdx Endpoint Number.
 | 
			
		||||
  * @retval None
 | 
			
		||||
  */
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx,  uint32_t bEpIdx) {
 | 
			
		||||
  uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
 | 
			
		||||
  regVal |= USB_EP_KIND;
 | 
			
		||||
@@ -534,18 +384,8 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, u
 | 
			
		||||
  pcd_set_endpoint(USBx, bEpIdx, regVal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 }
 | 
			
		||||
#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 )
 | 
			
		||||
 | 
			
		||||
// Number of endpoints in hardware
 | 
			
		||||
// TODO should use TUP_DCD_ENDPOINT_MAX
 | 
			
		||||
#define STFSDEV_EP_COUNT (8u)
 | 
			
		||||
 | 
			
		||||
#endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										292
									
								
								src/portable/st/stm32_fsdev/fsdev_stm32.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								src/portable/st/stm32_fsdev/fsdev_stm32.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,292 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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)
 | 
			
		||||
  // 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_BUS_32BIT
 | 
			
		||||
  #define FSDEV_PMA_SIZE (2048u)
 | 
			
		||||
  #undef USB_PMAADDR
 | 
			
		||||
  #define USB_PMAADDR USB_DRD_PMAADDR
 | 
			
		||||
  #define USB_TypeDef USB_DRD_TypeDef
 | 
			
		||||
  #define EP0R CHEP0R
 | 
			
		||||
  #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 USB_DRD_FS
 | 
			
		||||
  #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_BUS_32BIT
 | 
			
		||||
 | 
			
		||||
  #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE)
 | 
			
		||||
  #define USB_DRD_BASE USB_DRD_FS_BASE
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #define FSDEV_PMA_SIZE (2048u)
 | 
			
		||||
  #undef USB_PMAADDR
 | 
			
		||||
  #define USB_PMAADDR USB_DRD_PMAADDR
 | 
			
		||||
  #define USB_TypeDef USB_DRD_TypeDef
 | 
			
		||||
  #define EP0R CHEP0R
 | 
			
		||||
  #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 USB_DRD_FS
 | 
			
		||||
  #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 */
 | 
			
		||||
  #undef USB_PMAADDR
 | 
			
		||||
  #define USB_PMAADDR 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
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  #error You are using an untested or unimplemented STM32 variant. Please update the driver.
 | 
			
		||||
  // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4
 | 
			
		||||
#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,
 | 
			
		||||
  #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 */
 | 
			
		||||
		Reference in New Issue
	
	Block a user