Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,96 @@ GenC0.menu.upload_method.OpenOCDDapLink.upload.tool=openocd_upload
GenC0.menu.upload_method.OpenOCDDapLink.debug.server.openocd.scripts.0=interface/cmsis-dap.cfg
GenC0.menu.upload_method.OpenOCDDapLink.debug.server.openocd.scripts.1={runtime.platform.path}/debugger/select_swd.cfg

################################################################################
# Seeed XIAO STM32C5

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be better to add a more generic menu name, like Seeed Studio or something like that and select the board in the pnum menu (default if first or only one). I guess that some script will fail if no pnum item.

Moreover you add only one menu when you select it with only one option for the USB.

No Serial support?
What about optimization? debug information? C Runtime Library?

XIAO_STM32C5.name=Seeed Studio

XIAO_STM32C5.build.core=arduino
XIAO_STM32C5.build.family=SEEED_STUDIO
XIAO_STM32C5.build.board=XIAO_STM32C5
XIAO_STM32C5.build.variant=STM32C5xx/C593C(E-G)(T-U)_C5A3CG(T-U)
XIAO_STM32C5.build.variant_h=variant_XIAO_STM32C5.h
XIAO_STM32C5.build.ldscript=ldscript_XIAO_STM32C5.ld
XIAO_STM32C5.build.st_extra_flags=-D{build.product_line} -DHSE_VALUE=48000000U -DUSBD_SELF_POWERED=1 -DUSBD_MAX_POWER=50 {build.enable_usb} {build.xSerial}
XIAO_STM32C5.build.mcu=cortex-m33
XIAO_STM32C5.build.fpu=-mfpu=fpv5-sp-d16
XIAO_STM32C5.build.float-abi=-mfloat-abi=hard
XIAO_STM32C5.build.series=STM32C5xx
XIAO_STM32C5.build.product_line=STM32C5A3xx
XIAO_STM32C5.build.hal=-DUSE_HALV2_DRIVER
XIAO_STM32C5.build.flash_offset=0x8000
XIAO_STM32C5.upload.maximum_size=1015808
XIAO_STM32C5.upload.maximum_data_size=262144
XIAO_STM32C5.upload.tool=uf2upload
XIAO_STM32C5.upload.protocol=serial
XIAO_STM32C5.upload.uf2.volume=XIAOC5BOOT
XIAO_STM32C5.upload.uf2.address=0x08008000
XIAO_STM32C5.upload.uf2.family=0x00C5C5C5
XIAO_STM32C5.upload.uf2.timeout=10000
XIAO_STM32C5.debug.svd_file={runtime.tools.STM32_SVD.path}/svd/STM32C5xx/STM32C5A3.svd
XIAO_STM32C5.vid.0=0x2886
XIAO_STM32C5.pid.0=0x80C5

# Seeed XIAO STM32C5
XIAO_STM32C5.menu.pnum.XIAO_STM32C5=Seeed XIAO STM32C5
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.build.board=XIAO_STM32C5
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.build.product_line=STM32C5A3xx
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.build.variant=STM32C5xx/C593C(E-G)(T-U)_C5A3CG(T-U)
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.build.variant_h=variant_XIAO_STM32C5.h
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.build.ldscript=ldscript_XIAO_STM32C5.ld
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.upload.maximum_size=1015808
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.upload.maximum_data_size=262144
XIAO_STM32C5.menu.pnum.XIAO_STM32C5.debug.svd_file={runtime.tools.STM32_SVD.path}/svd/STM32C5xx/STM32C5A3.svd

# U(S)ART support
XIAO_STM32C5.menu.xserial.generic=Enabled (generic 'Serial')
XIAO_STM32C5.menu.xserial.none=Enabled (no generic 'Serial')
XIAO_STM32C5.menu.xserial.none.build.xSerial=-DHAL_UART_MODULE_ENABLED -DHWSERIAL_NONE
XIAO_STM32C5.menu.xserial.disabled=Disabled (no Serial support)
XIAO_STM32C5.menu.xserial.disabled.build.xSerial=

# USB connectivity
XIAO_STM32C5.menu.usb.none=None
XIAO_STM32C5.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
XIAO_STM32C5.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
XIAO_STM32C5.menu.usb.CDC=CDC (no generic 'Serial')
XIAO_STM32C5.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB

# Optimize
XIAO_STM32C5.menu.opt.osstd=Smallest (-Os default)
XIAO_STM32C5.menu.opt.oslto=Smallest (-Os) with LTO
XIAO_STM32C5.menu.opt.oslto.build.flags.optimize=-Os -flto
XIAO_STM32C5.menu.opt.o1std=Fast (-O1)
XIAO_STM32C5.menu.opt.o1std.build.flags.optimize=-O1
XIAO_STM32C5.menu.opt.o1lto=Fast (-O1) with LTO
XIAO_STM32C5.menu.opt.o1lto.build.flags.optimize=-O1 -flto
XIAO_STM32C5.menu.opt.o2std=Faster (-O2)
XIAO_STM32C5.menu.opt.o2std.build.flags.optimize=-O2
XIAO_STM32C5.menu.opt.o2lto=Faster (-O2) with LTO
XIAO_STM32C5.menu.opt.o2lto.build.flags.optimize=-O2 -flto
XIAO_STM32C5.menu.opt.o3std=Fastest (-O3)
XIAO_STM32C5.menu.opt.o3std.build.flags.optimize=-O3
XIAO_STM32C5.menu.opt.o3lto=Fastest (-O3) with LTO
XIAO_STM32C5.menu.opt.o3lto.build.flags.optimize=-O3 -flto
XIAO_STM32C5.menu.opt.ogstd=Debug (-Og)
XIAO_STM32C5.menu.opt.ogstd.build.flags.optimize=-Og

# Debug information
XIAO_STM32C5.menu.dbg.none=None
XIAO_STM32C5.menu.dbg.enable=Symbols Enabled (-g)
XIAO_STM32C5.menu.dbg.enable.build.flags.debug=-g

# C Runtime Library
XIAO_STM32C5.menu.rtlib.nano=Newlib Nano (default)
XIAO_STM32C5.menu.rtlib.nanofp=Newlib Nano + Float Printf
XIAO_STM32C5.menu.rtlib.nanofp.build.flags.ldspecs=--specs=nano.specs -u _printf_float
XIAO_STM32C5.menu.rtlib.nanofs=Newlib Nano + Float Scanf
XIAO_STM32C5.menu.rtlib.nanofs.build.flags.ldspecs=--specs=nano.specs -u _scanf_float
XIAO_STM32C5.menu.rtlib.nanofps=Newlib Nano + Float Printf/Scanf
XIAO_STM32C5.menu.rtlib.nanofps.build.flags.ldspecs=--specs=nano.specs -u _printf_float -u _scanf_float
XIAO_STM32C5.menu.rtlib.full=Newlib Standard
XIAO_STM32C5.menu.rtlib.full.build.flags.ldspecs=

################################################################################
# Generic C5
GenC5.name=Generic STM32C5 series
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
* Copyright (c) 2026, Seeed Technology Co., Ltd.
* SPDX-License-Identifier: BSD-3-Clause
*
* The application starts after the 32 KiB TinyUF2 bootloader. Memory sizes are
* supplied by boards.txt through LD_MAX_SIZE and LD_MAX_DATA_SIZE.
*/
ENTRY(Reset_Handler)

HEAP_SIZE = 0x2000;
STACK_SIZE = 0x2000;

MEMORY
{
ROM (rx) : org = 0x08000000 + LD_FLASH_OFFSET, len = LD_MAX_SIZE - LD_FLASH_OFFSET
/* TinyUF2 uses the final SRAM word for the 1200-bps reset handoff. */
RAM (xrw) : org = 0x20000000, len = LD_MAX_DATA_SIZE - 4
}

SECTIONS
{
.vectors :
{
. = ALIGN(8);
KEEP(*(.vectors));
. = ALIGN(8);
} > ROM

.text :
{
. = ALIGN(8);
*(.text);
*(.text*);
*(.glue_7);
*(.glue_7t);
*(.eh_frame);
KEEP(*(.init));
KEEP(*(.fini));
. = ALIGN(8);
_etext = .;
} > ROM

.rodata :
{
. = ALIGN(8);
*(.rodata);
*(.rodata*);
. = ALIGN(8);
} > ROM

.ARM.extab (READONLY) :
{
. = ALIGN(8);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(8);
} > ROM

.ARM (READONLY) :
{
. = ALIGN(8);
__exidx_start = .;
*(.ARM.exidx*);
__exidx_end = .;
. = ALIGN(8);
} > ROM

.preinit_array (READONLY) :
{
. = ALIGN(8);
PROVIDE_HIDDEN(__preinit_array_start = .);
KEEP(*(.preinit_array*));
PROVIDE_HIDDEN(__preinit_array_end = .);
. = ALIGN(8);
} > ROM

.init_array (READONLY) :
{
. = ALIGN(8);
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(SORT(.init_array.*)));
KEEP(*(.init_array*));
PROVIDE_HIDDEN(__init_array_end = .);
. = ALIGN(8);
} > ROM

.fini_array (READONLY) :
{
. = ALIGN(8);
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)));
KEEP(*(.fini_array*));
PROVIDE_HIDDEN(__fini_array_end = .);
. = ALIGN(8);
} > ROM

.copy.table (READONLY) :
{
. = ALIGN(8);
__copy_table_start__ = .;
LONG(LOADADDR(.data));
LONG(ADDR(.data));
LONG(SIZEOF(.data) / 4);
__copy_table_end__ = .;
} > ROM

.zero.table (READONLY) :
{
. = ALIGN(8);
__zero_table_start__ = .;
LONG(ADDR(.bss));
LONG(SIZEOF(.bss) / 4);
__zero_table_end__ = .;
} > ROM

.data :
{
. = ALIGN(8);
_sidata = LOADADDR(.data);
__data_start__ = .;
_sdata = .;
*(.data);
*(.data*);
. = ALIGN(8);
_edata = .;
} > RAM AT> ROM

.bss :
{
. = ALIGN(8);
_sbss = .;
__bss_start__ = _sbss;
*(.bss);
*(.bss*);
*(COMMON);
. = ALIGN(8);
_ebss = .;
__bss_end__ = _ebss;
} > RAM

.heap (NOLOAD) :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
_heap_start = .;
. += HEAP_SIZE;
. = ALIGN(8);
_heap_end = .;
__HeapLimit = .;
} > RAM

.stack (NOLOAD) :
{
. = ALIGN(8);
__StackLimit = .;
. += STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
_estack = .;
__stack = .;
} > RAM

/DISCARD/ :
{
libc.a(*);
libm.a(*);
libgcc.a(*);
}

.ARM.attributes 0 :
{
*(.ARM.attributes)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2026, Seeed Technology Co., Ltd.
* SPDX-License-Identifier: BSD-3-Clause
*/
#if defined(ARDUINO_XIAO_STM32C5)

#include "pins_arduino.h"

const PinName digitalPin[] = {
PA_0, // D0 / A0
PA_1, // D1 / A1
PA_2, // D2 / A2
PA_3, // D3 / A3
PB_7, // D4 / I2C1_SDA
PB_6, // D5 / I2C1_SCL
PA_9, // D6 / USART1_TX
PA_10, // D7 / USART1_RX
PE_2, // D8 / SPI3_SCK
PB_0, // D9 / SPI3_MISO
PB_15, // D10 / SPI3_MOSI
PB_8, // D11 / FDCAN1_RX
PB_9, // D12 / FDCAN1_TX
PB_5, // D13 / FDCAN2_RX
PB_13, // D14 / FDCAN2_TX
PB_14, // D15 / CAN_STB
PB_12, // Board LED, active low
PB_3, // Onboard IMU / I2C2_SCL
PB_4, // Onboard IMU / I2C2_SDA
PC_13, // Onboard IMU / INT1
PA_8, // Onboard IMU heater / TIM1_CH1
PH_2 // BOOT0 / user button (active low)
};

const pin_size_t analogInputPin[] = {
D0,
D1,
D2,
D3
};

/* TinyUF2 C5 (d52adcf) reserves the last SRAM word for the double-tap
* handoff. The matching application linker script excludes this word from
* the stack/heap RAM region. */
static constexpr uintptr_t TINYUF2_HANDOFF_ADDRESS = 0x2003FFFCUL;
static constexpr uint32_t TINYUF2_ENTER_DFU_MAGIC = 0xF01669EFUL;

extern "C" void CDC_LineCodingChanged(uint32_t bitrate)
{
if (bitrate == 1200U) {
*reinterpret_cast<volatile uint32_t *>(TINYUF2_HANDOFF_ADDRESS) = TINYUF2_ENTER_DFU_MAGIC;
__DSB();
__ISB();
NVIC_SystemReset();
while (true) {
}
}
}

extern "C" void SystemClock_Config(void)
{
if (HAL_RCC_HSE_Enable(HAL_RCC_HSE_ON) != HAL_OK) {
Error_Handler();
}

hal_rcc_psi_config_t psi_config;
psi_config.psi_source = HAL_RCC_PSI_SRC_HSE;
psi_config.psi_ref = HAL_RCC_PSI_REF_48MHZ;
psi_config.psi_out = HAL_RCC_PSI_OUT_144MHZ;
if (HAL_RCC_PSI_SetConfig(&psi_config) != HAL_OK) {
Error_Handler();
}
if (HAL_RCC_PSIS_Enable() != HAL_OK) {
Error_Handler();
}

hal_rcc_bus_clk_config_t bus_config;
bus_config.hclk_prescaler = HAL_RCC_HCLK_PRESCALER1;
bus_config.pclk1_prescaler = HAL_RCC_PCLK_PRESCALER2;
bus_config.pclk2_prescaler = HAL_RCC_PCLK_PRESCALER2;
bus_config.pclk3_prescaler = HAL_RCC_PCLK_PRESCALER2;
if (HAL_RCC_SetBusClockConfig(&bus_config) != HAL_OK) {
Error_Handler();
}

HAL_FLASH_ITF_SetLatency(HAL_FLASH, HAL_FLASH_ITF_LATENCY_4);
if (HAL_RCC_SetSYSCLKSource(HAL_RCC_SYSCLK_SRC_PSIS) != HAL_OK) {
Error_Handler();
}
HAL_FLASH_ITF_SetProgrammingDelay(HAL_FLASH, HAL_FLASH_ITF_PROGRAM_DELAY_2);
if (HAL_RCC_CK48_SetKernelClkSource(HAL_RCC_CK48_CLK_SRC_HSE) != HAL_OK) {
Error_Handler();
}
if (HAL_UpdateCoreClock() != HAL_OK) {
Error_Handler();
}
}

void initVariant(void)
{
/* CAN_STB is active high. Keep the onboard transceiver out of standby. */
pinMode(D15, OUTPUT);
digitalWrite(D15, LOW);
}

#endif /* ARDUINO_XIAO_STM32C5 */
Loading