mirror of
https://github.com/hathach/tinyusb.git
synced 2026-08-18 11:02:16 +00:00
add py32f0 support
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -81,6 +81,7 @@ hw/mcu/gd/
|
||||
hw/mcu/hpmicro/
|
||||
hw/mcu/infineon/
|
||||
hw/mcu/microchip/
|
||||
hw/mcu/puya/
|
||||
hw/mcu/mindmotion/
|
||||
hw/mcu/nordic/nrfx/
|
||||
hw/mcu/nuvoton/
|
||||
|
||||
9
hw/bsp/py32f0/boards/py32f071_dev_board/board.cmake
Normal file
9
hw/bsp/py32f0/boards/py32f071_dev_board/board.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
set(PYOCD_TARGET py32f071ex8)
|
||||
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/py32f071xb.ld)
|
||||
|
||||
function(update_board TARGET)
|
||||
target_compile_definitions(${TARGET} PUBLIC
|
||||
PY32F071xB
|
||||
CFG_EXAMPLE_VIDEO_READONLY
|
||||
)
|
||||
endfunction()
|
||||
75
hw/bsp/py32f0/boards/py32f071_dev_board/board.h
Normal file
75
hw/bsp/py32f0/boards/py32f071_dev_board/board.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2026, 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_2
|
||||
#define LED_STATE_ON 0
|
||||
|
||||
#define BUTTON_PORT GPIOB
|
||||
#define BUTTON_PIN GPIO_PIN_0
|
||||
#define BUTTON_STATE_ACTIVE 0
|
||||
|
||||
static inline void board_py32f0_clock_init(void) {
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI |
|
||||
RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
|
||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
|
||||
while (1) {}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
8
hw/bsp/py32f0/boards/py32f071_dev_board/board.mk
Normal file
8
hw/bsp/py32f0/boards/py32f071_dev_board/board.mk
Normal file
@ -0,0 +1,8 @@
|
||||
CFLAGS += \
|
||||
-DPY32F071xB \
|
||||
-DCFG_EXAMPLE_VIDEO_READONLY
|
||||
|
||||
LD_FILE = $(BOARD_PATH)/py32f071xb.ld
|
||||
PYOCD_TARGET = py32f071ex8
|
||||
|
||||
flash: flash-pyocd
|
||||
105
hw/bsp/py32f0/boards/py32f071_dev_board/py32f071_hal_conf.h
Normal file
105
hw/bsp/py32f0/boards/py32f071_dev_board/py32f071_hal_conf.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2026, 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 PY32F071_HAL_CONF_H_
|
||||
#define PY32F071_HAL_CONF_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
#if !defined(HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t) 8000000)
|
||||
#endif
|
||||
|
||||
#if !defined(HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t) 24000000)
|
||||
#endif
|
||||
|
||||
#if !defined(HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT ((uint32_t) 200)
|
||||
#endif
|
||||
|
||||
#if !defined(LSI_VALUE)
|
||||
#define LSI_VALUE ((uint32_t) 32768)
|
||||
#endif
|
||||
|
||||
#if !defined(LSE_VALUE)
|
||||
#define LSE_VALUE ((uint32_t) 32768)
|
||||
#endif
|
||||
|
||||
#if !defined(LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT ((uint32_t) 5000)
|
||||
#endif
|
||||
|
||||
#define VDD_VALUE ((uint32_t) 3300)
|
||||
#define TICK_INT_PRIORITY ((uint32_t) 3)
|
||||
#define USE_RTOS 0
|
||||
#define PREFETCH_ENABLE 0
|
||||
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
#include "py32f0xx_hal.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "py32f071_hal_rcc.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "py32f071_hal_flash.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "py32f071_hal_gpio.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "py32f071_hal_pwr.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "py32f071_hal_cortex.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#define assert_param(expr) ((expr) ? (void) 0U : assert_failed((uint8_t *) __FILE__, __LINE__))
|
||||
#else
|
||||
#define assert_param(expr) ((void) 0U)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
122
hw/bsp/py32f0/boards/py32f071_dev_board/py32f071xb.ld
Normal file
122
hw/bsp/py32f0/boards/py32f071_dev_board/py32f071xb.ld
Normal file
@ -0,0 +1,122 @@
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_Min_Heap_Size = 0x200;
|
||||
_Min_Stack_Size = 0x400;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector))
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text)
|
||||
*(.text*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.eh_frame)
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} >FLASH
|
||||
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array*))
|
||||
PROVIDE_HIDDEN(__preinit_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array*))
|
||||
PROVIDE_HIDDEN(__init_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array*))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >RAM AT> FLASH
|
||||
|
||||
. = ALIGN(4);
|
||||
.bss :
|
||||
{
|
||||
_sbss = .;
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end__ = _ebss;
|
||||
} >RAM
|
||||
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE(end = .);
|
||||
PROVIDE(_end = .);
|
||||
. = . + _Min_Heap_Size;
|
||||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(8);
|
||||
} >RAM
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a(*)
|
||||
libm.a(*)
|
||||
libgcc.a(*)
|
||||
}
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
133
hw/bsp/py32f0/family.c
Normal file
133
hw/bsp/py32f0/family.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2026, 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.
|
||||
*/
|
||||
|
||||
/* metadata:
|
||||
manufacturer: Puya
|
||||
*/
|
||||
|
||||
#include "py32f0xx_hal.h"
|
||||
#include "bsp/board_api.h"
|
||||
#include "board.h"
|
||||
|
||||
void USB_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
void USBD_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
void HAL_MspInit(void) {
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void board_init(void) {
|
||||
HAL_Init();
|
||||
board_py32f0_clock_init();
|
||||
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||
SysTick->CTRL &= ~1U;
|
||||
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
#endif
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
GPIO_InitStruct.Pin = LED_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
|
||||
board_led_write(false);
|
||||
|
||||
GPIO_InitStruct.Pin = BUTTON_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
|
||||
|
||||
__HAL_RCC_USB_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void board_led_write(bool state) {
|
||||
GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||
HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state);
|
||||
}
|
||||
|
||||
uint32_t board_button_read(void) {
|
||||
return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
|
||||
}
|
||||
|
||||
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
|
||||
(void) max_len;
|
||||
volatile uint32_t * py32_uuid = (volatile uint32_t *) UID_BASE;
|
||||
uint32_t* id32 = (uint32_t*) (uintptr_t) id;
|
||||
uint8_t const len = 12;
|
||||
|
||||
id32[0] = py32_uuid[0];
|
||||
id32[1] = py32_uuid[1];
|
||||
id32[2] = py32_uuid[2];
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
volatile uint32_t system_ticks = 0;
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
HAL_IncTick();
|
||||
system_ticks++;
|
||||
}
|
||||
|
||||
uint32_t tusb_time_millis_api(void) {
|
||||
return system_ticks;
|
||||
}
|
||||
#endif
|
||||
|
||||
void HardFault_Handler(void) {
|
||||
__asm("BKPT #0\n");
|
||||
}
|
||||
|
||||
void _init(void);
|
||||
void _init(void) {
|
||||
}
|
||||
97
hw/bsp/py32f0/family.cmake
Normal file
97
hw/bsp/py32f0/family.cmake
Normal file
@ -0,0 +1,97 @@
|
||||
include_guard()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||
|
||||
if (NOT DEFINED PY32_SDK_NAME)
|
||||
set(PY32_SDK_NAME PY32F071_Firmware)
|
||||
endif ()
|
||||
if (NOT DEFINED PY32_SERIES)
|
||||
set(PY32_SERIES PY32F071)
|
||||
endif ()
|
||||
if (NOT DEFINED PY32_TEMPLATE)
|
||||
set(PY32_TEMPLATE PY32F071xx_Templates)
|
||||
endif ()
|
||||
if (NOT DEFINED PY32_STARTUP)
|
||||
set(PY32_STARTUP startup_py32f071xx.s)
|
||||
endif ()
|
||||
if (NOT DEFINED PY32_SYSTEM_SOURCE)
|
||||
set(PY32_SYSTEM_SOURCE system_py32f071.c)
|
||||
endif ()
|
||||
if (NOT DEFINED PY32_HAL_PREFIX)
|
||||
set(PY32_HAL_PREFIX py32f071)
|
||||
endif ()
|
||||
set(PY32_SDK ${TOP}/hw/mcu/puya/${PY32_SDK_NAME})
|
||||
set(PY32_HAL ${PY32_SDK}/Drivers/${PY32_SERIES}_HAL_Driver)
|
||||
set(PY32_CMSIS ${PY32_SDK}/Drivers/CMSIS/Device/${PY32_SERIES})
|
||||
|
||||
set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor")
|
||||
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||
|
||||
set(FAMILY_MCUS PY32F0 CACHE INTERNAL "")
|
||||
|
||||
set(STARTUP_FILE_GNU ${PY32_SDK}/Templates/${PY32_TEMPLATE}/EIDE/${PY32_STARTUP})
|
||||
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||
set(LD_FILE_Clang ${LD_FILE_GNU})
|
||||
|
||||
function(family_add_board BOARD_TARGET)
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${PY32_SDK}/Templates/${PY32_TEMPLATE}/Src/${PY32_SYSTEM_SOURCE}
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal.c
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal_cortex.c
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal_flash.c
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal_gpio.c
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal_pwr.c
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal_rcc.c
|
||||
${PY32_HAL}/Src/${PY32_HAL_PREFIX}_hal_rcc_ex.c
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${PY32_SDK}/Drivers/CMSIS/Include
|
||||
${PY32_CMSIS}/Include
|
||||
${PY32_HAL}/Inc
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||
)
|
||||
target_compile_definitions(${BOARD_TARGET} PRIVATE
|
||||
USE_HAL_DRIVER
|
||||
)
|
||||
update_board(${BOARD_TARGET})
|
||||
endfunction()
|
||||
|
||||
function(family_configure_example TARGET RTOS)
|
||||
family_configure_common(${TARGET} ${RTOS})
|
||||
family_add_tinyusb(${TARGET} OPT_MCU_PY32F0)
|
||||
|
||||
target_sources(${TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||
${TOP}/src/portable/mentor/musb/dcd_musb.c
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
target_include_directories(${TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${TARGET} PUBLIC
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
-nostartfiles
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
message(FATAL_ERROR "Clang is not supported")
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
message(FATAL_ERROR "IAR is not supported")
|
||||
endif ()
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes")
|
||||
endif ()
|
||||
set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES
|
||||
SKIP_LINTING ON
|
||||
COMPILE_OPTIONS -w)
|
||||
|
||||
family_add_bin_hex(${TARGET})
|
||||
family_flash_pyocd(${TARGET})
|
||||
endfunction()
|
||||
57
hw/bsp/py32f0/family.mk
Normal file
57
hw/bsp/py32f0/family.mk
Normal file
@ -0,0 +1,57 @@
|
||||
UF2_FAMILY_ID = 0x0
|
||||
|
||||
include $(TOP)/$(BOARD_PATH)/board.mk
|
||||
|
||||
PY32_SDK_NAME ?= PY32F071_Firmware
|
||||
PY32_SERIES ?= PY32F071
|
||||
PY32_TEMPLATE ?= PY32F071xx_Templates
|
||||
PY32_STARTUP ?= startup_py32f071xx.s
|
||||
PY32_SYSTEM_SOURCE ?= system_py32f071.c
|
||||
PY32_HAL_PREFIX ?= py32f071
|
||||
|
||||
SDK_DIR = hw/mcu/puya/$(PY32_SDK_NAME)
|
||||
HAL_DIR = $(SDK_DIR)/Drivers/$(PY32_SERIES)_HAL_Driver
|
||||
CMSIS_DIR = $(SDK_DIR)/Drivers/CMSIS
|
||||
CMSIS_DEVICE_DIR = $(CMSIS_DIR)/Device/$(PY32_SERIES)
|
||||
|
||||
DEPS_SUBMODULES += $(SDK_DIR)
|
||||
|
||||
CFLAGS += \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_PY32F0 \
|
||||
-DUSE_HAL_DRIVER
|
||||
|
||||
# Puya HAL leaves some CMSIS-compatible callback parameters intentionally unused.
|
||||
CFLAGS += -Wno-error=unused-parameter
|
||||
|
||||
MCU_DIR = $(SDK_DIR)
|
||||
|
||||
SRC_C += \
|
||||
src/portable/mentor/musb/dcd_musb.c \
|
||||
hw/bsp/py32f0/family.c \
|
||||
$(SDK_DIR)/Templates/$(PY32_TEMPLATE)/Src/$(PY32_SYSTEM_SOURCE) \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal.c \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal_cortex.c \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal_flash.c \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal_gpio.c \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal_pwr.c \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal_rcc.c \
|
||||
$(HAL_DIR)/Src/$(PY32_HAL_PREFIX)_hal_rcc_ex.c
|
||||
|
||||
SRC_S += $(SDK_DIR)/Templates/$(PY32_TEMPLATE)/EIDE/$(PY32_STARTUP)
|
||||
|
||||
INC += \
|
||||
$(TOP)/hw/bsp/py32f0 \
|
||||
$(TOP)/$(CMSIS_DIR)/Include \
|
||||
$(TOP)/$(CMSIS_DEVICE_DIR)/Include \
|
||||
$(TOP)/$(HAL_DIR)/Inc \
|
||||
$(TOP)/hw/bsp/py32f0/boards/$(BOARD)
|
||||
|
||||
SKIP_NANOLIB = 1
|
||||
|
||||
LDFLAGS += \
|
||||
-nostdlib -nostartfiles \
|
||||
--specs=nosys.specs --specs=nano.specs \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,--print-memory-usage
|
||||
|
||||
CPU_CORE ?= cortex-m0plus
|
||||
@ -703,6 +703,17 @@
|
||||
|
||||
#define TU_ATTR_FAST_FUNC __attribute__((section(".fast")))
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Puya
|
||||
//--------------------------------------------------------------------+
|
||||
#elif TU_CHECK_MCU(OPT_MCU_PY32F0)
|
||||
#define TUP_USBIP_MUSB
|
||||
#define TUP_USBIP_MUSB_PY32
|
||||
#define TUP_DCD_ENDPOINT_MAX 6
|
||||
// PY32 shares the buffer between IN and OUT of the same endpoint number.
|
||||
// Possible to share IN/OUT if only one direction is armed at any one time
|
||||
#define CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY 1
|
||||
|
||||
#endif
|
||||
|
||||
// External USB controller
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "musb_ti.h"
|
||||
#elif defined(TUP_USBIP_MUSB_ADI)
|
||||
#include "musb_max32.h"
|
||||
#elif defined(TUP_USBIP_MUSB_PY32)
|
||||
#include "musb_py32.h"
|
||||
#else
|
||||
#error "Unsupported MCU"
|
||||
#endif
|
||||
@ -45,6 +47,7 @@ typedef struct {
|
||||
};
|
||||
uint16_t length; /* the number of bytes in the buffer */
|
||||
uint16_t remaining; /* the number of bytes remaining in the buffer */
|
||||
uint16_t mps; /* maximum packet size */
|
||||
bool armed; /* true while a transfer is posted */
|
||||
bool use_fifo; /* true: buf is tu_fifo_t*; false: buf is plain byte pointer. */
|
||||
} pipe_state_t;
|
||||
@ -159,6 +162,14 @@ TU_ATTR_ALWAYS_INLINE static inline pipe_state_t* pipe_get(uint8_t epnum, tusb_d
|
||||
return &_dcd.pipe[idx];
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t musb_mps_to_maxp(uint16_t mps) {
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
return (uint8_t) ((mps + 7u) / 8u);
|
||||
#else
|
||||
return mps;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// HW FIFO Helper
|
||||
// Note: Index register is already set by caller
|
||||
@ -223,7 +234,9 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign
|
||||
bool double_packet) {
|
||||
(void) mps;
|
||||
|
||||
#if defined(TUP_USBIP_MUSB_ADI)
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
(void) musb; (void) epnum; (void) is_rx; (void) double_packet;
|
||||
#elif defined(TUP_USBIP_MUSB_ADI)
|
||||
// AnalogDevice FIFO sizes: EP1..7 = 512 B, EP8..9 = 2048 B, EP10..11 = 4096 B.
|
||||
// DPB requires FIFO >= 2 * MPS. For HS bulk (MPS=512) only EP >= 8 qualifies.
|
||||
// Force single-buffered on EP < 8 even if the caller requested DPB.
|
||||
@ -266,7 +279,7 @@ TU_ATTR_ALWAYS_INLINE static inline void hwfifo_flush(musb_regs_t* musb, unsigne
|
||||
// write to txfifo using pipe_state_t info
|
||||
static void pipe_write(musb_regs_t* musb_regs, pipe_state_t* pipe, uint8_t epnum) {
|
||||
musb_ep_csr_t* ep_csr = &musb_regs->indexed_csr;
|
||||
const uint16_t mps = ep_csr->tx_maxp & MUSB_TXMAXP_PACKET_SIZE_M;
|
||||
const uint16_t mps = pipe->mps;
|
||||
const uint16_t xact_len = tu_min16(mps, pipe->remaining);
|
||||
volatile void *hwfifo = &musb_regs->fifo[epnum];
|
||||
if (xact_len) {
|
||||
@ -320,7 +333,7 @@ static void process_epin_isr(uint8_t rhport, musb_regs_t *musb_regs, uint8_t epn
|
||||
// release the FIFO slot by clearing RXRDY. return true if short packet
|
||||
static bool pipe_read(musb_regs_t* musb_regs, pipe_state_t* pipe, uint8_t epnum) {
|
||||
musb_ep_csr_t* ep_csr = &musb_regs->indexed_csr; // index already set in process_epout_isr()
|
||||
const uint16_t mps = ep_csr->rx_maxp & MUSB_RXMAXP_PACKET_SIZE_M;
|
||||
const uint16_t mps = pipe->mps;
|
||||
const uint16_t rx_count = ep_csr->rx_count;
|
||||
const uint16_t xact_len = tu_min16(tu_min16(pipe->remaining, mps), rx_count);
|
||||
volatile void *hwfifo = &musb_regs->fifo[epnum];
|
||||
@ -632,7 +645,11 @@ static void process_bus_reset_isr(uint8_t rhport) {
|
||||
hwfifo_reset(musb, i, 0);
|
||||
hwfifo_reset(musb, i, 1);
|
||||
}
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true);
|
||||
#else
|
||||
dcd_event_bus_reset(rhport, (musb->power & MUSB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
@ -641,6 +658,11 @@ static void process_bus_reset_isr(uint8_t rhport) {
|
||||
|
||||
#if CFG_TUSB_DEBUG >= MUSB_DEBUG
|
||||
static void print_musb_info(musb_regs_t* musb_regs) {
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
(void) musb_regs;
|
||||
// musb discovery fields not present
|
||||
TU_LOG1("musb py32 fixed full-speed configuration\r\n");
|
||||
#else
|
||||
// print version, epinfo, raminfo, config_data0, fifo_size
|
||||
TU_LOG1("musb version = %u.%u\r\n", musb_regs->hwvers_bit.major, musb_regs->hwvers_bit.minor);
|
||||
TU_LOG1("Number of endpoints: %u TX, %u RX\r\n", musb_regs->epinfo_bit.tx_ep_num, musb_regs->epinfo_bit.rx_ep_num);
|
||||
@ -657,6 +679,7 @@ static void print_musb_info(musb_regs_t* musb_regs) {
|
||||
TU_LOG1("FIFO %u Size: TX %u RX %u\r\n", i, musb_regs->indexed_csr.fifo_size_bit.tx, musb_regs->indexed_csr.fifo_size_bit.rx);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -716,15 +739,23 @@ void dcd_remote_wakeup(uint8_t rhport) {
|
||||
void dcd_connect(uint8_t rhport)
|
||||
{
|
||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
(void) musb_regs;
|
||||
#else
|
||||
musb_regs->power |= TUD_OPT_HIGH_SPEED ? MUSB_POWER_HSENAB : 0;
|
||||
musb_regs->power |= MUSB_POWER_SOFTCONN;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disconnect by disabling internal pull-up resistor on D+/D-
|
||||
void dcd_disconnect(uint8_t rhport)
|
||||
{
|
||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
(void) musb_regs;
|
||||
#else
|
||||
musb_regs->power &= ~MUSB_POWER_SOFTCONN;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dcd_sof_enable(uint8_t rhport, bool en)
|
||||
@ -750,6 +781,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
|
||||
pipe->buf = NULL;
|
||||
pipe->length = 0;
|
||||
pipe->remaining = 0;
|
||||
pipe->mps = (uint16_t) mps;
|
||||
pipe->armed = false;
|
||||
|
||||
musb_regs_t* musb = MUSB_REGS(rhport);
|
||||
@ -757,7 +789,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
|
||||
const uint8_t is_rx = (1 - epdir);
|
||||
musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx];
|
||||
|
||||
maxp_csr->maxp = mps;
|
||||
maxp_csr->maxp = musb_mps_to_maxp((uint16_t) mps);
|
||||
maxp_csr->csrh = 0;
|
||||
#if MUSB_CFG_SHARED_FIFO
|
||||
if (epdir) {
|
||||
@ -768,7 +800,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
|
||||
hwfifo_flush(musb, epn, is_rx, true);
|
||||
|
||||
TU_ASSERT(hwfifo_config(musb, epn, is_rx, mps, ep_desc->bmAttributes.xfer == TUSB_XFER_BULK));
|
||||
musb->intren_ep[is_rx] |= TU_BIT(epn);
|
||||
musb->intren_ep[is_rx ^ MUSB_INTR_EP_TX_RX_SWAP] |= TU_BIT(epn);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -779,6 +811,8 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
|
||||
musb_regs_t* musb = MUSB_REGS(rhport);
|
||||
musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn);
|
||||
const uint8_t is_rx = 1 - dir_in;
|
||||
pipe_state_t *pipe = pipe_get(epn, dir_in);
|
||||
pipe->mps = largest_packet_size;
|
||||
ep_csr->maxp_csr[is_rx].csrh = 0;
|
||||
return hwfifo_config(musb, epn, is_rx, largest_packet_size, true);
|
||||
}
|
||||
@ -796,6 +830,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc )
|
||||
pipe->buf = NULL;
|
||||
pipe->length = 0;
|
||||
pipe->remaining = 0;
|
||||
pipe->mps = (uint16_t) mps;
|
||||
pipe->armed = false;
|
||||
|
||||
musb_regs_t* musb = MUSB_REGS(rhport);
|
||||
@ -803,7 +838,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc )
|
||||
const uint8_t is_rx = 1 - dir_in;
|
||||
musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx];
|
||||
|
||||
maxp_csr->maxp = mps;
|
||||
maxp_csr->maxp = musb_mps_to_maxp((uint16_t) mps);
|
||||
maxp_csr->csrh |= MUSB_CSRH_ISO;
|
||||
#if MUSB_CFG_SHARED_FIFO
|
||||
if (dir_in) {
|
||||
@ -818,7 +853,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc )
|
||||
musb->fifo_size[is_rx] = hwfifo_byte2size(mps) | MUSB_FIFOSZ_DOUBLE_PACKET;
|
||||
#endif
|
||||
|
||||
musb->intren_ep[is_rx] |= TU_BIT(epn);
|
||||
musb->intren_ep[is_rx ^ MUSB_INTR_EP_TX_RX_SWAP] |= TU_BIT(epn);
|
||||
|
||||
if (ie) musb_dcd_int_enable(rhport);
|
||||
|
||||
@ -839,7 +874,7 @@ void dcd_edpt_close_all(uint8_t rhport)
|
||||
musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d];
|
||||
hwfifo_flush(musb, i, d, true);
|
||||
hwfifo_reset(musb, i, d);
|
||||
maxp_csr->maxp = 0;
|
||||
maxp_csr->maxp = musb_mps_to_maxp(0);
|
||||
maxp_csr->csrh = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ extern "C" {
|
||||
|
||||
#define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints
|
||||
#define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing
|
||||
#define MUSB_INTR_EP_TX_RX_SWAP 0
|
||||
|
||||
static const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS };
|
||||
|
||||
|
||||
79
src/portable/mentor/musb/musb_py32.h
Normal file
79
src/portable/mentor/musb/musb_py32.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2026, 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_MUSB_PY32_H_
|
||||
#define TUSB_MUSB_PY32_H_
|
||||
|
||||
#include "py32f0xx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// PY32 does not expose generic MUSB shared FIFO allocation registers; this
|
||||
// selects the existing TX_MODE path required for IN endpoints.
|
||||
#define MUSB_CFG_SHARED_FIFO 1
|
||||
#define MUSB_CFG_DYNAMIC_FIFO 0
|
||||
#define MUSB_INTR_EP_TX_RX_SWAP 1
|
||||
|
||||
static const uintptr_t MUSB_BASES[] = { USBD_BASE };
|
||||
static const IRQn_Type musb_irqs[] = { USB_IRQn };
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_phy_init(uint8_t rhport) {
|
||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
||||
|
||||
musb_regs->index = 0;
|
||||
musb_regs->faddr = 0;
|
||||
musb_regs->intr_usben = MUSB_IE_RESET | MUSB_IE_RESUME | MUSB_IE_SUSPND;
|
||||
musb_regs->intr_txen = TU_BIT(0);
|
||||
musb_regs->intr_rxen = 0;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) {
|
||||
NVIC_EnableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) {
|
||||
NVIC_DisableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) {
|
||||
NVIC_ClearPendingIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
|
||||
return NVIC_GetEnableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_handler_enter(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -30,6 +30,7 @@
|
||||
#define MUSB_CFG_SHARED_FIFO 0
|
||||
#define MUSB_CFG_DYNAMIC_FIFO 1
|
||||
#define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096
|
||||
#define MUSB_INTR_EP_TX_RX_SWAP 0
|
||||
|
||||
static const uintptr_t MUSB_BASES[] = { USB0_BASE };
|
||||
|
||||
|
||||
@ -64,6 +64,75 @@
|
||||
#define __R volatile const
|
||||
#endif
|
||||
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
__IO uint8_t csrh; // 0x04, 0x08: CSRH
|
||||
__IO uint8_t csrl; // 0x05, 0x09: CSRL
|
||||
__IO uint8_t maxp; // 0x06, 0x0A: MAXP
|
||||
__I uint8_t reserved;
|
||||
} musb_ep_maxp_csr_t;
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(musb_ep_maxp_csr_t) == 4, "size is not correct");
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
__IO uint8_t csr0l; // 0x00: CSR0
|
||||
__IO uint8_t count0; // 0x01: COUNT0
|
||||
__I uint8_t reserved_0x02[2];
|
||||
|
||||
union {
|
||||
struct {
|
||||
__IO uint8_t tx_csrh; // 0x04: TX CSRH
|
||||
__IO uint8_t tx_csrl; // 0x05: TX CSRL
|
||||
__IO uint8_t tx_maxp; // 0x06: TX MAXP
|
||||
__I uint8_t reserved_0x07;
|
||||
|
||||
__IO uint8_t rx_csrh; // 0x08: RX CSRH
|
||||
__IO uint8_t rx_csrl; // 0x09: RX CSRL
|
||||
__IO uint8_t rx_maxp; // 0x0A: RX MAXP
|
||||
__I uint8_t reserved_0x0b;
|
||||
};
|
||||
|
||||
musb_ep_maxp_csr_t maxp_csr[2];
|
||||
};
|
||||
|
||||
__IO uint16_t rx_count; // 0x0C: RX COUNT
|
||||
__I uint8_t reserved_0x0e[2];
|
||||
} musb_ep_csr_t;
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct");
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
__IO uint8_t faddr; // 0x00: FADDR
|
||||
__IO uint8_t power; // 0x01: POWER
|
||||
__I uint8_t reserved_0x02[2];
|
||||
|
||||
__IO uint8_t intr_usb; // 0x04: INTRUSB
|
||||
__IO uint8_t intr_rx; // 0x05: INTRRX
|
||||
__IO uint8_t intr_tx; // 0x06: INTRTX
|
||||
__I uint8_t reserved_0x07;
|
||||
|
||||
__IO uint8_t intr_usben; // 0x08: INTRUSBEN
|
||||
union {
|
||||
struct {
|
||||
__IO uint8_t intr_rxen; // 0x09: INTRRXEN
|
||||
__IO uint8_t intr_txen; // 0x0A: INTRTXEN
|
||||
};
|
||||
|
||||
__IO uint8_t intren_ep[2]; // 0x09-0x0A: RX, TX
|
||||
};
|
||||
__I uint8_t reserved_0x0b;
|
||||
|
||||
__IO uint16_t frame; // 0x0C: FRAME
|
||||
__IO uint8_t index; // 0x0E: INDEX
|
||||
__I uint8_t reserved_0x0f;
|
||||
|
||||
musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR
|
||||
__IO uint32_t fifo[16]; // 0x20-0x5F: FIFO 0-15
|
||||
} musb_regs_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
__IO uint16_t maxp; // 0x00, 0x04: MAXP
|
||||
__IO uint8_t csrl; // 0x02, 0x06: CSRL
|
||||
@ -277,6 +346,8 @@ typedef struct {
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x350, "size is not correct");
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@ -104,6 +104,9 @@
|
||||
#define OPT_MCU_NUC120 802
|
||||
#define OPT_MCU_NUC505 803
|
||||
|
||||
// Puya
|
||||
#define OPT_MCU_PY32F0 850 ///< Puya PY32F0
|
||||
|
||||
// Espressif
|
||||
#define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2
|
||||
#define OPT_MCU_ESP32S3 901 ///< Espressif ESP32-S3
|
||||
@ -349,9 +352,13 @@
|
||||
//------------ MUSB --------------//
|
||||
#if defined(TUP_USBIP_MUSB)
|
||||
#define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32 bit data
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // allow odd 16bit access
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // allow odd 8bit access
|
||||
#if defined(TUP_USBIP_MUSB_PY32)
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 1 // 8 bit data
|
||||
#else
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32 bit data
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // allow odd 16bit access
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // allow odd 8bit access
|
||||
#endif
|
||||
#define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo
|
||||
#endif
|
||||
|
||||
|
||||
@ -82,6 +82,12 @@ deps_optional = {
|
||||
'hw/mcu/nxp/mcux-devices-rt': ['https://github.com/nxp-mcuxpresso/mcux-devices-rt',
|
||||
'dba2b523c9df61f3330bd186242f8210a8e47c45',
|
||||
'imxrt'],
|
||||
'hw/mcu/puya/PY32F071_Firmware': ['https://github.com/OpenPuya/PY32F071_Firmware.git',
|
||||
'73e384cddce63e3019de41d9b6af17dfc96fa536',
|
||||
'py32f0'],
|
||||
'hw/mcu/puya/PY32F072_Firmware': ['https://github.com/OpenPuya/PY32F072_Firmware.git',
|
||||
'bc3a6cdbece335a27abb8b51e6fc4911f5116185',
|
||||
'py32f0'],
|
||||
'hw/mcu/raspberry_pi/FreeRTOS-Kernel': ['https://github.com/raspberrypi/FreeRTOS-Kernel.git',
|
||||
'4f7299d6ea746b27a9dd19e87af568e34bd65b15',
|
||||
'rp2040'],
|
||||
|
||||
Reference in New Issue
Block a user