summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2025-08-01 10:39:47 +0700
committerGitHub <[email protected]>2025-08-01 10:39:47 +0700
commita16c7a27e44990e4025f7d169344eb4a6cf2a377 (patch)
treef6725f3ab347c9f0e50526b15658caa0f3d7719d
parentde9a6c8561e439c397bbb44cc053701a76d9988d (diff)
parente0f2343954c71743358f2b2362bef64bbc68e4a3 (diff)
Merge pull request #3191 from hathach/at32
support at32 mcu (2)
-rwxr-xr-x.github/workflows/ci_set_matrix.py1
-rw-r--r--examples/build_system/cmake/cpu/cortex-m4-nofpu.cmake30
-rw-r--r--examples/build_system/make/cpu/cortex-m4-nofpu.mk20
-rw-r--r--examples/device/net_lwip_webserver/skip.txt1
-rw-r--r--hw/bsp/at32f402_405/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f402_405/at32f402_405_clock.c127
-rw-r--r--hw/bsp/at32f402_405/at32f402_405_clock.h43
-rw-r--r--hw/bsp/at32f402_405/at32f402_405_conf.h151
-rw-r--r--hw/bsp/at32f402_405/at32f402_405_int.c139
-rw-r--r--hw/bsp/at32f402_405/at32f402_405_int.h55
-rw-r--r--hw/bsp/at32f402_405/boards/AT_START_F402_405/board.cmake8
-rw-r--r--hw/bsp/at32f402_405/boards/AT_START_F402_405/board.h169
-rw-r--r--hw/bsp/at32f402_405/boards/AT_START_F402_405/board.mk7
-rw-r--r--hw/bsp/at32f402_405/family.c300
-rw-r--r--hw/bsp/at32f402_405/family.cmake114
-rw-r--r--hw/bsp/at32f402_405/family.mk45
-rw-r--r--hw/bsp/at32f403a_407/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f403a_407/at32f403a_407_clock.c87
-rw-r--r--hw/bsp/at32f403a_407/at32f403a_407_clock.h43
-rw-r--r--hw/bsp/at32f403a_407/at32f403a_407_conf.h161
-rw-r--r--hw/bsp/at32f403a_407/at32f403a_407_int.c117
-rw-r--r--hw/bsp/at32f403a_407/at32f403a_407_int.h55
-rw-r--r--hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.cmake8
-rw-r--r--hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.h61
-rw-r--r--hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.mk7
-rw-r--r--hw/bsp/at32f403a_407/family.c275
-rw-r--r--hw/bsp/at32f403a_407/family.cmake108
-rw-r--r--hw/bsp/at32f403a_407/family.mk41
-rw-r--r--hw/bsp/at32f413/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f413/at32f413_clock.c94
-rw-r--r--hw/bsp/at32f413/at32f413_clock.h43
-rw-r--r--hw/bsp/at32f413/at32f413_conf.h157
-rw-r--r--hw/bsp/at32f413/at32f413_int.c139
-rw-r--r--hw/bsp/at32f413/at32f413_int.h55
-rw-r--r--hw/bsp/at32f413/boards/AT_START_F413/board.cmake8
-rw-r--r--hw/bsp/at32f413/boards/AT_START_F413/board.h62
-rw-r--r--hw/bsp/at32f413/boards/AT_START_F413/board.mk8
-rw-r--r--hw/bsp/at32f413/family.c275
-rw-r--r--hw/bsp/at32f413/family.cmake108
-rw-r--r--hw/bsp/at32f413/family.mk41
-rw-r--r--hw/bsp/at32f415/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f415/at32f415_clock.c92
-rw-r--r--hw/bsp/at32f415/at32f415_clock.h43
-rw-r--r--hw/bsp/at32f415/at32f415_conf.h143
-rw-r--r--hw/bsp/at32f415/at32f415_int.c119
-rw-r--r--hw/bsp/at32f415/at32f415_int.h55
-rw-r--r--hw/bsp/at32f415/boards/AT_START_F415/board.cmake11
-rw-r--r--hw/bsp/at32f415/boards/AT_START_F415/board.h80
-rw-r--r--hw/bsp/at32f415/boards/AT_START_F415/board.mk8
-rw-r--r--hw/bsp/at32f415/family.c271
-rw-r--r--hw/bsp/at32f415/family.cmake108
-rw-r--r--hw/bsp/at32f415/family.mk39
-rw-r--r--hw/bsp/at32f423/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f423/at32f423_clock.c127
-rw-r--r--hw/bsp/at32f423/at32f423_clock.h43
-rw-r--r--hw/bsp/at32f423/at32f423_conf.h153
-rw-r--r--hw/bsp/at32f423/at32f423_int.c139
-rw-r--r--hw/bsp/at32f423/at32f423_int.h55
-rw-r--r--hw/bsp/at32f423/boards/AT_START_F423/board.cmake8
-rw-r--r--hw/bsp/at32f423/boards/AT_START_F423/board.h91
-rw-r--r--hw/bsp/at32f423/boards/AT_START_F423/board.mk7
-rw-r--r--hw/bsp/at32f423/family.c275
-rw-r--r--hw/bsp/at32f423/family.cmake110
-rw-r--r--hw/bsp/at32f423/family.mk40
-rw-r--r--hw/bsp/at32f425/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f425/at32f425_clock.c91
-rw-r--r--hw/bsp/at32f425/at32f425_clock.h43
-rw-r--r--hw/bsp/at32f425/at32f425_conf.h145
-rw-r--r--hw/bsp/at32f425/at32f425_int.c139
-rw-r--r--hw/bsp/at32f425/at32f425_int.h55
-rw-r--r--hw/bsp/at32f425/boards/AT_START_F425/board.cmake12
-rw-r--r--hw/bsp/at32f425/boards/AT_START_F425/board.h90
-rw-r--r--hw/bsp/at32f425/boards/AT_START_F425/board.mk9
-rw-r--r--hw/bsp/at32f425/family.c279
-rw-r--r--hw/bsp/at32f425/family.cmake108
-rw-r--r--hw/bsp/at32f425/family.mk39
-rw-r--r--hw/bsp/at32f435_437/FreeRTOSConfig/FreeRTOSConfig.h177
-rw-r--r--hw/bsp/at32f435_437/at32f435_437_clock.c119
-rw-r--r--hw/bsp/at32f435_437/at32f435_437_clock.h43
-rw-r--r--hw/bsp/at32f435_437/at32f435_437_conf.h173
-rw-r--r--hw/bsp/at32f435_437/at32f435_437_int.c119
-rw-r--r--hw/bsp/at32f435_437/at32f435_437_int.h55
-rw-r--r--hw/bsp/at32f435_437/boards/AT_START_F435_437/board.cmake8
-rw-r--r--hw/bsp/at32f435_437/boards/AT_START_F435_437/board.h182
-rw-r--r--hw/bsp/at32f435_437/boards/AT_START_F435_437/board.mk7
-rw-r--r--hw/bsp/at32f435_437/family.c347
-rw-r--r--hw/bsp/at32f435_437/family.cmake114
-rw-r--r--hw/bsp/at32f435_437/family.mk42
-rw-r--r--src/common/tusb_mcu.h38
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c2
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_at32.h220
-rw-r--r--src/portable/synopsys/dwc2/dwc2_at32.h121
-rw-r--r--src/portable/synopsys/dwc2/dwc2_common.c10
-rw-r--r--src/portable/synopsys/dwc2/dwc2_common.h2
-rw-r--r--src/tusb_option.h9
-rwxr-xr-xtools/get_deps.py21
96 files changed, 9060 insertions, 1 deletions
diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py
index 65d243281..40d51a7a2 100755
--- a/.github/workflows/ci_set_matrix.py
+++ b/.github/workflows/ci_set_matrix.py
@@ -15,6 +15,7 @@ toolchain_list = [
# family: [supported toolchain]
family_list = {
+ "at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437": ["arm-gcc"],
"broadcom_32bit": ["arm-gcc"],
"broadcom_64bit": ["aarch64-gcc"],
"ch32v10x ch32v20x ch32v30x fomu gd32vf103": ["riscv-gcc"],
diff --git a/examples/build_system/cmake/cpu/cortex-m4-nofpu.cmake b/examples/build_system/cmake/cpu/cortex-m4-nofpu.cmake
new file mode 100644
index 000000000..eec924986
--- /dev/null
+++ b/examples/build_system/cmake/cpu/cortex-m4-nofpu.cmake
@@ -0,0 +1,30 @@
+if (TOOLCHAIN STREQUAL "gcc")
+ set(TOOLCHAIN_COMMON_FLAGS
+ -mthumb
+ -mcpu=cortex-m4
+ -mfloat-abi=soft
+ )
+ if (NOT DEFINED FREERTOS_PORT)
+ set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "")
+ endif ()
+
+elseif (TOOLCHAIN STREQUAL "clang")
+ set(TOOLCHAIN_COMMON_FLAGS
+ --target=arm-none-eabi
+ -mcpu=cortex-m4
+ )
+ if (NOT DEFINED FREERTOS_PORT)
+ set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "")
+ endif ()
+
+elseif (TOOLCHAIN STREQUAL "iar")
+ set(TOOLCHAIN_COMMON_FLAGS
+ --cpu cortex-m4
+ --fpu none
+ )
+
+ if (NOT DEFINED FREERTOS_PORT)
+ set(FREERTOS_PORT IAR_ARM_CM3 CACHE INTERNAL "")
+ endif ()
+
+endif ()
diff --git a/examples/build_system/make/cpu/cortex-m4-nofpu.mk b/examples/build_system/make/cpu/cortex-m4-nofpu.mk
new file mode 100644
index 000000000..ac2916005
--- /dev/null
+++ b/examples/build_system/make/cpu/cortex-m4-nofpu.mk
@@ -0,0 +1,20 @@
+ifeq ($(TOOLCHAIN),gcc)
+ CFLAGS += \
+ -mthumb \
+ -mcpu=cortex-m4 \
+ -mfloat-abi=soft
+
+else ifeq ($(TOOLCHAIN),clang)
+ CFLAGS += \
+ --target=arm-none-eabi \
+ -mcpu=cortex-m4
+
+else ifeq ($(TOOLCHAIN),iar)
+ CFLAGS += --cpu cortex-m4 --fpu none
+ ASFLAGS += --cpu cortex-m4 --fpu none
+
+else
+ $(error "TOOLCHAIN is not supported")
+endif
+
+FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM3
diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt
index 20a264387..6f66efb53 100644
--- a/examples/device/net_lwip_webserver/skip.txt
+++ b/examples/device/net_lwip_webserver/skip.txt
@@ -15,6 +15,7 @@ mcu:STM32N6
family:broadcom_64bit
family:broadcom_32bit
family:espressif
+board:AT_START_F425
board:curiosity_nano
board:frdm_kl25z
# lpc55 has weird error 'ncm_interface' causes a section type conflict with 'ntb_parameters'
diff --git a/hw/bsp/at32f402_405/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f402_405/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..1f75a7cb0
--- /dev/null
+++ b/hw/bsp/at32f402_405/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f402_405.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f402_405/at32f402_405_clock.c b/hw/bsp/at32f402_405/at32f402_405_clock.c
new file mode 100644
index 000000000..d9a1b5eef
--- /dev/null
+++ b/hw/bsp/at32f402_405/at32f402_405_clock.c
@@ -0,0 +1,127 @@
+/**
+ **************************************************************************
+ * @file at32f402_405_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f402_405_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * system clock (sclk) = (hext * pll_ns)/(pll_ms * pll_fp)
+ * system clock source = pll (hext)
+ * - hext = HEXT_VALUE
+ * - sclk = 216000000
+ * - ahbdiv = 1
+ * - ahbclk = 216000000
+ * - apb2div = 1
+ * - apb2clk = 216000000
+ * - apb1div = 2
+ * - apb1clk = 108000000
+ * - pll_ns = 72
+ * - pll_ms = 1
+ * - pll_fr = 4
+ * - flash_wtcyc = 6 cycle
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* reset crm */
+ crm_reset();
+
+ /* config flash psr register */
+ flash_psr_set(FLASH_WAIT_CYCLE_6);
+
+ /* enable pwc periph clock */
+ crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
+
+ /* set power ldo output voltage to 1.3v */
+ pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3);
+
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
+
+ /* wait till hext is ready */
+ while(crm_hext_stable_wait() == ERROR)
+ {
+ }
+
+ /* if pll parameter has changed, please use the AT32_New_Clock_Configuration tool for new configuration. */
+ crm_pll_config(CRM_PLL_SOURCE_HEXT, 72, 1, CRM_PLL_FP_4);
+
+ /* config pllu div */
+ crm_pllu_div_set(CRM_PLL_FU_18);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB2 clock is 216 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_1);
+
+ /* config apb1clk, the maximum frequency of APB1 clock is 120 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_2);
+
+ /* enable auto step mode */
+ crm_auto_step_mode_enable(TRUE);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* disable auto step mode */
+ crm_auto_step_mode_enable(FALSE);
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+
+#ifdef AT32F405xx
+ /*
+ AT32405 OTGHS PHY not initialized, resulting in high power consumption
+ Solutions:
+ 1. If OTGHS is not used, call the "reduce_power_consumption" function to reduce power consumption.
+ PLL or HEXT should be enabled when calling this function.
+ Example: reduce_power_consumption();
+
+ 2. If OTGHS is required, initialize OTGHS to reduce power consumption, without the need to call this function.
+
+ for more detailed information. please refer to the faq document FAQ0148.
+ */
+#endif
+
+#ifdef AT32F402xx
+ /* reduce power consumption */
+ reduce_power_consumption();
+#endif
+}
diff --git a/hw/bsp/at32f402_405/at32f402_405_clock.h b/hw/bsp/at32f402_405/at32f402_405_clock.h
new file mode 100644
index 000000000..30f5ae45d
--- /dev/null
+++ b/hw/bsp/at32f402_405/at32f402_405_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f402_405_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F402_405_CLOCK_H
+#define __AT32F402_405_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f402_405.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f402_405/at32f402_405_conf.h b/hw/bsp/at32f402_405/at32f402_405_conf.h
new file mode 100644
index 000000000..1feef0247
--- /dev/null
+++ b/hw/bsp/at32f402_405/at32f402_405_conf.h
@@ -0,0 +1,151 @@
+/**
+ **************************************************************************
+ * @file at32f402_405_conf.h
+ * @brief at32f402_405 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F402_405_CONF_H
+#define __AT32F402_405_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ *
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ *
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)12000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
+
+#define SystemCoreClock system_core_clock
+
+/* module define -------------------------------------------------------------*/
+#define ACC_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define CRM_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define ERTC_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define QSPI_MODULE_ENABLED
+#define SCFG_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef ACC_MODULE_ENABLED
+#include "at32f402_405_acc.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f402_405_adc.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f402_405_can.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f402_405_crc.h"
+#endif
+#ifdef CRM_MODULE_ENABLED
+#include "at32f402_405_crm.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f402_405_debug.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f402_405_dma.h"
+#endif
+#ifdef ERTC_MODULE_ENABLED
+#include "at32f402_405_ertc.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f402_405_exint.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f402_405_flash.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f402_405_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f402_405_i2c.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f402_405_misc.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f402_405_pwc.h"
+#endif
+#ifdef QSPI_MODULE_ENABLED
+#include "at32f402_405_qspi.h"
+#endif
+#ifdef SCFG_MODULE_ENABLED
+#include "at32f402_405_scfg.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f402_405_spi.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f402_405_tmr.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f402_405_usart.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f402_405_usb.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f402_405_wdt.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f402_405_wwdt.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f402_405/at32f402_405_int.c b/hw/bsp/at32f402_405/at32f402_405_int.c
new file mode 100644
index 000000000..7f2fb6fa7
--- /dev/null
+++ b/hw/bsp/at32f402_405/at32f402_405_int.c
@@ -0,0 +1,139 @@
+/**
+ **************************************************************************
+ * @file at32f402_405_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f402_405_int.h"
+
+/** @addtogroup AT32F405_periph_examples
+ * @{
+ */
+
+/** @addtogroup 405_USB_device_msc
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles hard fault exception.
+ * @param none
+ * @retval none
+ */
+// void HardFault_Handler(void)
+// {
+// /* go to infinite loop when hard fault exception occurs */
+// while(1)
+// {
+// }
+// }
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+// void SVC_Handler(void)
+// {
+// }
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+// void PendSV_Handler(void)
+// {
+// }
+
+/**
+ * @brief this function handles systick handler.
+ * @param none
+ * @retval none
+ */
+// void SysTick_Handler(void)
+// {
+// }
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f402_405/at32f402_405_int.h b/hw/bsp/at32f402_405/at32f402_405_int.h
new file mode 100644
index 000000000..207a7d6df
--- /dev/null
+++ b/hw/bsp/at32f402_405/at32f402_405_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f402_405_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F402_405_INT_H
+#define __AT32F402_405_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f402_405.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.cmake b/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.cmake
new file mode 100644
index 000000000..0d09680a1
--- /dev/null
+++ b/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.cmake
@@ -0,0 +1,8 @@
+set(MCU_VARIANT AT32F405RCT7)
+set(MCU_LINKER_NAME AT32F405xC)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC ${MCU_VARIANT})
+endfunction()
diff --git a/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.h b/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.h
new file mode 100644
index 000000000..0061fd242
--- /dev/null
+++ b/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.h
@@ -0,0 +1,169 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define USB_VBUS_IGNORE
+//#define USB_SOF_OUTPUT_ENABLE
+
+// LED
+#define LED_PORT GPIOF
+#define LED_PIN GPIO_PINS_4
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 0
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+//USART
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN_SOURCE GPIO_PINS_SOURCE9
+#define PRINT_UART_TX_PIN_MUX_NUM GPIO_MUX_7
+
+//USB
+#ifdef BOARD_TUD_RHPORT
+ #if BOARD_TUD_RHPORT == 0
+ #define USB_ID USB_OTG1_ID
+ #define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+ #define OTG_IRQ OTGFS1_IRQn
+ #define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+ #define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+ #define OTG_PIN_GPIO GPIOA
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_VBUS GPIO_PINS_9
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE9
+ #define OTG_PIN_ID GPIO_PINS_10
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE10
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_8
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE8
+ #define OTG_PIN_MUX GPIO_MUX_10
+ #define USB_SPEED_CORE_ID USB_FULL_SPEED_CORE_ID
+ #elif BOARD_TUD_RHPORT == 1
+ #define USB_ID USB_OTG2_ID
+ #define OTG_CLOCK CRM_OTGHS_PERIPH_CLOCK
+ #define OTG_IRQ OTGHS_IRQn
+ #define OTG_IRQ_HANDLER OTGHS_IRQHandler
+ #define OTG_WKUP_IRQ OTGHS_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGHS_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_20
+ #define OTG_PIN_GPIO GPIOB
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOB_PERIPH_CLOCK
+ #define OTG_PIN_VBUS GPIO_PINS_13
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE13
+ #define OTG_PIN_ID GPIO_PINS_12
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE12
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_4
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE4
+ #define OTG_PIN_MUX GPIO_MUX_10
+ #define USB_SPEED_CORE_ID USB_HIGH_SPEED_CORE_ID
+ #endif
+#endif
+#ifdef BOARD_TUH_RHPORT
+ #if BOARD_TUH_RHPORT == 0
+ #define USB_ID USB_OTG1_ID
+ #define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+ #define OTG_IRQ OTGFS1_IRQn
+ #define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+ #define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+ #define OTG_PIN_GPIO GPIOA
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_VBUS GPIO_PINS_9
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE9
+ #define OTG_PIN_ID GPIO_PINS_10
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE10
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_8
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE8
+ #define OTG_PIN_MUX GPIO_MUX_10
+ #define USB_SPEED_CORE_ID USB_FULL_SPEED_CORE_ID
+ #elif BOARD_TUH_RHPORT == 1
+ #define USB_ID USB_OTG2_ID
+ #define OTG_CLOCK CRM_OTGHS_PERIPH_CLOCK
+ #define OTG_IRQ OTGHS_IRQn
+ #define OTG_IRQ_HANDLER OTGHS_IRQHandler
+ #define OTG_WKUP_IRQ OTGHS_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGHS_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_20
+ #define OTG_PIN_GPIO GPIOB
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOB_PERIPH_CLOCK
+ #define OTG_PIN_VBUS GPIO_PINS_13
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE13
+ #define OTG_PIN_ID GPIO_PINS_12
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE12
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_4
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE4
+ #define OTG_PIN_MUX GPIO_MUX_10
+ #define USB_SPEED_CORE_ID USB_HIGH_SPEED_CORE_ID
+ #endif
+#endif
+
+//Vbus
+static inline void board_vbus_sense_init(void)
+{
+ #ifdef BOARD_TUD_RHPORT
+ #if BOARD_TUD_RHPORT == 0
+ *(int*)(0x50000038) |= (1<<21);
+ #elif BOARD_TUD_RHPORT == 1
+ *(int*)(0x40040038) |= (1<<21);
+ #endif
+ #endif
+ #ifdef BOARD_TUH_RHPORT
+ #if BOARD_TUH_RHPORT == 0
+ *(int*)(0x50000038) |= (1<<21);
+ #elif BOARD_TUH_RHPORT == 1
+ *(int*)(0x40040038) |= (1<<21);
+ #endif
+ #endif
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.mk b/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.mk
new file mode 100644
index 000000000..25a719ccf
--- /dev/null
+++ b/hw/bsp/at32f402_405/boards/AT_START_F402_405/board.mk
@@ -0,0 +1,7 @@
+MCU_VARIANT = AT32F405RCT7
+MCU_LINKER_NAME = AT32F405xC
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT}
diff --git a/hw/bsp/at32f402_405/family.c b/hw/bsp/at32f402_405/family.c
new file mode 100644
index 000000000..2dbc538b8
--- /dev/null
+++ b/hw/bsp/at32f402_405/family.c
@@ -0,0 +1,300 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f402_405_clock.h"
+#include "bsp/board_api.h"
+#include "board.h"
+
+void uart_print_init(uint32_t baudrate);
+void usb_clock48m_select(usb_clk48_s clk_s);
+void led_and_botton_init(void);
+void usb_gpio_config(void);
+
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void OTGFS1_IRQHandler(void)
+{
+ tusb_int_handler(0, true);
+}
+void OTGHS_IRQHandler(void)
+{
+ tusb_int_handler(1, true);
+}
+void OTGFS1_WKUP_IRQHandler(void)
+{
+ tusb_int_handler(0, true);
+}
+void OTGHS_WKUP_IRQHandler(void)
+{
+ tusb_int_handler(1, true);
+}
+
+void board_init(void)
+{
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* config system clock */
+ system_clock_config();
+
+ /* config usb io*/
+ usb_gpio_config();
+
+ /* enable usb clock */
+ crm_periph_clock_enable(OTG_CLOCK, TRUE);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HEXT);
+
+ /* vbus ignore */
+ board_vbus_sense_init();
+
+ /* configure systick */
+ SysTick_Config(system_core_clock / 1000);
+
+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(OTG_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+ #else
+ NVIC_SetPriority(OTG_IRQ, 0);
+ #endif
+
+ /* config led and key */
+ led_and_botton_init();
+
+ /* config usart to printf */
+ uart_print_init(115200);
+ // printf("usart printf config success!\r\n");
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+void led_and_botton_init(void)
+{
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN | GPIO_PINS_5 | GPIO_PINS_6;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+ gpio_bits_set(LED_PORT, GPIO_PINS_5);
+ gpio_bits_set(LED_PORT, GPIO_PINS_6);
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+}
+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s)
+{
+ if(clk_s == USB_CLK_HICK)
+ {
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
+ /* enable the acc calibration ready interrupt */
+ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
+ /* update the c1\c2\c3 value */
+ acc_write_c1(7980);
+ acc_write_c2(8000);
+ acc_write_c3(8020);
+ /* open acc calibration */
+ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
+ }
+ else
+ {
+ crm_pllu_output_set(TRUE);
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLLU_STABLE_FLAG) != SET){}
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_PLLU);
+ }
+}
+
+void usb_gpio_config(void)
+{
+ gpio_init_type gpio_init_struct;
+ crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ #ifdef USB_SOF_OUTPUT_ENABLE
+ crm_periph_clock_enable(OTG_PIN_SOF_GPIO_CLOCK, TRUE);
+ gpio_init_struct.gpio_pins = OTG_PIN_SOF;
+ gpio_init(OTG_PIN_SOF_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(OTG_PIN_SOF_GPIO, OTG_PIN_SOF_SOURCE, OTG_PIN_MUX);
+ #endif
+ /* otgfs use vbus pin */
+ #ifndef USB_VBUS_IGNORE
+ gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
+ gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
+ gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
+ #endif
+}
+
+/**
+ * @brief initialize uart
+ * @param baudrate: uart baudrate
+ * @retval none
+ */
+void uart_print_init(uint32_t baudrate)
+{
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+// Get characters from UART. Return number of read bytes
+int board_uart_read(uint8_t *buf, int len) {
+ (void) buf;
+ (void) len;
+ return 0;
+}
+
+// Send characters to UART. Return number of sent bytes
+int board_uart_write(void const *buf, int len)
+{
+ #if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--)
+ {
+ while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET)
+ {
+ timeout--;
+ if(timeout == 0)
+ {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *)buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+ #else
+ (void) buf;
+ (void) len;
+ return 0;
+ #endif
+}
+
+void board_led_write(bool state)
+{
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void)
+{
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len)
+{
+ (void) max_len;
+ volatile uint32_t * at32_uuid = ((volatile uint32_t*)0x1FFFF7E8);
+ uint32_t* id32 = (uint32_t*) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_uuid[2];
+
+ return len;
+}
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+ volatile uint32_t system_ticks = 0;
+ void SysTick_Handler(void)
+ {
+ system_ticks++;
+ }
+ uint32_t board_millis(void)
+ {
+ return system_ticks;
+ }
+ void SVC_Handler(void)
+ {
+ }
+ void PendSV_Handler(void)
+ {
+ }
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line)
+{
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f402_405/family.cmake b/hw/bsp/at32f402_405/family.cmake
new file mode 100644
index 000000000..010e36b88
--- /dev/null
+++ b/hw/bsp/at32f402_405/family.cmake
@@ -0,0 +1,114 @@
+include_guard()
+
+set(AT32_FAMILY at32f402_405)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ BOARD_TUD_RHPORT=0
+ BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f402_405/family.mk b/hw/bsp/at32f402_405/family.mk
new file mode 100644
index 000000000..60a0f93e9
--- /dev/null
+++ b/hw/bsp/at32f402_405/family.mk
@@ -0,0 +1,45 @@
+AT32_FAMILY = at32f402_405
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F402_405 \
+ -DBOARD_TUD_RHPORT=0 \
+ -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/synopsys/dwc2/dcd_dwc2.c \
+ src/portable/synopsys/dwc2/hcd_dwc2.c \
+ src/portable/synopsys/dwc2/dwc2_common.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+# For freeRTOS port source
+FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F
+
+flash: flash-atlink
diff --git a/hw/bsp/at32f403a_407/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f403a_407/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..a89d8c282
--- /dev/null
+++ b/hw/bsp/at32f403a_407/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f403a_407.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f403a_407/at32f403a_407_clock.c b/hw/bsp/at32f403a_407/at32f403a_407_clock.c
new file mode 100644
index 000000000..7a028cebd
--- /dev/null
+++ b/hw/bsp/at32f403a_407/at32f403a_407_clock.c
@@ -0,0 +1,87 @@
+/**
+ **************************************************************************
+ * @file at32f403a_407_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f403a_407_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * - system clock = hick8m / 2 * pll_mult
+ * - system clock source = pll (hick)
+ * - hick = 8000000 / 2
+ * - sclk = 240000000
+ * - ahbdiv = 1
+ * - ahbclk = 240000000
+ * - apb2div = 2
+ * - apb2clk = 120000000
+ * - apb1div = 2
+ * - apb1clk = 120000000
+ * - pll_mult = 60
+ * - pll_range = GT72MHZ (greater than 72 mhz)
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* reset crm */
+ crm_reset();
+
+ /* config pll clock resource */
+ crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_60, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_2);
+
+ /* config apb1clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_2);
+
+ /* enable auto step mode */
+ crm_auto_step_mode_enable(TRUE);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* disable auto step mode */
+ crm_auto_step_mode_enable(FALSE);
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+}
diff --git a/hw/bsp/at32f403a_407/at32f403a_407_clock.h b/hw/bsp/at32f403a_407/at32f403a_407_clock.h
new file mode 100644
index 000000000..ddedfa619
--- /dev/null
+++ b/hw/bsp/at32f403a_407/at32f403a_407_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f403a_407_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F403A_407_CLOCK_H
+#define __AT32F403A_407_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f403a_407.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AT32F403A_407_CLOCK_H */
diff --git a/hw/bsp/at32f403a_407/at32f403a_407_conf.h b/hw/bsp/at32f403a_407/at32f403a_407_conf.h
new file mode 100644
index 000000000..172e972d2
--- /dev/null
+++ b/hw/bsp/at32f403a_407/at32f403a_407_conf.h
@@ -0,0 +1,161 @@
+/**
+ **************************************************************************
+ * @file at32f403a_407_conf.h
+ * @brief at32f403a_407 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F403A_407_CONF_H
+#define __AT32F403A_407_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ *
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ *
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+
+/* module define -------------------------------------------------------------*/
+#define CRM_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define RTC_MODULE_ENABLED
+#define BPR_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define DAC_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define SDIO_MODULE_ENABLED
+#define XMC_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define ACC_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+#define EMAC_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef CRM_MODULE_ENABLED
+#include "at32f403a_407_crm.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f403a_407_tmr.h"
+#endif
+#ifdef RTC_MODULE_ENABLED
+#include "at32f403a_407_rtc.h"
+#endif
+#ifdef BPR_MODULE_ENABLED
+#include "at32f403a_407_bpr.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f403a_407_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f403a_407_i2c.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f403a_407_usart.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f403a_407_pwc.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f403a_407_can.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f403a_407_adc.h"
+#endif
+#ifdef DAC_MODULE_ENABLED
+#include "at32f403a_407_dac.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f403a_407_spi.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f403a_407_dma.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f403a_407_debug.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f403a_407_flash.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f403a_407_crc.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f403a_407_wwdt.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f403a_407_wdt.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f403a_407_exint.h"
+#endif
+#ifdef SDIO_MODULE_ENABLED
+#include "at32f403a_407_sdio.h"
+#endif
+#ifdef XMC_MODULE_ENABLED
+#include "at32f403a_407_xmc.h"
+#endif
+#ifdef ACC_MODULE_ENABLED
+#include "at32f403a_407_acc.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f403a_407_misc.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f403a_407_usb.h"
+#endif
+#ifdef EMAC_MODULE_ENABLED
+#include "at32f403a_407_emac.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f403a_407/at32f403a_407_int.c b/hw/bsp/at32f403a_407/at32f403a_407_int.c
new file mode 100644
index 000000000..0911035cf
--- /dev/null
+++ b/hw/bsp/at32f403a_407/at32f403a_407_int.c
@@ -0,0 +1,117 @@
+/**
+ **************************************************************************
+ * @file at32f403a_407_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f403a_407_int.h"
+
+/** @addtogroup UTILITIES_examples
+ * @{
+ */
+
+/** @addtogroup USB_IAP_bootloader
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+//void SVC_Handler(void)
+//{
+//}
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+//void PendSV_Handler(void)
+//{
+//}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f403a_407/at32f403a_407_int.h b/hw/bsp/at32f403a_407/at32f403a_407_int.h
new file mode 100644
index 000000000..6d85c70ca
--- /dev/null
+++ b/hw/bsp/at32f403a_407/at32f403a_407_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f403a_407_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F403A_407_INT_H
+#define __AT32F403A_407_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f403a_407.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.cmake b/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.cmake
new file mode 100644
index 000000000..25c9558f9
--- /dev/null
+++ b/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.cmake
@@ -0,0 +1,8 @@
+set(MCU_VARIANT AT32F403ACGU7)
+set(MCU_LINKER_NAME AT32F403AxG)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC ${MCU_VARIANT})
+endfunction()
diff --git a/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.h b/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.h
new file mode 100644
index 000000000..55d9d05dc
--- /dev/null
+++ b/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.h
@@ -0,0 +1,61 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// LED
+#define LED_PORT GPIOD
+#define LED_PIN GPIO_PINS_13
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 0
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+// UART
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+
+static inline void board_vbus_sense_init(void)
+{
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.mk b/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.mk
new file mode 100644
index 000000000..9bb6843aa
--- /dev/null
+++ b/hw/bsp/at32f403a_407/boards/AT_START_F403A_407/board.mk
@@ -0,0 +1,7 @@
+MCU_VARIANT = AT32F403ACGU7
+MCU_LINKER_NAME = AT32F403AxG
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT}
diff --git a/hw/bsp/at32f403a_407/family.c b/hw/bsp/at32f403a_407/family.c
new file mode 100644
index 000000000..f9a6dd70d
--- /dev/null
+++ b/hw/bsp/at32f403a_407/family.c
@@ -0,0 +1,275 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f403a_407_clock.h"
+#include "board.h"
+#include "bsp/board_api.h"
+
+void usb_clock48m_select(usb_clk48_s clk_s);
+void uart_print_init(uint32_t baudrate);
+
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void USBFS_H_CAN1_TX_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFS_L_CAN1_RX0_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFS_MAPH_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFS_MAPL_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFSWakeUp_IRQHandler(void) {
+ tud_int_handler(0);
+}
+
+void board_init(void) {
+ system_clock_config();
+
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HICK);
+
+ /* configure systick */
+ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
+
+ /* enable usb clock */
+ crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE);
+
+ SysTick_Config(SystemCoreClock / 1000);
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(USBFS_H_CAN1_TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+ NVIC_SetPriority(USBFS_L_CAN1_RX0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+ NVIC_SetPriority(USBFSWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+#endif
+
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+
+ uart_print_init(115200);
+ printf("usart printf config success!\r\n");
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s) {
+ if (clk_s == USB_CLK_HICK) {
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
+
+ /* enable the acc calibration ready interrupt */
+ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
+
+ /* update the c1\c2\c3 value */
+ acc_write_c1(7980);
+ acc_write_c2(8000);
+ acc_write_c3(8020);
+
+ /* open acc calibration */
+ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
+ } else {
+ switch (system_core_clock) {
+ /* 48MHz */
+ case 48000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1);
+ break;
+
+ /* 72MHz */
+ case 72000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1_5);
+ break;
+
+ /* 96MHz */
+ case 96000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2);
+ break;
+
+ /* 120MHz */
+ case 120000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2_5);
+ break;
+
+ /* 144MHz */
+ case 144000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3);
+ break;
+
+ /* 168MHz */
+ case 168000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3_5);
+ break;
+
+ /* 192MHz */
+ case 192000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_4);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void uart_print_init(uint32_t baudrate) {
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+void board_led_write(bool state) {
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void) {
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ (void) max_len;
+ volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8);
+ uint32_t *id32 = (uint32_t *) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_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) {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--) {
+ while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) {
+ timeout--;
+ if (timeout == 0) {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+#else
+ (void) buf;
+ (void) len;
+ return 0;
+#endif
+}
+
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+volatile uint32_t system_ticks = 0;
+void SysTick_Handler(void) {
+ system_ticks++;
+}
+
+uint32_t board_millis(void) {
+ return system_ticks;
+}
+
+void SVC_Handler(void) {
+}
+
+void PendSV_Handler(void) {
+}
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line) {
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f403a_407/family.cmake b/hw/bsp/at32f403a_407/family.cmake
new file mode 100644
index 000000000..ae4037088
--- /dev/null
+++ b/hw/bsp/at32f403a_407/family.cmake
@@ -0,0 +1,108 @@
+include_guard()
+
+set(AT32_FAMILY at32f403a_407)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f403a_407/family.mk b/hw/bsp/at32f403a_407/family.mk
new file mode 100644
index 000000000..c82d402ca
--- /dev/null
+++ b/hw/bsp/at32f403a_407/family.mk
@@ -0,0 +1,41 @@
+AT32_FAMILY = at32f403a_407
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F403A_407
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+# For freeRTOS port source
+FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F
+
+flash: flash-atlink
diff --git a/hw/bsp/at32f413/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f413/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..0a4184f34
--- /dev/null
+++ b/hw/bsp/at32f413/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f413.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f413/at32f413_clock.c b/hw/bsp/at32f413/at32f413_clock.c
new file mode 100644
index 000000000..a1a32311b
--- /dev/null
+++ b/hw/bsp/at32f413/at32f413_clock.c
@@ -0,0 +1,94 @@
+/**
+ **************************************************************************
+ * @file at32f413_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f413_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * system clock (sclk) = hext / 2 * pll_mult
+ * system clock source = pll (hext)
+ * - hext = HEXT_VALUE
+ * - sclk = 192000000
+ * - ahbdiv = 1
+ * - ahbclk = 192000000
+ * - apb2div = 2
+ * - apb2clk = 96000000
+ * - apb1div = 2
+ * - apb1clk = 96000000
+ * - pll_mult = 48
+ * - pll_range = GT72MHZ (greater than 72 mhz)
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* reset crm */
+ crm_reset();
+
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
+
+ /* wait till hext is ready */
+ while(crm_hext_stable_wait() == ERROR)
+ {
+ }
+
+ /* config pll clock resource */
+ crm_pll_config(CRM_PLL_SOURCE_HEXT_DIV, CRM_PLL_MULT_48, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB1/APB2 clock is 100 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_2);
+
+ /* config apb1clk, the maximum frequency of APB1/APB2 clock is 100 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_2);
+
+ /* enable auto step mode */
+ crm_auto_step_mode_enable(TRUE);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* disable auto step mode */
+ crm_auto_step_mode_enable(FALSE);
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+}
diff --git a/hw/bsp/at32f413/at32f413_clock.h b/hw/bsp/at32f413/at32f413_clock.h
new file mode 100644
index 000000000..28c47d1e6
--- /dev/null
+++ b/hw/bsp/at32f413/at32f413_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f413_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F413_CLOCK_H
+#define __AT32F413_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f413.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AT32F413_CLOCK_H */
diff --git a/hw/bsp/at32f413/at32f413_conf.h b/hw/bsp/at32f413/at32f413_conf.h
new file mode 100644
index 000000000..d8e266a0c
--- /dev/null
+++ b/hw/bsp/at32f413/at32f413_conf.h
@@ -0,0 +1,157 @@
+/**
+ **************************************************************************
+ * @file at32f413_conf.h
+ * @brief at32f413 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F413_CONF_H
+#define __AT32F413_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ *
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ *
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
+
+/* module define -------------------------------------------------------------*/
+#define CRM_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define RTC_MODULE_ENABLED
+#define BPR_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define SDIO_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define ACC_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef CRM_MODULE_ENABLED
+#include "at32f413_crm.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f413_tmr.h"
+#endif
+#ifdef RTC_MODULE_ENABLED
+#include "at32f413_rtc.h"
+#endif
+#ifdef BPR_MODULE_ENABLED
+#include "at32f413_bpr.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f413_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f413_i2c.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f413_usart.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f413_pwc.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f413_can.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f413_adc.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f413_spi.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f413_dma.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f413_debug.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f413_flash.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f413_crc.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f413_wwdt.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f413_wdt.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f413_exint.h"
+#endif
+#ifdef SDIO_MODULE_ENABLED
+#include "at32f413_sdio.h"
+#endif
+#ifdef ACC_MODULE_ENABLED
+#include "at32f413_acc.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f413_misc.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f413_usb.h"
+#endif
+
+/**
+ * @}
+ */
+
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f413/at32f413_int.c b/hw/bsp/at32f413/at32f413_int.c
new file mode 100644
index 000000000..7612e52f0
--- /dev/null
+++ b/hw/bsp/at32f413/at32f413_int.c
@@ -0,0 +1,139 @@
+/**
+ **************************************************************************
+ * @file at32f413_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f413_int.h"
+
+/** @addtogroup AT32F413_periph_examples
+ * @{
+ */
+
+/** @addtogroup 413_USB_device_msc
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles hard fault exception.
+ * @param none
+ * @retval none
+ */
+// void HardFault_Handler(void)
+// {
+// /* go to infinite loop when hard fault exception occurs */
+// while(1)
+// {
+// }
+// }
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+// void SVC_Handler(void)
+// {
+// }
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+// void PendSV_Handler(void)
+// {
+// }
+
+/**
+ * @brief this function handles systick handler.
+ * @param none
+ * @retval none
+ */
+// void SysTick_Handler(void)
+// {
+// }
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f413/at32f413_int.h b/hw/bsp/at32f413/at32f413_int.h
new file mode 100644
index 000000000..fbbf30dbc
--- /dev/null
+++ b/hw/bsp/at32f413/at32f413_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f413_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F413_INT_H
+#define __AT32F413_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f413.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f413/boards/AT_START_F413/board.cmake b/hw/bsp/at32f413/boards/AT_START_F413/board.cmake
new file mode 100644
index 000000000..0a9cc4bbd
--- /dev/null
+++ b/hw/bsp/at32f413/boards/AT_START_F413/board.cmake
@@ -0,0 +1,8 @@
+set(MCU_VARIANT AT32F413RCT7)
+set(MCU_LINKER_NAME AT32F413xC)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC ${MCU_VARIANT})
+endfunction()
diff --git a/hw/bsp/at32f413/boards/AT_START_F413/board.h b/hw/bsp/at32f413/boards/AT_START_F413/board.h
new file mode 100644
index 000000000..13ec7a207
--- /dev/null
+++ b/hw/bsp/at32f413/boards/AT_START_F413/board.h
@@ -0,0 +1,62 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// LED
+#define LED_PORT GPIOC
+#define LED_PIN GPIO_PINS_2
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 0
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+// UART
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+
+static inline void board_vbus_sense_init(void)
+{
+
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f413/boards/AT_START_F413/board.mk b/hw/bsp/at32f413/boards/AT_START_F413/board.mk
new file mode 100644
index 000000000..30fc6b9af
--- /dev/null
+++ b/hw/bsp/at32f413/boards/AT_START_F413/board.mk
@@ -0,0 +1,8 @@
+MCU_VARIANT = AT32F413RCT7
+MCU_LINKER_NAME = AT32F413xC
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT} \
+ -DCFG_EXAMPLE_VIDEO_READONLY
diff --git a/hw/bsp/at32f413/family.c b/hw/bsp/at32f413/family.c
new file mode 100644
index 000000000..6e12c6015
--- /dev/null
+++ b/hw/bsp/at32f413/family.c
@@ -0,0 +1,275 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f413_clock.h"
+#include "board.h"
+#include "bsp/board_api.h"
+
+void usb_clock48m_select(usb_clk48_s clk_s);
+void uart_print_init(uint32_t baudrate);
+
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void USBFS_H_CAN1_TX_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFS_L_CAN1_RX0_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFS_MAPH_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFS_MAPL_IRQHandler(void) {
+ tud_int_handler(0);
+}
+void USBFSWakeUp_IRQHandler(void) {
+ tud_int_handler(0);
+}
+
+void board_init(void) {
+ system_clock_config();
+
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HICK);
+
+ /* configure systick */
+ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
+
+ /* enable usb clock */
+ crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE);
+
+ SysTick_Config(SystemCoreClock / 1000);
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(USBFS_H_CAN1_TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+ NVIC_SetPriority(USBFS_L_CAN1_RX0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+ NVIC_SetPriority(USBFSWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+#endif
+
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+
+ uart_print_init(115200);
+ printf("usart printf config success!\r\n");
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s) {
+ if (clk_s == USB_CLK_HICK) {
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
+
+ /* enable the acc calibration ready interrupt */
+ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
+
+ /* update the c1\c2\c3 value */
+ acc_write_c1(7980);
+ acc_write_c2(8000);
+ acc_write_c3(8020);
+
+ /* open acc calibration */
+ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
+ } else {
+ switch (system_core_clock) {
+ /* 48MHz */
+ case 48000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1);
+ break;
+
+ /* 72MHz */
+ case 72000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1_5);
+ break;
+
+ /* 96MHz */
+ case 96000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2);
+ break;
+
+ /* 120MHz */
+ case 120000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2_5);
+ break;
+
+ /* 144MHz */
+ case 144000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3);
+ break;
+
+ /* 168MHz */
+ case 168000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3_5);
+ break;
+
+ /* 192MHz */
+ case 192000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_4);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void uart_print_init(uint32_t baudrate) {
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+void board_led_write(bool state) {
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void) {
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ (void) max_len;
+ volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8);
+ uint32_t *id32 = (uint32_t *) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_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) {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--) {
+ while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) {
+ timeout--;
+ if (timeout == 0) {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+#else
+ (void) buf;
+ (void) len;
+ return 0;
+#endif
+}
+
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+volatile uint32_t system_ticks = 0;
+void SysTick_Handler(void) {
+ system_ticks++;
+}
+
+uint32_t board_millis(void) {
+ return system_ticks;
+}
+
+void SVC_Handler(void) {
+}
+
+void PendSV_Handler(void) {
+}
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line) {
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f413/family.cmake b/hw/bsp/at32f413/family.cmake
new file mode 100644
index 000000000..b534bcbbc
--- /dev/null
+++ b/hw/bsp/at32f413/family.cmake
@@ -0,0 +1,108 @@
+include_guard()
+
+set(AT32_FAMILY at32f413)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f413/family.mk b/hw/bsp/at32f413/family.mk
new file mode 100644
index 000000000..9c5d867de
--- /dev/null
+++ b/hw/bsp/at32f413/family.mk
@@ -0,0 +1,41 @@
+AT32_FAMILY = at32f413
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F413
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+# For freeRTOS port source
+FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F
+
+flash: flash-atlink
diff --git a/hw/bsp/at32f415/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f415/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..c7932efc0
--- /dev/null
+++ b/hw/bsp/at32f415/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f415.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f415/at32f415_clock.c b/hw/bsp/at32f415/at32f415_clock.c
new file mode 100644
index 000000000..3d137fcd2
--- /dev/null
+++ b/hw/bsp/at32f415/at32f415_clock.c
@@ -0,0 +1,92 @@
+/**
+ **************************************************************************
+ * @file at32f415_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f415_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * system clock (sclk) = hick8m / 2 * pll_mult
+ * system clock source = pll (hick)
+ * - hick = HICK_VALUE
+ * - sclk = 144000000
+ * - ahbdiv = 1
+ * - ahbclk = 144000000
+ * - apb2div = 2
+ * - apb2clk = 72000000
+ * - apb1div = 2
+ * - apb1clk = 72000000
+ * - pll_mult = 36
+ * - flash_wtcyc = 4 cycle
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* config flash psr register */
+ flash_psr_set(FLASH_WAIT_CYCLE_4);
+
+ /* reset crm */
+ crm_reset();
+
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE);
+
+ /* config pll clock resource */
+ crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_36);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB1/APB2 clock is 75 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_2);
+
+ /* config apb1clk, the maximum frequency of APB1/APB2 clock is 75 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_2);
+
+ /* enable auto step mode */
+ crm_auto_step_mode_enable(TRUE);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* disable auto step mode */
+ crm_auto_step_mode_enable(FALSE);
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+}
diff --git a/hw/bsp/at32f415/at32f415_clock.h b/hw/bsp/at32f415/at32f415_clock.h
new file mode 100644
index 000000000..71f204f8b
--- /dev/null
+++ b/hw/bsp/at32f415/at32f415_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f415_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F415_CLOCK_H
+#define __AT32F415_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f415.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AT32F415_CLOCK_H */
diff --git a/hw/bsp/at32f415/at32f415_conf.h b/hw/bsp/at32f415/at32f415_conf.h
new file mode 100644
index 000000000..284eee7d2
--- /dev/null
+++ b/hw/bsp/at32f415/at32f415_conf.h
@@ -0,0 +1,143 @@
+/**
+ **************************************************************************
+ * @file at32f415_conf.h
+ * @brief at32f415 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F415_CONF_H
+#define __AT32F415_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
+
+/* module define -------------------------------------------------------------*/
+#define CRM_MODULE_ENABLED
+#define CMP_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define ERTC_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define SDIO_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef CRM_MODULE_ENABLED
+#include "at32f415_crm.h"
+#endif
+#ifdef CMP_MODULE_ENABLED
+#include "at32f415_cmp.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f415_tmr.h"
+#endif
+#ifdef ERTC_MODULE_ENABLED
+#include "at32f415_ertc.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f415_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f415_i2c.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f415_usart.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f415_pwc.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f415_can.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f415_adc.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f415_spi.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f415_dma.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f415_debug.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f415_flash.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f415_crc.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f415_wwdt.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f415_wdt.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f415_exint.h"
+#endif
+#ifdef SDIO_MODULE_ENABLED
+#include "at32f415_sdio.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f415_misc.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f415_usb.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AT32F415_CONF_H */
diff --git a/hw/bsp/at32f415/at32f415_int.c b/hw/bsp/at32f415/at32f415_int.c
new file mode 100644
index 000000000..c52adaf9a
--- /dev/null
+++ b/hw/bsp/at32f415/at32f415_int.c
@@ -0,0 +1,119 @@
+/**
+ **************************************************************************
+ * @file at32f415_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f415_int.h"
+
+/** @addtogroup AT32F415_periph_examples
+ * @{
+ */
+
+/** @addtogroup 415_CRC_calculation
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+
+ while(1)
+ {
+ }
+
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+//void SVC_Handler(void)
+//{
+//}
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+//void PendSV_Handler(void)
+//{
+//}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f415/at32f415_int.h b/hw/bsp/at32f415/at32f415_int.h
new file mode 100644
index 000000000..2106538b6
--- /dev/null
+++ b/hw/bsp/at32f415/at32f415_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f415_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F415_INT_H
+#define __AT32F415_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f415.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f415/boards/AT_START_F415/board.cmake b/hw/bsp/at32f415/boards/AT_START_F415/board.cmake
new file mode 100644
index 000000000..43fc43a70
--- /dev/null
+++ b/hw/bsp/at32f415/boards/AT_START_F415/board.cmake
@@ -0,0 +1,11 @@
+set(MCU_VARIANT AT32F415RCT7)
+set(MCU_LINKER_NAME AT32F415xC)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC
+ ${MCU_VARIANT}
+ CFG_EXAMPLE_VIDEO_READONLY
+ )
+endfunction()
diff --git a/hw/bsp/at32f415/boards/AT_START_F415/board.h b/hw/bsp/at32f415/boards/AT_START_F415/board.h
new file mode 100644
index 000000000..8b933f9e9
--- /dev/null
+++ b/hw/bsp/at32f415/boards/AT_START_F415/board.h
@@ -0,0 +1,80 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define USB_VBUS_IGNORE
+
+// LED
+#define LED_PORT GPIOC
+#define LED_PIN GPIO_PINS_2
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 0
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+// Usart
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+
+//USB
+#define USB_ID 0
+#define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+#define OTG_IRQ OTGFS1_IRQn
+#define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+#define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+#define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+#define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+#define OTG_PIN_GPIO GPIOA
+#define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+#define OTG_PIN_VBUS GPIO_PINS_9
+#define OTG_PIN_ID GPIO_PINS_10
+#define OTG_PIN_SOF_GPIO GPIOA
+#define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+#define OTG_PIN_SOF GPIO_PINS_8
+
+static inline void board_vbus_sense_init(void)
+{
+ *(int*)(0x50000038) |= (1<<21);
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f415/boards/AT_START_F415/board.mk b/hw/bsp/at32f415/boards/AT_START_F415/board.mk
new file mode 100644
index 000000000..7ea7dc593
--- /dev/null
+++ b/hw/bsp/at32f415/boards/AT_START_F415/board.mk
@@ -0,0 +1,8 @@
+MCU_VARIANT = AT32F415RCT7
+MCU_LINKER_NAME = AT32F415xC
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT} \
+ -DCFG_EXAMPLE_VIDEO_READONLY
diff --git a/hw/bsp/at32f415/family.c b/hw/bsp/at32f415/family.c
new file mode 100644
index 000000000..b8ccae97d
--- /dev/null
+++ b/hw/bsp/at32f415/family.c
@@ -0,0 +1,271 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f415_clock.h"
+#include "board.h"
+#include "bsp/board_api.h"
+
+void uart_print_init(uint32_t baudrate);
+void usb_clock48m_select(usb_clk48_s clk_s);
+void led_and_button_init(void);
+
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void OTGFS1_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+void OTGFS1_WKUP_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+
+void board_init(void) {
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* config system clock */
+ system_clock_config();
+
+ /* enable usb clock */
+ crm_periph_clock_enable(OTG_CLOCK, TRUE);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HEXT);
+
+ /* vbus ignore */
+ board_vbus_sense_init();
+
+ /* configure systick */
+ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
+ SysTick_Config(SystemCoreClock / 1000);
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(OTG_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+#endif
+
+/* otgfs use vbus pin */
+#ifndef USB_VBUS_IGNORE
+ gpio_init_type gpio_init_struct;
+ crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
+ gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
+ gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
+#endif
+
+ /* config led and key */
+ led_and_button_init();
+
+ /* config usart printf */
+ uart_print_init(115200);
+ printf("usart printf config success!\r\n");
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s) {
+ (void) clk_s;
+ switch (system_core_clock) {
+ /* 48MHz */
+ case 48000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1);
+ break;
+
+ /* 72MHz */
+ case 72000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1_5);
+ break;
+
+ /* 96MHz */
+ case 96000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2);
+ break;
+
+ /* 120MHz */
+ case 120000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2_5);
+ break;
+
+ /* 144MHz */
+ case 144000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void led_and_button_init(void) {
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+}
+
+/**
+ * @brief initialize uart
+ * @param baudrate: uart baudrate
+ * @retval none
+ */
+void uart_print_init(uint32_t baudrate) {
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+// Get characters from UART. Return number of read bytes
+int board_uart_read(uint8_t *buf, int len) {
+ (void) buf;
+ (void) len;
+ return 0;
+}
+
+// Send characters to UART. Return number of sent bytes
+int board_uart_write(void const *buf, int len) {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--) {
+ while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) {
+ timeout--;
+ if (timeout == 0) {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+#else
+ (void) buf;
+ (void) len;
+ return 0;
+#endif
+}
+
+void board_led_write(bool state) {
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void) {
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ (void) max_len;
+ volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8);
+ uint32_t *id32 = (uint32_t *) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_uuid[2];
+
+ return len;
+}
+
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+
+volatile uint32_t system_ticks = 0;
+void SysTick_Handler(void) {
+ system_ticks++;
+}
+
+uint32_t board_millis(void) {
+ return system_ticks;
+}
+
+void SVC_Handler(void) {
+}
+
+void PendSV_Handler(void) {
+}
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line) {
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f415/family.cmake b/hw/bsp/at32f415/family.cmake
new file mode 100644
index 000000000..8ac946265
--- /dev/null
+++ b/hw/bsp/at32f415/family.cmake
@@ -0,0 +1,108 @@
+include_guard()
+
+set(AT32_FAMILY at32f415)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4-nofpu CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f415/family.mk b/hw/bsp/at32f415/family.mk
new file mode 100644
index 000000000..73a89c543
--- /dev/null
+++ b/hw/bsp/at32f415/family.mk
@@ -0,0 +1,39 @@
+AT32_FAMILY = at32f415
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4-nofpu
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F415 \
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/synopsys/dwc2/dcd_dwc2.c \
+ src/portable/synopsys/dwc2/hcd_dwc2.c \
+ src/portable/synopsys/dwc2/dwc2_common.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+flash: flash-atlink
diff --git a/hw/bsp/at32f423/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f423/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..d5f8aafb0
--- /dev/null
+++ b/hw/bsp/at32f423/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f423.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f423/at32f423_clock.c b/hw/bsp/at32f423/at32f423_clock.c
new file mode 100644
index 000000000..564208fcb
--- /dev/null
+++ b/hw/bsp/at32f423/at32f423_clock.c
@@ -0,0 +1,127 @@
+/**
+ **************************************************************************
+ * @file at32f423_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f423_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * system clock (sclk) = (hext * pll_ns)/(pll_ms * pll_fr) / 2
+ * system clock source = pll (hext)
+ * - hext = HEXT_VALUE
+ * - sclk = 144000000
+ * - ahbdiv = 1
+ * - ahbclk = 144000000
+ * - apb2div = 1
+ * - apb2clk = 144000000
+ * - apb1div = 2
+ * - apb1clk = 72000000
+ * - pll_ns = 72
+ * - pll_ms = 1
+ * - pll_fr = 1
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* reset crm */
+ crm_reset();
+
+ /* config flash psr register */
+ flash_psr_set(FLASH_WAIT_CYCLE_4);
+
+ /* enable pwc periph clock */
+ crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
+
+ /* ensure system clock to highest, set power ldo output voltage to 1.3v */
+ pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3);
+
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
+
+ /* wait till hext is ready */
+ while(crm_hext_stable_wait() == ERROR)
+ {
+ }
+
+ /* config pll clock resource
+ common frequency config list: pll source selected hick or hext(8mhz)
+ _____________________________________________________________________________
+ | | | | | | | | |
+ | sysclk | 150 | 144 | 120 | 108 | 96 | 72 | 36 |
+ |________|_________|_________|_________|_________|_________|_________________|
+ | | | | | | | | |
+ |pll_ns | 75 | 72 | 120 | 108 | 96 | 72 | 72 |
+ | | | | | | | | |
+ |pll_ms | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+ | | | | | | | | |
+ |pll_fr | FR_2 | FR_2 | FR_4 | FR_4 | FR_4 | FR_4 | FR_8 |
+ |________|_________|_________|_________|_________|_________|________|________|
+
+ if pll clock source selects hext with other frequency values, or configure pll to other
+ frequency values, please use the at32 new clock configuration tool for configuration. */
+ crm_pll_config(CRM_PLL_SOURCE_HEXT, 72, 1, CRM_PLL_FR_2);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB2 clock is 150 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_1);
+
+ /* config apb1clk, the maximum frequency of APB1 clock is 120 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_2);
+
+ /* enable auto step mode */
+ crm_auto_step_mode_enable(TRUE);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* disable auto step mode */
+ crm_auto_step_mode_enable(FALSE);
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f423/at32f423_clock.h b/hw/bsp/at32f423/at32f423_clock.h
new file mode 100644
index 000000000..27079924d
--- /dev/null
+++ b/hw/bsp/at32f423/at32f423_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f423_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F423_CLOCK_H
+#define __AT32F423_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f423.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f423/at32f423_conf.h b/hw/bsp/at32f423/at32f423_conf.h
new file mode 100644
index 000000000..9b166d00e
--- /dev/null
+++ b/hw/bsp/at32f423/at32f423_conf.h
@@ -0,0 +1,153 @@
+/**
+ **************************************************************************
+ * @file at32f423_conf.h
+ * @brief at32f423 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F423_CONF_H
+#define __AT32F423_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ *
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ *
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
+
+/* module define -------------------------------------------------------------*/
+#define CRM_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define ERTC_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define DAC_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define XMC_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define ACC_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+#define SCFG_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef CRM_MODULE_ENABLED
+#include "at32f423_crm.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f423_tmr.h"
+#endif
+#ifdef ERTC_MODULE_ENABLED
+#include "at32f423_ertc.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f423_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f423_i2c.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f423_usart.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f423_pwc.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f423_can.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f423_adc.h"
+#endif
+#ifdef DAC_MODULE_ENABLED
+#include "at32f423_dac.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f423_spi.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f423_dma.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f423_debug.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f423_flash.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f423_crc.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f423_wwdt.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f423_wdt.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f423_exint.h"
+#endif
+#ifdef XMC_MODULE_ENABLED
+#include "at32f423_xmc.h"
+#endif
+#ifdef ACC_MODULE_ENABLED
+#include "at32f423_acc.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f423_misc.h"
+#endif
+#ifdef SCFG_MODULE_ENABLED
+#include "at32f423_scfg.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f423_usb.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f423/at32f423_int.c b/hw/bsp/at32f423/at32f423_int.c
new file mode 100644
index 000000000..2b623e053
--- /dev/null
+++ b/hw/bsp/at32f423/at32f423_int.c
@@ -0,0 +1,139 @@
+/**
+ **************************************************************************
+ * @file at32f423_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f423_int.h"
+
+/** @addtogroup AT32F423_periph_examples
+ * @{
+ */
+
+/** @addtogroup 423_USB_device_msc
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles hard fault exception.
+ * @param none
+ * @retval none
+ */
+//void HardFault_Handler(void)
+//{
+ /* go to infinite loop when hard fault exception occurs */
+ //while(1)
+ //{
+ //}
+//}
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+//void SVC_Handler(void)
+//{
+//}
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+//void PendSV_Handler(void)
+//{
+//}
+
+/**
+ * @brief this function handles systick handler.
+ * @param none
+ * @retval none
+ */
+//void SysTick_Handler(void)
+//{
+//}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f423/at32f423_int.h b/hw/bsp/at32f423/at32f423_int.h
new file mode 100644
index 000000000..28550331e
--- /dev/null
+++ b/hw/bsp/at32f423/at32f423_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f423_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F423_INT_H
+#define __AT32F423_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f423.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+//void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f423/boards/AT_START_F423/board.cmake b/hw/bsp/at32f423/boards/AT_START_F423/board.cmake
new file mode 100644
index 000000000..f97a12194
--- /dev/null
+++ b/hw/bsp/at32f423/boards/AT_START_F423/board.cmake
@@ -0,0 +1,8 @@
+set(MCU_VARIANT AT32F423VCT7)
+set(MCU_LINKER_NAME AT32F423xC)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC ${MCU_VARIANT})
+endfunction()
diff --git a/hw/bsp/at32f423/boards/AT_START_F423/board.h b/hw/bsp/at32f423/boards/AT_START_F423/board.h
new file mode 100644
index 000000000..fc8e2d8a5
--- /dev/null
+++ b/hw/bsp/at32f423/boards/AT_START_F423/board.h
@@ -0,0 +1,91 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define USB_VBUS_IGNORE
+
+// LED
+#define LED_PORT GPIOD
+#define LED_PIN GPIO_PINS_13
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 0
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+// UART
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN_SOURCE GPIO_PINS_SOURCE9
+#define PRINT_UART_TX_PIN_MUX_NUM GPIO_MUX_7
+
+//USB
+#define USB_ID 0
+#define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+#define OTG_IRQ OTGFS1_IRQn
+#define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+#define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+#define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+#define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+#define OTG_PIN_GPIO GPIOA
+#define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+#define OTG_PIN_DP GPIO_PINS_12
+#define OTG_PIN_DP_SOURCE GPIO_PINS_SOURCE12
+#define OTG_PIN_DM GPIO_PINS_11
+#define OTG_PIN_DM_SOURCE GPIO_PINS_SOURCE11
+#define OTG_PIN_VBUS GPIO_PINS_9
+#define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE9
+#define OTG_PIN_ID GPIO_PINS_10
+#define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE10
+#define OTG_PIN_SOF_GPIO GPIOA
+#define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+#define OTG_PIN_SOF GPIO_PINS_8
+#define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE8
+#define OTG_PIN_MUX GPIO_MUX_10
+
+//Vbus
+static inline void board_vbus_sense_init(void)
+{
+ *(int*)(0x50000038) |= (1<<21);
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f423/boards/AT_START_F423/board.mk b/hw/bsp/at32f423/boards/AT_START_F423/board.mk
new file mode 100644
index 000000000..f7ef2117d
--- /dev/null
+++ b/hw/bsp/at32f423/boards/AT_START_F423/board.mk
@@ -0,0 +1,7 @@
+MCU_VARIANT = AT32F423VCT7
+MCU_LINKER_NAME = AT32F423xC
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT}
diff --git a/hw/bsp/at32f423/family.c b/hw/bsp/at32f423/family.c
new file mode 100644
index 000000000..5e9e70dd8
--- /dev/null
+++ b/hw/bsp/at32f423/family.c
@@ -0,0 +1,275 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f423_clock.h"
+#include "board.h"
+#include "bsp/board_api.h"
+
+void usb_clock48m_select(usb_clk48_s clk_s);
+void led_and_button_init(void);
+void uart_print_init(uint32_t baudrate);
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void OTGFS1_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+void OTGFS1_WKUP_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+
+void board_init(void) {
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* config system clock */
+ system_clock_config();
+
+ /* enable usb clock */
+ crm_periph_clock_enable(OTG_CLOCK, TRUE);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HEXT);
+
+ /* vbus ignore */
+ board_vbus_sense_init();
+
+ /* configure systick */
+ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
+ SysTick_Config(SystemCoreClock / 1000);
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(OTG_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+#endif
+
+/* otgfs use vbus pin */
+#ifndef USB_VBUS_IGNORE
+ gpio_init_type gpio_init_struct;
+ crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
+ gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
+ gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
+#endif
+
+ /* config led and key */
+ led_and_button_init();
+
+ /* config usart printf */
+ uart_print_init(115200);
+ printf("usart printf config success!\r\n");
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s) {
+ if (clk_s == USB_CLK_HICK) {
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
+
+ /* enable the acc calibration ready interrupt */
+ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
+
+ /* update the c1\c2\c3 value */
+ acc_write_c1(7980);
+ acc_write_c2(8000);
+ acc_write_c3(8020);
+
+ /* open acc calibration */
+ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
+ } else {
+ switch (system_core_clock) {
+ /* 48MHz */
+ case 48000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2);
+ break;
+
+ /* 72MHz */
+ case 72000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3);
+ break;
+
+ /* 96MHz */
+ case 96000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_4);
+ break;
+
+ /* 120MHz */
+ case 120000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_5);
+ break;
+
+ /* 144MHz */
+ case 144000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_6);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+void uart_print_init(uint32_t baudrate) {
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+void led_and_button_init(void) {
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+}
+
+void board_led_write(bool state) {
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void) {
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ (void) max_len;
+ volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8);
+ uint32_t *id32 = (uint32_t *) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_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) {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--) {
+ while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) {
+ timeout--;
+ if (timeout == 0) {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+#else
+ (void) buf;
+ (void) len;
+ return 0;
+#endif
+}
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+volatile uint32_t system_ticks = 0;
+void SysTick_Handler(void) {
+ system_ticks++;
+}
+
+uint32_t board_millis(void) {
+ return system_ticks;
+}
+
+void SVC_Handler(void) {
+}
+
+void PendSV_Handler(void) {
+}
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line) {
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f423/family.cmake b/hw/bsp/at32f423/family.cmake
new file mode 100644
index 000000000..17c3f37a2
--- /dev/null
+++ b/hw/bsp/at32f423/family.cmake
@@ -0,0 +1,110 @@
+include_guard()
+
+set(AT32_FAMILY at32f423)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f423/family.mk b/hw/bsp/at32f423/family.mk
new file mode 100644
index 000000000..960f4a9a1
--- /dev/null
+++ b/hw/bsp/at32f423/family.mk
@@ -0,0 +1,40 @@
+AT32_FAMILY = at32f423
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F423 \
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/synopsys/dwc2/dcd_dwc2.c \
+ src/portable/synopsys/dwc2/hcd_dwc2.c \
+ src/portable/synopsys/dwc2/dwc2_common.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+flash: flash-atlink
diff --git a/hw/bsp/at32f425/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f425/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..f1784902e
--- /dev/null
+++ b/hw/bsp/at32f425/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f425.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f425/at32f425_clock.c b/hw/bsp/at32f425/at32f425_clock.c
new file mode 100644
index 000000000..16a94444f
--- /dev/null
+++ b/hw/bsp/at32f425/at32f425_clock.c
@@ -0,0 +1,91 @@
+/**
+ **************************************************************************
+ * @file at32f425_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f425_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * system clock (sclk) = hext * pll_mult
+ * system clock source = pll (hext)
+ * - hext = HEXT_VALUE
+ * - sclk = 96000000
+ * - ahbdiv = 1
+ * - ahbclk = 96000000
+ * - apb2div = 1
+ * - apb2clk = 96000000
+ * - apb1div = 1
+ * - apb1clk = 96000000
+ * - pll_mult = 12
+ * - flash_wtcyc = 2 cycle
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* reset crm */
+ crm_reset();
+
+ /* config flash psr register */
+ flash_psr_set(FLASH_WAIT_CYCLE_2);
+
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
+
+ /* wait till hext is ready */
+ while(crm_hext_stable_wait() == ERROR)
+ {
+ }
+
+ /* config pll clock resource */
+ crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_12);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB1/APB2 clock is 96 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_1);
+
+ /* config apb1clk, the maximum frequency of APB1/APB2 clock is 96 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_1);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+}
diff --git a/hw/bsp/at32f425/at32f425_clock.h b/hw/bsp/at32f425/at32f425_clock.h
new file mode 100644
index 000000000..785fcc81a
--- /dev/null
+++ b/hw/bsp/at32f425/at32f425_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f425_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F425_CLOCK_H
+#define __AT32F425_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f425.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f425/at32f425_conf.h b/hw/bsp/at32f425/at32f425_conf.h
new file mode 100644
index 000000000..79f00dfb4
--- /dev/null
+++ b/hw/bsp/at32f425/at32f425_conf.h
@@ -0,0 +1,145 @@
+/**
+ **************************************************************************
+ * @file at32f425_conf.h
+ * @brief at32f425 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F425_CONF_H
+#define __AT32F425_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ *
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ *
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
+
+/* module define -------------------------------------------------------------*/
+#define ACC_MODULE_ENABLED
+#define CRM_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define ERTC_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+#define SCFG_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef ACC_MODULE_ENABLED
+#include "at32f425_acc.h"
+#endif
+#ifdef CRM_MODULE_ENABLED
+#include "at32f425_crm.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f425_can.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f425_usb.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f425_tmr.h"
+#endif
+#ifdef ERTC_MODULE_ENABLED
+#include "at32f425_ertc.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f425_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f425_i2c.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f425_usart.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f425_pwc.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f425_adc.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f425_spi.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f425_dma.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f425_debug.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f425_flash.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f425_crc.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f425_wwdt.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f425_wdt.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f425_exint.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f425_misc.h"
+#endif
+#ifdef SCFG_MODULE_ENABLED
+#include "at32f425_scfg.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f425/at32f425_int.c b/hw/bsp/at32f425/at32f425_int.c
new file mode 100644
index 000000000..ed774f4f2
--- /dev/null
+++ b/hw/bsp/at32f425/at32f425_int.c
@@ -0,0 +1,139 @@
+/**
+ **************************************************************************
+ * @file at32f425_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f425_int.h"
+
+/** @addtogroup AT32F425_periph_examples
+ * @{
+ */
+
+/** @addtogroup 425_USB_device_msc
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles hard fault exception.
+ * @param none
+ * @retval none
+ */
+// void HardFault_Handler(void)
+// {
+// /* go to infinite loop when hard fault exception occurs */
+// while(1)
+// {
+// }
+// }
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+// void SVC_Handler(void)
+// {
+// }
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+// void PendSV_Handler(void)
+// {
+// }
+
+/**
+ * @brief this function handles systick handler.
+ * @param none
+ * @retval none
+ */
+// void SysTick_Handler(void)
+// {
+// }
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f425/at32f425_int.h b/hw/bsp/at32f425/at32f425_int.h
new file mode 100644
index 000000000..ad9dc308b
--- /dev/null
+++ b/hw/bsp/at32f425/at32f425_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f425_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F425_INT_H
+#define __AT32F425_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f425.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f425/boards/AT_START_F425/board.cmake b/hw/bsp/at32f425/boards/AT_START_F425/board.cmake
new file mode 100644
index 000000000..535bb3cb4
--- /dev/null
+++ b/hw/bsp/at32f425/boards/AT_START_F425/board.cmake
@@ -0,0 +1,12 @@
+set(MCU_VARIANT AT32F425R8T7)
+set(MCU_LINKER_NAME AT32F425x8)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC
+ ${MCU_VARIANT}
+ CFG_EXAMPLE_VIDEO_READONLY
+ CFG_EXAMPLE_MSC_READONLY
+ )
+endfunction()
diff --git a/hw/bsp/at32f425/boards/AT_START_F425/board.h b/hw/bsp/at32f425/boards/AT_START_F425/board.h
new file mode 100644
index 000000000..ddfe1f71b
--- /dev/null
+++ b/hw/bsp/at32f425/boards/AT_START_F425/board.h
@@ -0,0 +1,90 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define USB_VBUS_IGNORE
+
+// LED
+#define LED_PORT GPIOC
+#define LED_PIN GPIO_PINS_2
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 0
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+// Usart
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN_SOURCE GPIO_PINS_SOURCE9
+#define PRINT_UART_TX_PIN_MUX_NUM GPIO_MUX_1
+
+//USB
+#define USB_ID 0
+#define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+#define OTG_IRQ OTGFS1_IRQn
+#define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+#define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+#define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+#define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+#define OTG_PIN_GPIO GPIOA
+#define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+#define OTG_PIN_DP GPIO_PINS_12
+#define OTG_PIN_DP_SOURCE GPIO_PINS_SOURCE12
+#define OTG_PIN_DM GPIO_PINS_11
+#define OTG_PIN_DM_SOURCE GPIO_PINS_SOURCE11
+#define OTG_PIN_VBUS GPIO_PINS_9
+#define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE9
+#define OTG_PIN_ID GPIO_PINS_10
+#define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE10
+#define OTG_PIN_SOF_GPIO GPIOA
+#define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+#define OTG_PIN_SOF GPIO_PINS_8
+#define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE8
+#define OTG_PIN_MUX GPIO_MUX_3
+
+static inline void board_vbus_sense_init(void)
+{
+ *(int*)(0x50000038) |= (1<<21);
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f425/boards/AT_START_F425/board.mk b/hw/bsp/at32f425/boards/AT_START_F425/board.mk
new file mode 100644
index 000000000..f7aeba1db
--- /dev/null
+++ b/hw/bsp/at32f425/boards/AT_START_F425/board.mk
@@ -0,0 +1,9 @@
+MCU_VARIANT = AT32F425R8T7
+MCU_LINKER_NAME = AT32F425x8
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT} \
+ -DCFG_EXAMPLE_VIDEO_READONLY \
+ -DCFG_EXAMPLE_MSC_READONLY
diff --git a/hw/bsp/at32f425/family.c b/hw/bsp/at32f425/family.c
new file mode 100644
index 000000000..26e69bf31
--- /dev/null
+++ b/hw/bsp/at32f425/family.c
@@ -0,0 +1,279 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f425_clock.h"
+#include "board.h"
+#include "bsp/board_api.h"
+
+void uart_print_init(uint32_t baudrate);
+void usb_clock48m_select(usb_clk48_s clk_s);
+void led_and_button_init(void);
+
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void OTGFS1_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+void OTGFS1_WKUP_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+
+void board_init(void) {
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* config system clock */
+ system_clock_config();
+
+ /* enable usb clock */
+ crm_periph_clock_enable(OTG_CLOCK, TRUE);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HEXT);
+
+ /* vbus ignore */
+ board_vbus_sense_init();
+
+ /* configure systick */
+ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
+ SysTick_Config(SystemCoreClock / 1000);
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(OTG_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+#endif
+
+/* otgfs use vbus pin */
+#ifndef USB_VBUS_IGNORE
+ gpio_init_type gpio_init_struct;
+ crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
+ gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
+ gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
+#endif
+
+ /* config led and key */
+ led_and_button_init();
+
+ /* config usart printf */
+ uart_print_init(115200);
+ printf("usart printf config success!\r\n");
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s) {
+ if (clk_s == USB_CLK_HICK) {
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
+
+ /* enable the acc calibration ready interrupt */
+ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
+
+ /* update the c1\c2\c3 value */
+ acc_write_c1(7980);
+ acc_write_c2(8000);
+ acc_write_c3(8020);
+
+ /* open acc calibration */
+ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
+ } else {
+ /* usb divider reset */
+ crm_usb_div_reset();
+
+ switch (system_core_clock) {
+ /* 48MHz */
+ case 48000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1);
+ break;
+
+ /* 72MHz */
+ case 72000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1_5);
+ break;
+
+ /* 96MHz */
+ case 96000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void led_and_button_init(void) {
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+}
+
+/**
+ * @brief initialize uart
+ * @param baudrate: uart baudrate
+ * @retval none
+ */
+void uart_print_init(uint32_t baudrate) {
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+// Get characters from UART. Return number of read bytes
+int board_uart_read(uint8_t *buf, int len) {
+ (void) buf;
+ (void) len;
+ return 0;
+}
+
+// Send characters to UART. Return number of sent bytes
+int board_uart_write(void const *buf, int len) {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--) {
+ while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) {
+ timeout--;
+ if (timeout == 0) {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+#else
+ (void) buf;
+ (void) len;
+ return 0;
+#endif
+}
+
+void board_led_write(bool state) {
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void) {
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ (void) max_len;
+ volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8);
+ uint32_t *id32 = (uint32_t *) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_uuid[2];
+
+ return len;
+}
+
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+
+volatile uint32_t system_ticks = 0;
+void SysTick_Handler(void) {
+ system_ticks++;
+}
+
+uint32_t board_millis(void) {
+ return system_ticks;
+}
+
+void SVC_Handler(void) {
+}
+
+void PendSV_Handler(void) {
+}
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line) {
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f425/family.cmake b/hw/bsp/at32f425/family.cmake
new file mode 100644
index 000000000..3f6b36a6b
--- /dev/null
+++ b/hw/bsp/at32f425/family.cmake
@@ -0,0 +1,108 @@
+include_guard()
+
+set(AT32_FAMILY at32f425)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4-nofpu CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f425/family.mk b/hw/bsp/at32f425/family.mk
new file mode 100644
index 000000000..0a0a74414
--- /dev/null
+++ b/hw/bsp/at32f425/family.mk
@@ -0,0 +1,39 @@
+AT32_FAMILY = at32f425
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4-nofpu
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F425 \
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/synopsys/dwc2/dcd_dwc2.c \
+ src/portable/synopsys/dwc2/hcd_dwc2.c \
+ src/portable/synopsys/dwc2/dwc2_common.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+flash: flash-atlink
diff --git a/hw/bsp/at32f435_437/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f435_437/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..4e24ead70
--- /dev/null
+++ b/hw/bsp/at32f435_437/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,177 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// Include MCU header
+ #include "at32f435_437.h"
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configCHECK_HANDLER_INSTALLATION 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/hw/bsp/at32f435_437/at32f435_437_clock.c b/hw/bsp/at32f435_437/at32f435_437_clock.c
new file mode 100644
index 000000000..bec5800aa
--- /dev/null
+++ b/hw/bsp/at32f435_437/at32f435_437_clock.c
@@ -0,0 +1,119 @@
+/**
+ **************************************************************************
+ * @file at32f435_437_clock.c
+ * @brief system clock config program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f435_437_clock.h"
+
+/**
+ * @brief system clock config program
+ * @note the system clock is configured as follow:
+ * system clock (sclk) = (hext * pll_ns)/(pll_ms * pll_fr)
+ * system clock source = pll (hext)
+ * - hext = HEXT_VALUE
+ * - sclk = 288000000
+ * - ahbdiv = 1
+ * - ahbclk = 288000000
+ * - apb2div = 2
+ * - apb2clk = 144000000
+ * - apb1div = 2
+ * - apb1clk = 144000000
+ * - pll_ns = 144
+ * - pll_ms = 1
+ * - pll_fr = 4
+ * @param none
+ * @retval none
+ */
+void system_clock_config(void)
+{
+ /* reset crm */
+ crm_reset();
+
+ /* enable pwc periph clock */
+ crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
+
+ /* config ldo voltage */
+ pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3);
+
+ /* set the flash clock divider */
+ flash_clock_divider_set(FLASH_CLOCK_DIV_3);
+
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
+
+ /* wait till hext is ready */
+ while(crm_hext_stable_wait() == ERROR)
+ {
+ }
+
+ /* config pll clock resource
+ common frequency config list: pll source selected hick or hext(8mhz)
+ _________________________________________________________________________________________________
+ | | | | | | | | | | |
+ |pll(mhz)| 288 | 252 | 216 | 192 | 180 | 144 | 108 | 72 | 36 |
+ |________|_________|_________|_________|_________|_________|_________|_________|_________________|
+ | | | | | | | | | | |
+ |pll_ns | 144 | 126 | 108 | 96 | 90 | 72 | 108 | 72 | 72 |
+ | | | | | | | | | | |
+ |pll_ms | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+ | | | | | | | | | | |
+ |pll_fr | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_8 | FR_8 | FR_16|
+ |________|_________|_________|_________|_________|_________|_________|_________|________|________|
+
+ if pll clock source selects hext with other frequency values, or configure pll to other
+ frequency values, please use the at32 new clock configuration tool for configuration. */
+ crm_pll_config(CRM_PLL_SOURCE_HEXT, 144, 1, CRM_PLL_FR_4);
+
+ /* enable pll */
+ crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
+
+ /* wait till pll is ready */
+ while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
+ {
+ }
+
+ /* config ahbclk */
+ crm_ahb_div_set(CRM_AHB_DIV_1);
+
+ /* config apb2clk, the maximum frequency of APB1/APB2 clock is 144 MHz */
+ crm_apb2_div_set(CRM_APB2_DIV_2);
+
+ /* config apb1clk, the maximum frequency of APB1/APB2 clock is 144 MHz */
+ crm_apb1_div_set(CRM_APB1_DIV_2);
+
+ /* enable auto step mode */
+ crm_auto_step_mode_enable(TRUE);
+
+ /* select pll as system clock source */
+ crm_sysclk_switch(CRM_SCLK_PLL);
+
+ /* wait till pll is used as system clock source */
+ while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
+ {
+ }
+
+ /* disable auto step mode */
+ crm_auto_step_mode_enable(FALSE);
+
+ /* update system_core_clock global variable */
+ system_core_clock_update();
+}
diff --git a/hw/bsp/at32f435_437/at32f435_437_clock.h b/hw/bsp/at32f435_437/at32f435_437_clock.h
new file mode 100644
index 000000000..6d0273f30
--- /dev/null
+++ b/hw/bsp/at32f435_437/at32f435_437_clock.h
@@ -0,0 +1,43 @@
+/**
+ **************************************************************************
+ * @file at32f435_437_clock.h
+ * @brief header file of clock program
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F435_437_CLOCK_H
+#define __AT32F435_437_CLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f435_437.h"
+
+/* exported functions ------------------------------------------------------- */
+void system_clock_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f435_437/at32f435_437_conf.h b/hw/bsp/at32f435_437/at32f435_437_conf.h
new file mode 100644
index 000000000..54ab75b5f
--- /dev/null
+++ b/hw/bsp/at32f435_437/at32f435_437_conf.h
@@ -0,0 +1,173 @@
+/**
+ **************************************************************************
+ * @file at32f435_437_conf.h
+ * @brief at32f435_437 config header file
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F435_437_CONF_H
+#define __AT32F435_437_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief in the following line adjust the value of high speed external crystal (hext)
+ * used in your application
+ *
+ * tip: to avoid modifying this file each time you need to use different hext, you
+ * can define the hext value in your toolchain compiler preprocessor.
+ *
+ */
+#if !defined HEXT_VALUE
+#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
+#endif
+
+/**
+ * @brief in the following line adjust the high speed external crystal (hext) startup
+ * timeout value
+ */
+#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
+#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
+#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
+
+/* module define -------------------------------------------------------------*/
+#define CRM_MODULE_ENABLED
+#define TMR_MODULE_ENABLED
+#define ERTC_MODULE_ENABLED
+#define GPIO_MODULE_ENABLED
+#define I2C_MODULE_ENABLED
+#define USART_MODULE_ENABLED
+#define PWC_MODULE_ENABLED
+#define CAN_MODULE_ENABLED
+#define ADC_MODULE_ENABLED
+#define DAC_MODULE_ENABLED
+#define SPI_MODULE_ENABLED
+#define EDMA_MODULE_ENABLED
+#define DMA_MODULE_ENABLED
+#define DEBUG_MODULE_ENABLED
+#define FLASH_MODULE_ENABLED
+#define CRC_MODULE_ENABLED
+#define WWDT_MODULE_ENABLED
+#define WDT_MODULE_ENABLED
+#define EXINT_MODULE_ENABLED
+#define SDIO_MODULE_ENABLED
+#define XMC_MODULE_ENABLED
+#define USB_MODULE_ENABLED
+#define ACC_MODULE_ENABLED
+#define MISC_MODULE_ENABLED
+#define QSPI_MODULE_ENABLED
+#define DVP_MODULE_ENABLED
+#define SCFG_MODULE_ENABLED
+#define EMAC_MODULE_ENABLED
+
+/* includes ------------------------------------------------------------------*/
+#ifdef CRM_MODULE_ENABLED
+#include "at32f435_437_crm.h"
+#endif
+#ifdef TMR_MODULE_ENABLED
+#include "at32f435_437_tmr.h"
+#endif
+#ifdef ERTC_MODULE_ENABLED
+#include "at32f435_437_ertc.h"
+#endif
+#ifdef GPIO_MODULE_ENABLED
+#include "at32f435_437_gpio.h"
+#endif
+#ifdef I2C_MODULE_ENABLED
+#include "at32f435_437_i2c.h"
+#endif
+#ifdef USART_MODULE_ENABLED
+#include "at32f435_437_usart.h"
+#endif
+#ifdef PWC_MODULE_ENABLED
+#include "at32f435_437_pwc.h"
+#endif
+#ifdef CAN_MODULE_ENABLED
+#include "at32f435_437_can.h"
+#endif
+#ifdef ADC_MODULE_ENABLED
+#include "at32f435_437_adc.h"
+#endif
+#ifdef DAC_MODULE_ENABLED
+#include "at32f435_437_dac.h"
+#endif
+#ifdef SPI_MODULE_ENABLED
+#include "at32f435_437_spi.h"
+#endif
+#ifdef DMA_MODULE_ENABLED
+#include "at32f435_437_dma.h"
+#endif
+#ifdef DEBUG_MODULE_ENABLED
+#include "at32f435_437_debug.h"
+#endif
+#ifdef FLASH_MODULE_ENABLED
+#include "at32f435_437_flash.h"
+#endif
+#ifdef CRC_MODULE_ENABLED
+#include "at32f435_437_crc.h"
+#endif
+#ifdef WWDT_MODULE_ENABLED
+#include "at32f435_437_wwdt.h"
+#endif
+#ifdef WDT_MODULE_ENABLED
+#include "at32f435_437_wdt.h"
+#endif
+#ifdef EXINT_MODULE_ENABLED
+#include "at32f435_437_exint.h"
+#endif
+#ifdef SDIO_MODULE_ENABLED
+#include "at32f435_437_sdio.h"
+#endif
+#ifdef XMC_MODULE_ENABLED
+#include "at32f435_437_xmc.h"
+#endif
+#ifdef ACC_MODULE_ENABLED
+#include "at32f435_437_acc.h"
+#endif
+#ifdef MISC_MODULE_ENABLED
+#include "at32f435_437_misc.h"
+#endif
+#ifdef EDMA_MODULE_ENABLED
+#include "at32f435_437_edma.h"
+#endif
+#ifdef QSPI_MODULE_ENABLED
+#include "at32f435_437_qspi.h"
+#endif
+#ifdef SCFG_MODULE_ENABLED
+#include "at32f435_437_scfg.h"
+#endif
+#ifdef EMAC_MODULE_ENABLED
+#include "at32f435_437_emac.h"
+#endif
+#ifdef DVP_MODULE_ENABLED
+#include "at32f435_437_dvp.h"
+#endif
+#ifdef USB_MODULE_ENABLED
+#include "at32f435_437_usb.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f435_437/at32f435_437_int.c b/hw/bsp/at32f435_437/at32f435_437_int.c
new file mode 100644
index 000000000..119a0c960
--- /dev/null
+++ b/hw/bsp/at32f435_437/at32f435_437_int.c
@@ -0,0 +1,119 @@
+/**
+ **************************************************************************
+ * @file at32f435_437_int.c
+ * @brief main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f435_437_int.h"
+
+/** @addtogroup AT32F437_periph_examples
+ * @{
+ */
+
+/** @addtogroup 437_USB_device_msc
+ * @{
+ */
+
+/**
+ * @brief this function handles nmi exception.
+ * @param none
+ * @retval none
+ */
+void NMI_Handler(void)
+{
+}
+
+
+/**
+ * @brief this function handles memory manage exception.
+ * @param none
+ * @retval none
+ */
+void MemManage_Handler(void)
+{
+ /* go to infinite loop when memory manage exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles bus fault exception.
+ * @param none
+ * @retval none
+ */
+void BusFault_Handler(void)
+{
+ /* go to infinite loop when bus fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles usage fault exception.
+ * @param none
+ * @retval none
+ */
+void UsageFault_Handler(void)
+{
+ /* go to infinite loop when usage fault exception occurs */
+ while(1)
+ {
+ }
+}
+
+/**
+ * @brief this function handles svcall exception.
+ * @param none
+ * @retval none
+ */
+//void SVC_Handler(void)
+//{
+//}
+
+/**
+ * @brief this function handles debug monitor exception.
+ * @param none
+ * @retval none
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief this function handles pendsv_handler exception.
+ * @param none
+ * @retval none
+ */
+//void PendSV_Handler(void)
+//{
+//}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/hw/bsp/at32f435_437/at32f435_437_int.h b/hw/bsp/at32f435_437/at32f435_437_int.h
new file mode 100644
index 000000000..76bfaaae4
--- /dev/null
+++ b/hw/bsp/at32f435_437/at32f435_437_int.h
@@ -0,0 +1,55 @@
+/**
+ **************************************************************************
+ * @file at32f435_437_int.h
+ * @brief header file of main interrupt service routines.
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+/* define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AT32F435_437_INT_H
+#define __AT32F435_437_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* includes ------------------------------------------------------------------*/
+#include "at32f435_437.h"
+
+/* exported types ------------------------------------------------------------*/
+/* exported constants --------------------------------------------------------*/
+/* exported macro ------------------------------------------------------------*/
+/* exported functions ------------------------------------------------------- */
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.cmake b/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.cmake
new file mode 100644
index 000000000..fc54dbcab
--- /dev/null
+++ b/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.cmake
@@ -0,0 +1,8 @@
+set(MCU_VARIANT AT32F437ZMT7)
+set(MCU_LINKER_NAME AT32F437xM)
+
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC ${MCU_VARIANT})
+endfunction()
diff --git a/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.h b/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.h
new file mode 100644
index 000000000..ef4ec6dcf
--- /dev/null
+++ b/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.h
@@ -0,0 +1,182 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//#define USB_VBUS_IGNORE
+//#define USB_SOF_OUTPUT_ENABLE
+
+// LED
+#define LED_PORT GPIOD
+#define LED_PIN GPIO_PINS_13
+#define LED_STATE_ON 0 // Active Low
+#define LED_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE)
+
+// Button
+#define BUTTON_PORT GPIOA
+#define BUTTON_PIN GPIO_PINS_0
+#define BUTTON_STATE_ACTIVE 1
+#define BUTTON_GPIO_CLK_EN() crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE)
+
+// USART
+#define PRINT_UART USART1
+#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN GPIO_PINS_9
+#define PRINT_UART_TX_GPIO GPIOA
+#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
+#define PRINT_UART_TX_PIN_SOURCE GPIO_PINS_SOURCE9
+#define PRINT_UART_TX_PIN_MUX_NUM GPIO_MUX_7
+
+// USB
+#ifdef BOARD_TUD_RHPORT
+ #if BOARD_TUD_RHPORT == 0
+ #define USB_ID 0
+ #define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+ #define OTG_IRQ OTGFS1_IRQn
+ #define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+ #define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+ #define OTG_PIN_GPIO GPIOA
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_DP GPIO_PINS_12
+ #define OTG_PIN_DP_SOURCE GPIO_PINS_SOURCE12
+ #define OTG_PIN_DM GPIO_PINS_11
+ #define OTG_PIN_DM_SOURCE GPIO_PINS_SOURCE11
+ #define OTG_PIN_VBUS GPIO_PINS_9
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE9
+ #define OTG_PIN_ID GPIO_PINS_10
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE12
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_8
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE8
+ #define OTG_PIN_MUX GPIO_MUX_10
+ #elif BOARD_TUD_RHPORT == 1
+ #define USB_ID 1
+ #define OTG_CLOCK CRM_OTGFS2_PERIPH_CLOCK
+ #define OTG_IRQ OTGFS2_IRQn
+ #define OTG_IRQ_HANDLER OTGFS2_IRQHandler
+ #define OTG_WKUP_IRQ OTGFS2_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGFS2_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_20
+ #define OTG_PIN_GPIO GPIOB
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOB_PERIPH_CLOCK
+ #define OTG_PIN_DP GPIO_PINS_15
+ #define OTG_PIN_DP_SOURCE GPIO_PINS_SOURCE15
+ #define OTG_PIN_DM GPIO_PINS_14
+ #define OTG_PIN_DM_SOURCE GPIO_PINS_SOURCE14
+ #define OTG_PIN_VBUS GPIO_PINS_13
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE13
+ #define OTG_PIN_ID GPIO_PINS_12
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE10
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_4
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE4
+ #define OTG_PIN_MUX GPIO_MUX_12
+ #endif
+#endif
+
+#ifdef BOARD_TUH_RHPORT
+ #if BOARD_TUH_RHPORT == 0
+ #define USB_ID 0
+ #define OTG_CLOCK CRM_OTGFS1_PERIPH_CLOCK
+ #define OTG_IRQ OTGFS1_IRQn
+ #define OTG_IRQ_HANDLER OTGFS1_IRQHandler
+ #define OTG_WKUP_IRQ OTGFS1_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGFS1_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_18
+ #define OTG_PIN_GPIO GPIOA
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_DP GPIO_PINS_12
+ #define OTG_PIN_DP_SOURCE GPIO_PINS_SOURCE12
+ #define OTG_PIN_DM GPIO_PINS_11
+ #define OTG_PIN_DM_SOURCE GPIO_PINS_SOURCE11
+ #define OTG_PIN_VBUS GPIO_PINS_9
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE9
+ #define OTG_PIN_ID GPIO_PINS_10
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE12
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_8
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE8
+ #define OTG_PIN_MUX GPIO_MUX_10
+ #elif BOARD_TUH_RHPORT == 1
+ #define USB_ID 1
+ #define OTG_CLOCK CRM_OTGFS2_PERIPH_CLOCK
+ #define OTG_IRQ OTGFS2_IRQn
+ #define OTG_IRQ_HANDLER OTGFS2_IRQHandler
+ #define OTG_WKUP_IRQ OTGFS2_WKUP_IRQn
+ #define OTG_WKUP_HANDLER OTGFS2_WKUP_IRQHandler
+ #define OTG_WKUP_EXINT_LINE EXINT_LINE_20
+ #define OTG_PIN_GPIO GPIOB
+ #define OTG_PIN_GPIO_CLOCK CRM_GPIOB_PERIPH_CLOCK
+ #define OTG_PIN_DP GPIO_PINS_15
+ #define OTG_PIN_DP_SOURCE GPIO_PINS_SOURCE15
+ #define OTG_PIN_DM GPIO_PINS_14
+ #define OTG_PIN_DM_SOURCE GPIO_PINS_SOURCE14
+ #define OTG_PIN_VBUS GPIO_PINS_13
+ #define OTG_PIN_VBUS_SOURCE GPIO_PINS_SOURCE13
+ #define OTG_PIN_ID GPIO_PINS_12
+ #define OTG_PIN_ID_SOURCE GPIO_PINS_SOURCE10
+ #define OTG_PIN_SOF_GPIO GPIOA
+ #define OTG_PIN_SOF_GPIO_CLOCK CRM_GPIOA_PERIPH_CLOCK
+ #define OTG_PIN_SOF GPIO_PINS_4
+ #define OTG_PIN_SOF_SOURCE GPIO_PINS_SOURCE4
+ #define OTG_PIN_MUX GPIO_MUX_12
+ #endif
+#endif
+
+// VBUS
+static inline void board_vbus_sense_init(void)
+{
+ #ifdef BOARD_TUD_RHPORT
+ #if BOARD_TUD_RHPORT == 0
+ *(int*)(0x50000038) |= (1<<21);
+ #elif BOARD_TUD_RHPORT == 1
+ *(int*)(0x40040038) |= (1<<21);
+ #endif
+ #endif
+ #ifdef BOARD_TUH_RHPORT
+ #if BOARD_TUH_RHPORT == 0
+ *(int*)(0x50000038) |= (1<<21);
+ #elif BOARD_TUH_RHPORT == 1
+ *(int*)(0x40040038) |= (1<<21);
+ #endif
+ #endif
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.mk b/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.mk
new file mode 100644
index 000000000..e663d59f0
--- /dev/null
+++ b/hw/bsp/at32f435_437/boards/AT_START_F435_437/board.mk
@@ -0,0 +1,7 @@
+MCU_VARIANT = AT32F437ZMT7
+MCU_LINKER_NAME = AT32F437xM
+
+JLINK_DEVICE = ${MCU_VARIANT}
+
+CFLAGS += \
+ -D${MCU_VARIANT}
diff --git a/hw/bsp/at32f435_437/family.c b/hw/bsp/at32f435_437/family.c
new file mode 100644
index 000000000..c93beeb5a
--- /dev/null
+++ b/hw/bsp/at32f435_437/family.c
@@ -0,0 +1,347 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "at32f435_437_clock.h"
+#include "board.h"
+#include "bsp/board_api.h"
+
+void usb_gpio_config(void);
+void uart_print_init(uint32_t baudrate);
+void usb_clock48m_select(usb_clk48_s clk_s);
+void led_and_botton_init(void);
+int inHandlerMode(void);
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+void OTGFS1_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+void OTGFS2_IRQHandler(void) {
+ tusb_int_handler(1, true);
+}
+void OTGFS1_WKUP_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+void OTGFS2_WKUP_IRQHandler(void) {
+ tusb_int_handler(1, true);
+}
+
+void board_init(void) {
+ /* config nvic priority group */
+ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ /* config system clock to 288Mhz */
+ system_clock_config();
+
+ /* config usb io */
+ usb_gpio_config();
+
+ /* enable usb clock */
+ crm_periph_clock_enable(OTG_CLOCK, TRUE);
+
+ /* select usb 48m clcok source */
+ usb_clock48m_select(USB_CLK_HEXT);
+
+ /* enable otgfs irq */
+ //nvic_irq_enable(OTG_IRQ, 0, 0);
+
+ /* vbus ignore */
+ board_vbus_sense_init();
+
+ SysTick_Config(SystemCoreClock / 1000);
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
+ NVIC_SetPriority(OTG_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
+#endif
+
+ /* config led and key */
+ led_and_botton_init();
+
+ /* config usart printf */
+ uart_print_init(115200);
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+/**
+ * @brief usb 48M clock select
+ * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT
+ * @retval none
+ */
+void usb_clock48m_select(usb_clk48_s clk_s) {
+ if (clk_s == USB_CLK_HICK) {
+ crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK);
+
+ /* enable the acc calibration ready interrupt */
+ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE);
+
+ /* update the c1\c2\c3 value */
+ acc_write_c1(7980);
+ acc_write_c2(8000);
+ acc_write_c3(8020);
+#ifdef BOARD_TUD_RHPORT
+ #if BOARD_TUD_RHPORT == 0
+ acc_sof_select(ACC_SOF_OTG1);
+ #else
+ acc_sof_select(ACC_SOF_OTG2);
+ #endif
+#endif
+ /* open acc calibration */
+ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE);
+ } else {
+ switch (system_core_clock) {
+ /* 48MHz */
+ case 48000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1);
+ break;
+
+ /* 72MHz */
+ case 72000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_1_5);
+ break;
+
+ /* 96MHz */
+ case 96000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2);
+ break;
+
+ /* 120MHz */
+ case 120000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_2_5);
+ break;
+
+ /* 144MHz */
+ case 144000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3);
+ break;
+
+ /* 168MHz */
+ case 168000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_3_5);
+ break;
+
+ /* 192MHz */
+ case 192000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_4);
+ break;
+
+ /* 216MHz */
+ case 216000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_4_5);
+ break;
+
+ /* 240MHz */
+ case 240000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_5);
+ break;
+
+ /* 264MHz */
+ case 264000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_5_5);
+ break;
+
+ /* 288MHz */
+ case 288000000:
+ crm_usb_clock_div_set(CRM_USB_DIV_6);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void led_and_botton_init(void) {
+ /* LED */
+ gpio_init_type gpio_led_init_struct;
+ /* enable the led clock */
+ LED_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_led_init_struct);
+ /* configure the led gpio */
+ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+ gpio_led_init_struct.gpio_pins = LED_PIN;
+ gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(LED_PORT, &gpio_led_init_struct);
+ gpio_bits_set(LED_PORT, LED_PIN);
+ gpio_bits_set(LED_PORT, GPIO_PINS_14);
+ gpio_bits_set(LED_PORT, GPIO_PINS_15);
+ /* Button */
+ gpio_init_type gpio_button_init_struct;
+ /* enable the button clock */
+ BUTTON_GPIO_CLK_EN();
+ /* set default parameter */
+ gpio_default_para_init(&gpio_button_init_struct);
+ /* configure the button gpio */
+ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT;
+ gpio_button_init_struct.gpio_pins = BUTTON_PIN;
+ gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_init(BUTTON_PORT, &gpio_button_init_struct);
+}
+
+/**
+ * @brief initialize uart
+ * @param baudrate: uart baudrate
+ * @retval none
+ */
+void uart_print_init(uint32_t baudrate) {
+ gpio_init_type gpio_init_struct;
+ /* enable the uart and gpio clock */
+ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
+ crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ /* configure the uart tx pin */
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM);
+ /* configure uart param */
+ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
+ usart_transmitter_enable(PRINT_UART, TRUE);
+ usart_enable(PRINT_UART, TRUE);
+}
+
+// Get characters from UART. Return number of read bytes
+int board_uart_read(uint8_t *buf, int len) {
+ (void) buf;
+ (void) len;
+ return 0;
+}
+// Send characters to UART. Return number of sent bytes
+int board_uart_write(void const *buf, int len) {
+#if CFG_TUSB_OS == OPT_OS_NONE
+ int txsize = len;
+ u16 timeout = 0xffff;
+ while (txsize--) {
+ while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) {
+ timeout--;
+ if (timeout == 0) {
+ return 0;
+ }
+ }
+ PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF);
+ buf++;
+ }
+ return len;
+#else
+ (void) buf;
+ (void) len;
+ return 0;
+#endif
+}
+
+int inHandlerMode(void) {
+ return __get_IPSR();
+}
+
+void usb_gpio_config(void) {
+ gpio_init_type gpio_init_struct;
+ crm_periph_clock_enable(OTG_PIN_GPIO_CLOCK, TRUE);
+ gpio_default_para_init(&gpio_init_struct);
+ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+ gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+ gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+ gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+ /* dp and dm */
+ gpio_init_struct.gpio_pins = OTG_PIN_DP | OTG_PIN_DM;
+ gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_DP_SOURCE, OTG_PIN_MUX);
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_DM_SOURCE, OTG_PIN_MUX);
+#ifdef USB_SOF_OUTPUT_ENABLE
+ crm_periph_clock_enable(OTG_PIN_SOF_GPIO_CLOCK, TRUE);
+ gpio_init_struct.gpio_pins = OTG_PIN_SOF;
+ gpio_init(OTG_PIN_SOF_GPIO, &gpio_init_struct);
+ gpio_pin_mux_config(OTG_PIN_SOF_GPIO, OTG_PIN_SOF_SOURCE, OTG_PIN_MUX);
+#endif
+ /* otgfs use vbus pin */
+#ifndef USB_VBUS_IGNORE
+ gpio_init_struct.gpio_pins = OTG_PIN_VBUS;
+ gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
+ gpio_pin_mux_config(OTG_PIN_GPIO, OTG_PIN_VBUS_SOURCE, OTG_PIN_MUX);
+ gpio_init(OTG_PIN_GPIO, &gpio_init_struct);
+#endif
+}
+
+void board_led_write(bool state) {
+ gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON));
+}
+
+uint32_t board_button_read(void) {
+ return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN);
+}
+
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ (void) max_len;
+ volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8);
+ uint32_t *id32 = (uint32_t *) (uintptr_t) id;
+ uint8_t const len = 12;
+
+ id32[0] = at32_uuid[0];
+ id32[1] = at32_uuid[1];
+ id32[2] = at32_uuid[2];
+
+ return len;
+}
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+volatile uint32_t system_ticks = 0;
+void SysTick_Handler(void) {
+ system_ticks++;
+}
+uint32_t board_millis(void) {
+ return system_ticks;
+}
+void SVC_Handler(void) {
+}
+void PendSV_Handler(void) {
+}
+#endif
+
+void HardFault_Handler(void) {
+ __asm("BKPT #0\n");
+}
+
+// Required by __libc_init_array in startup code if we are compiling using
+// -nostdlib/-nostartfiles.
+void _init(void) {
+}
+
+#ifdef USE_FULL_ASSERT
+void assert_failed(const char *file, uint32_t line) {
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/hw/bsp/at32f435_437/family.cmake b/hw/bsp/at32f435_437/family.cmake
new file mode 100644
index 000000000..c85b58ae4
--- /dev/null
+++ b/hw/bsp/at32f435_437/family.cmake
@@ -0,0 +1,114 @@
+include_guard()
+
+set(AT32_FAMILY at32f435_437)
+set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries)
+
+string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "")
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ # Startup & Linker script
+ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s)
+ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+ set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s)
+
+ if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld)
+ endif ()
+ set(LD_FILE_Clang ${LD_FILE_GNU})
+ set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf)
+
+ add_library(${BOARD_TARGET} STATIC
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c
+ ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_exint.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${AT32_SDK_LIB}/cmsis/cm4/core_support
+ ${AT32_SDK_LIB}/cmsis/cm4/device_support
+ ${AT32_SDK_LIB}/drivers/inc
+ )
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ BOARD_TUD_RHPORT=0
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_Clang}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER})
+ target_sources(${TARGET} PUBLIC
+ ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
+ ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
+ )
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD})
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/at32f435_437/family.mk b/hw/bsp/at32f435_437/family.mk
new file mode 100644
index 000000000..b33be1180
--- /dev/null
+++ b/hw/bsp/at32f435_437/family.mk
@@ -0,0 +1,42 @@
+AT32_FAMILY = at32f435_437
+AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= cortex-m4
+
+CFLAGS_GCC += \
+ -flto
+
+CFLAGS += \
+ -DCFG_TUSB_MCU=OPT_MCU_AT32F435_437 \
+ -DBOARD_TUD_RHPORT=0
+
+LDFLAGS_GCC += \
+ -flto --specs=nosys.specs -nostdlib -nostartfiles
+
+SRC_C += \
+ src/portable/synopsys/dwc2/dcd_dwc2.c \
+ src/portable/synopsys/dwc2/hcd_dwc2.c \
+ src/portable/synopsys/dwc2/dwc2_common.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \
+ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_exint.c \
+ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \
+ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support
+
+SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s
+SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s
+
+LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld
+LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf
+
+flash: flash-atlink
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index 4b987cbaf..a91759b84 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -568,6 +568,44 @@
#define TUP_RHPORT_HIGHSPEED 1
#define TUD_ENDPOINT_ONE_DIRECTION_ONLY
+//--------------------------------------------------------------------+
+// ArteryTek
+//--------------------------------------------------------------------+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F403A_407)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_AT32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F413)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_AT32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F415)
+ #define TUP_USBIP_DWC2
+ #define TUP_USBIP_DWC2_AT32
+ #define TUP_DCD_ENDPOINT_MAX 4
+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F435_437)
+ #define TUP_USBIP_DWC2
+ #define TUP_USBIP_DWC2_AT32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F423)
+ #define TUP_USBIP_DWC2
+ #define TUP_USBIP_DWC2_AT32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F402_405)
+ #define TUP_USBIP_DWC2
+ #define TUP_USBIP_DWC2_AT32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
+#elif TU_CHECK_MCU(OPT_MCU_AT32F425)
+ #define TUP_USBIP_DWC2
+ #define TUP_USBIP_DWC2_AT32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
#endif
//--------------------------------------------------------------------+
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index ef58957bb..5d6033a66 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -117,6 +117,8 @@
#include "fsdev_stm32.h"
#elif defined(TUP_USBIP_FSDEV_CH32)
#include "fsdev_ch32.h"
+#elif defined(TUP_USBIP_FSDEV_AT32)
+ #include "fsdev_at32.h"
#else
#error "Unknown USB IP"
#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_at32.h b/src/portable/st/stm32_fsdev/fsdev_at32.h
new file mode 100644
index 000000000..3a785bbbd
--- /dev/null
+++ b/src/portable/st/stm32_fsdev/fsdev_at32.h
@@ -0,0 +1,220 @@
+/*
+* 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.
+ *
+ */
+#ifndef TUSB_FSDEV_AT32_H
+#define TUSB_FSDEV_AT32_H
+
+#include "common/tusb_compiler.h"
+
+#if CFG_TUSB_MCU == OPT_MCU_AT32F403A_407
+ #include "at32f403a_407.h"
+
+#elif CFG_TUSB_MCU == OPT_MCU_AT32F413
+ #include "at32f413.h"
+
+#endif
+
+#define FSDEV_PMA_SIZE (512u)
+#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
+#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
+
+/**************************** 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)
+
+#include "fsdev_type.h"
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
+static const IRQn_Type fsdev_irq[] = {
+ USBFS_H_CAN1_TX_IRQn,
+ USBFS_L_CAN1_RX0_IRQn,
+ USBFSWakeUp_IRQn
+};
+enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
+
+#else
+ #error "Unsupported MCU"
+#endif
+
+void dcd_int_enable(uint8_t rhport) {
+ (void)rhport;
+ #if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
+ // AT32F403A/407 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 (CRM->intmap_bit.usbintmap) {
+ NVIC_DisableIRQ(USBFS_MAPH_IRQn);
+ NVIC_DisableIRQ(USBFS_MAPL_IRQn);
+ NVIC_DisableIRQ(USBFSWakeUp_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_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
+ // AT32F403A/407 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 (CRM->intmap_bit.usbintmap) {
+ NVIC_DisableIRQ(USBFS_MAPH_IRQn);
+ NVIC_DisableIRQ(USBFS_MAPL_IRQn);
+ NVIC_DisableIRQ(USBFSWakeUp_IRQn);
+ } else
+ #endif
+ {
+ for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
+ NVIC_DisableIRQ(fsdev_irq[i]);
+ }
+ }
+}
+
+void dcd_disconnect(uint8_t rhport) {
+ (void) rhport;
+ /* disable usb phy */
+ FSDEV_REG->CNTR |= USB_CNTR_PDWN;
+ /* D+ 1.5k pull-up disable, USB->cfg_bit.puo = TRUE; */
+ *(uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1);
+}
+
+void dcd_connect(uint8_t rhport) {
+ (void) rhport;
+ /* enable usb phy */
+ FSDEV_REG->CNTR &= ~USB_CNTR_PDWN;
+ /* Dp 1.5k pull-up enable, USB->cfg_bit.puo = 0; */
+ *(uint32_t *)(FSDEV_REG_BASE+0x60) &= ~(1u<<1);
+}
+
+#endif
diff --git a/src/portable/synopsys/dwc2/dwc2_at32.h b/src/portable/synopsys/dwc2/dwc2_at32.h
new file mode 100644
index 000000000..37b6592c4
--- /dev/null
+++ b/src/portable/synopsys/dwc2/dwc2_at32.h
@@ -0,0 +1,121 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+
+#ifndef DWC2_AT32_H_
+#define DWC2_AT32_H_
+
+#define DWC2_EP_MAX TUP_DCD_ENDPOINT_MAX
+
+#if CFG_TUSB_MCU == OPT_MCU_AT32F415
+ #include <at32f415.h>
+ #define OTG1_FIFO_SIZE 1280
+ #define OTG1_IRQn OTGFS1_IRQn
+ #define DWC2_OTG1_REG_BASE 0x50000000UL
+#elif CFG_TUSB_MCU == OPT_MCU_AT32F435_437
+ #include <at32f435_437.h>
+ #define OTG1_FIFO_SIZE 1280
+ #define OTG2_FIFO_SIZE 1280
+ #define OTG1_IRQn OTGFS1_IRQn
+ #define OTG2_IRQn OTGFS2_IRQn
+ #define DWC2_OTG1_REG_BASE 0x50000000UL
+ #define DWC2_OTG2_REG_BASE 0x40040000UL
+#elif CFG_TUSB_MCU == OPT_MCU_AT32F423
+ #include <at32f423.h>
+ #define OTG1_FIFO_SIZE 1280
+ #define OTG1_IRQn OTGFS1_IRQn
+ #define DWC2_OTG1_REG_BASE 0x50000000UL
+#elif CFG_TUSB_MCU == OPT_MCU_AT32F402_405
+ #include <at32f402_405.h>
+ #define OTG1_FIFO_SIZE 1280
+ #define OTG2_FIFO_SIZE 4096
+ #define OTG1_IRQn OTGFS1_IRQn
+ #define OTG2_IRQn OTGHS_IRQn
+ #define DWC2_OTG1_REG_BASE 0x50000000UL
+ #define DWC2_OTG2_REG_BASE 0x40040000UL //OTGHS
+#elif CFG_TUSB_MCU == OPT_MCU_AT32F425
+ #include <at32f425.h>
+ #define OTG1_FIFO_SIZE 1280
+ #define OTG1_IRQn OTGFS1_IRQn
+ #define DWC2_OTG1_REG_BASE 0x50000000UL
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ static const dwc2_controller_t _dwc2_controller[] = {
+{.reg_base = DWC2_OTG1_REG_BASE, .irqnum = OTG1_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = OTG1_FIFO_SIZE},
+#if defined DWC2_OTG2_REG_BASE
+ {.reg_base = DWC2_OTG2_REG_BASE, .irqnum = OTG2_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = OTG2_FIFO_SIZE}
+#endif
+ };
+
+ TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_t role, bool enabled) {
+ (void) role;
+ const IRQn_Type irqn = (IRQn_Type) _dwc2_controller[rhport].irqnum;
+ if (enabled) {
+ NVIC_EnableIRQ(irqn);
+ } else {
+ NVIC_DisableIRQ(irqn);
+ }
+ }
+
+ TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum);
+ }
+
+ TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) {
+ NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum);
+ }
+
+ TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) {
+ // try to delay for 1 ms
+ uint32_t count = system_core_clock / 1000;
+ while (count--) __asm volatile("nop");
+ }
+
+ // MCU specific PHY init, called BEFORE core reset
+ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t *dwc2, uint8_t hs_phy_type) {
+ (void) dwc2;
+ // Enable on-chip HS PHY
+ if (hs_phy_type == GHWCFG2_HSPHY_UTMI || hs_phy_type == GHWCFG2_HSPHY_UTMI_ULPI) {
+ } else if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) {
+ }
+ }
+
+ // MCU specific PHY update, it is called AFTER init() and core reset
+ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t *dwc2, uint8_t hs_phy_type) {
+ (void) dwc2;
+ (void) hs_phy_type;
+
+ dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN | STM32_GCCFG_DCDEN | STM32_GCCFG_PDEN;
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DWC2_GD32_H_ */
diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c
index e1e7d5c1a..b001f343d 100644
--- a/src/portable/synopsys/dwc2/dwc2_common.c
+++ b/src/portable/synopsys/dwc2/dwc2_common.c
@@ -120,7 +120,9 @@ static void phy_hs_init(dwc2_regs_t* dwc2) {
// Set 16-bit interface if supported
if (ghwcfg4.phy_data_width) {
+ #if CFG_TUSB_MCU != OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit
gusbcfg |= GUSBCFG_PHYIF16; // 16 bit
+ #endif
} else {
gusbcfg &= ~GUSBCFG_PHYIF16; // 8 bit
}
@@ -139,7 +141,13 @@ static void phy_hs_init(dwc2_regs_t* dwc2) {
// - 9 if using 8-bit PHY interface
// - 5 if using 16-bit PHY interface
gusbcfg &= ~GUSBCFG_TRDT_Msk;
- gusbcfg |= (ghwcfg4.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos;
+
+#if CFG_TUSB_MCU == OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit
+ gusbcfg |= 9u << GUSBCFG_TRDT_Pos;
+#else
+ gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos;
+#endif
+
dwc2->gusbcfg = gusbcfg;
// MCU specific PHY update post reset
diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h
index 18b93894f..33219f786 100644
--- a/src/portable/synopsys/dwc2/dwc2_common.h
+++ b/src/portable/synopsys/dwc2/dwc2_common.h
@@ -49,6 +49,8 @@
#include "dwc2_efm32.h"
#elif TU_CHECK_MCU(OPT_MCU_XMC4000)
#include "dwc2_xmc.h"
+#elif defined(TUP_USBIP_DWC2_AT32)
+ #include "dwc2_at32.h"
#else
#error "Unsupported MCUs"
#endif
diff --git a/src/tusb_option.h b/src/tusb_option.h
index e6f5004b6..17bf556a3 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -201,6 +201,15 @@
#define OPT_MCU_MAX32650 2402 ///< ADI MAX32650/1/2
#define OPT_MCU_MAX78002 2403 ///< ADI MAX78002
+// ArteryTek
+#define OPT_MCU_AT32F403A_407 2500 ///< ArteryTek AT32F403A_AT32F407
+#define OPT_MCU_AT32F415 2501 ///< ArteryTek AT32F415
+#define OPT_MCU_AT32F435_437 2502 ///< ArteryTek AT32F435_AT32F437
+#define OPT_MCU_AT32F423 2503 ///< ArteryTek AT32F423
+#define OPT_MCU_AT32F402_405 2504 ///< ArteryTek AT32F402_405
+#define OPT_MCU_AT32F425 2505 ///< ArteryTek AT32F425
+#define OPT_MCU_AT32F413 2506 ///< ArteryTek AT32F413
+
// Check if configured MCU is one of listed
// Apply _TU_CHECK_MCU with || as separator to list of input
#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m)
diff --git a/tools/get_deps.py b/tools/get_deps.py
index 539ab52a9..ce838e427 100755
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -208,6 +208,27 @@ deps_optional = {
'hw/mcu/wch/ch32f20x': ['https://github.com/openwch/ch32f20x.git',
'77c4095087e5ed2c548ec9058e655d0b8757663b',
'ch32f20x'],
+ 'hw/mcu/artery/at32f403a_407': ['https://github.com/ArteryTek/AT32F403A_407_Firmware_Library.git',
+ 'f2cb360c3d28fada76b374308b8c4c61d37a090b',
+ 'at32f403a_407'],
+ 'hw/mcu/artery/at32f415': ['https://github.com/ArteryTek/AT32F415_Firmware_Library.git',
+ '716f545aa1290ff144ccf023a8e797b951e1bc8e',
+ 'at32f415'],
+ 'hw/mcu/artery/at32f435_437': ['https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git',
+ '25439cc6650a8ae0345934e8707a5f38c7ae41f8',
+ 'at32f435_437'],
+ 'hw/mcu/artery/at32f423': ['https://github.com/ArteryTek/AT32F423_Firmware_Library.git',
+ '2afa7f12852e57a9e8aab3a892c641e1a8635a18',
+ 'at32f423'],
+ 'hw/mcu/artery/at32f402_405': ['https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git',
+ '4424515c2663e82438654e0947695295df2abdfe',
+ 'at32f402_405'],
+ 'hw/mcu/artery/at32f425': ['https://github.com/ArteryTek/AT32F425_Firmware_Library.git',
+ '620233e1357d5c1b7e2bde6b9dd5196822b91817',
+ 'at32f425'],
+ 'hw/mcu/artery/at32f413': ['https://github.com/ArteryTek/AT32F413_Firmware_Library.git',
+ 'f6fe62dfec9fd40c5b63d92fc5ef2c2b5e77a450',
+ 'at32f413'],
'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git',
'2b7495b8535bdcb306dac29b9ded4cfb679d7e5c',
'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x '