diff --git a/boards/bitcraze-crazyflie21-main/Kconfig b/boards/bitcraze-crazyflie21-main/Kconfig new file mode 100644 index 0000000000..ea46117a0f --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/Kconfig @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2025 TU Dresden +# SPDX-License-Identifier: LGPL-2.1-only + +config BOARD + default "bitcraze-crazyflie21-main" if BOARD_BITCRAZE_CRAZYFLIE21_MAIN + +config BOARD_BITCRAZE_CRAZYFLIE21_MAIN + bool + default y + select CPU_MODEL_STM32F405RG + + # Clock configuration + select BOARD_HAS_HSE + select BOARD_HAS_LSE + +config CLOCK_HSE + default 8000000 + +config CLOCK_PLL_M + default 8 + +config CLOCK_PLL_N + default 336 if USEMODULE_PERIPH_USBDEV_CLK + default 360 + +source "$(RIOTBOARD)/common/stm32/Kconfig" diff --git a/boards/bitcraze-crazyflie21-main/Makefile b/boards/bitcraze-crazyflie21-main/Makefile new file mode 100644 index 0000000000..f8fcbb53a0 --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/bitcraze-crazyflie21-main/Makefile.dep b/boards/bitcraze-crazyflie21-main/Makefile.dep new file mode 100644 index 0000000000..195c236d4b --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/Makefile.dep @@ -0,0 +1,5 @@ +ifneq (,$(filter saul_default,$(USEMODULE))) + USEMODULE += saul_gpio +endif + +include $(RIOTBOARD)/common/makefiles/stdio_cdc_acm.dep.mk \ No newline at end of file diff --git a/boards/bitcraze-crazyflie21-main/Makefile.features b/boards/bitcraze-crazyflie21-main/Makefile.features new file mode 100644 index 0000000000..f29359e6d9 --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/Makefile.features @@ -0,0 +1,17 @@ +CPU = stm32 +CPU_MODEL = stm32f405rg + +CFLAGS += -DCONFIG_MOTOR_DRIVER_MAX=3 + +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_adc +FEATURES_PROVIDED += periph_dma +FEATURES_PROVIDED += periph_i2c +FEATURES_PROVIDED += periph_pwm +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_usbdev + +FEATURES_PROVIDED += highlevel_stdio +FEATURES_PROVIDED += motor_driver diff --git a/boards/bitcraze-crazyflie21-main/Makefile.include b/boards/bitcraze-crazyflie21-main/Makefile.include new file mode 100644 index 0000000000..cce686e8f8 --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/Makefile.include @@ -0,0 +1,14 @@ +# include shared STM32 headers +INCLUDES += -I$(RIOTBOARD)/common/stm32/include + +PORT_LINUX ?= /dev/ttyACM0 + +ROM_OFFSET ?= 0x4000 +TERM_DELAY ?= 2 + +PROGRAMMER ?= dfu-util +PROGRAMMERS_SUPPORTED += dfu-util +DFU_USB_ID ?= 0483:df11 +DFU_USE_DFUSE ?= 1 + +include $(RIOTMAKE)/tools/usb_board_reset.mk \ No newline at end of file diff --git a/boards/bitcraze-crazyflie21-main/doc.md b/boards/bitcraze-crazyflie21-main/doc.md new file mode 100644 index 0000000000..dd3c3ce78f --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/doc.md @@ -0,0 +1,72 @@ +@defgroup boards_bitcraze_crazyflie21_main bitcraze Crazyflie 2.1 Main Application MCU +@ingroup boards +@brief Support for the main application MCU of the bitcraze Crazyflie 2.1 board. + +### General information + +The Crazyflie 2.1 is an open source flying development platform produced by bitcraze. +It has two onboard microcontrollers, an nRF51822 used for radio communication and power management and +an STM32F405 (this board definition) used for running the main application. + +### Pinout + +The pinout is part of the [Board Datasheet][board-datasheet]. +The [Board Schematics][board-schematics] show which pins are connected to the motors, LEDs, etc. + +[board-datasheet]: https://www.bitcraze.io/documentation/hardware/crazyflie_2_1/crazyflie_2_1-datasheet.pdf +[board-schematics]: https://www.bitcraze.io/documentation/hardware/crazyflie_2_1/crazyflie_2.1_schematics_rev.b.pdf + +### MCU + +| MCU | STM32F405RG | +|:---------------------|:--------------------------------------------| +| Family | ARM Cortex-M4 | +| Vendor | ST Microelectronics | +| Package | LQFP64 | +| RAM | 192 KiB (128 KiB RAM + 64 KiB CCMRAM) | +| Flash | 1024 KiB | +| Frequency | up to 168 MHz (running at 168 MHz) | +| FPU | yes | +| Timers | 14 (12× 16bit, 2× 32bit [TIM2 + TIM5]) | +| ADCs | 3× 16 channel 6 to 12-bit | +| UARTs | 6 | +| SPIs | 3 | +| I2Cs | 3 | +| Vcc | 2.0 V - 3.6 V | +| MCU Datasheet | [MCU Datasheet][mcu-datasheet] | +| MCU Reference Manual | [MCU Reference Manual][mcu-ref] | + +[mcu-datasheet]: https://www.st.com/resource/en/datasheet/stm32f405rg.pdf +[mcu-ref]: https://www.st.com/resource/en/reference_manual/dm00031020-stm32f405-415-stm32f407-417-stm32f427-437-and-stm32f429-439-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf + +### Flash the board +Prerequisites: +- the Crazyflie NRF firmware runs on the NRF [instructions](https://www.bitcraze.io/documentation/repository/crazyflie2-nrf-firmware/master/build/build/) +- the original Crazyflie bootloader runs on the STM32 [instructions](https://www.bitcraze.io/documentation/repository/crazyflie-firmware/master/development/dfu/#bootloader-recovery) +- `dfu-util` is installed +- the Crazyflie's battery is disconnected + +To flash the board: +- navigate to the folder of the app you want to flash +- Hold down the power button on the Crazyflie +- connect via usb to your computer +- keep holding down the button for four seconds until the blink rate changes (the mcu is now in DFU mode) +- flash the board by running `BOARD=bitcraze-crazyflie21-main make all flash` + +### STDIO +By default, STDIO is implemented via the native USB interface. +In order to use STDIO over UART connect your UART adapter as follows: + +| PIN board | UART adapter | +|:----------|:-------------| +| PC10 (TX) | RX | +| PC11 (RX) | TX | +| GND | GND | + +Now flash the board with stdio over UART: +``` +USEMODULE=stdio_uart BOARD=bitcraze-crazyflie21-main make all flash +``` + +### Known Issues + - `timer_set()`: the callback is never called for timeouts of only one tick. diff --git a/boards/bitcraze-crazyflie21-main/include/board.h b/boards/bitcraze-crazyflie21-main/include/board.h new file mode 100644 index 0000000000..5ae75a403e --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/include/board.h @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2025 TU Dresden + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup boards_bitcraze_crazyflie21_main + * @{ + * + * @file + * @brief Board specific definitions for the Crazyflie 2.1 main application MCU + * + * @author Leonard Herbst + */ + +#include "cpu.h" +#include "motor_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Macros for controlling the on-board LEDs. + * @{ + */ +#define LED0_IS_INVERTED 1 +#define LED0_PIN_NUM 3 /* LED top right red */ +#define LED0_PORT GPIO_PORT_C +#define LED0_PORT_NUM PORT_C + +#define LED1_IS_INVERTED 1 +#define LED1_PIN_NUM 2 /* LED top right green */ +#define LED1_PORT GPIO_PORT_C +#define LED1_PORT_NUM PORT_C + +#define LED2_PIN_NUM 2 /* LED bottom left blue */ +#define LED2_PORT GPIO_PORT_D +#define LED2_PORT_NUM PORT_D + +#define LED3_IS_INVERTED 1 +#define LED3_PIN_NUM 0 /* LED top left red*/ +#define LED3_PORT GPIO_PORT_C +#define LED3_PORT_NUM PORT_C + +#define LED4_IS_INVERTED 1 +#define LED4_PIN_NUM 1 /* LED top left green */ +#define LED4_PORT GPIO_PORT_C +#define LED4_PORT_NUM PORT_C +/** @} */ + +/** + * @name Describe DC motors with PWM channel and GPIOs + * @{ + */ +/** Motor driver config. Two driver with three and one motor attached respectively */ +static const motor_driver_config_t motor_driver_config[] = { + { + .pwm_dev = 1, + .mode = MOTOR_DRIVER_1_DIR, + .mode_brake = MOTOR_BRAKE_HIGH, + .pwm_mode = PWM_LEFT, + .pwm_frequency = 20000U, + .pwm_resolution = 4200U, + .nb_motors = 3, + .motors = { + { + .pwm_channel = 1, + .gpio_enable = 0, + .gpio_dir0 = 0, + .gpio_dir1_or_brake = 0, + .gpio_dir_reverse = 0, + .gpio_enable_invert = 0, + .gpio_brake_invert = 0, + }, + { + .pwm_channel = 3, + .gpio_enable = 0, + .gpio_dir0 = 0, + .gpio_dir1_or_brake = 0, + .gpio_dir_reverse = 0, + .gpio_enable_invert = 0, + .gpio_brake_invert = 0, + }, + { + .pwm_channel = 0, + .gpio_enable = 0, + .gpio_dir0 = 0, + .gpio_dir1_or_brake = 0, + .gpio_dir_reverse = 0, + .gpio_enable_invert = 0, + .gpio_brake_invert = 0, + }, + }, + .cb = NULL, + }, + { + .pwm_dev = 2, + .mode = MOTOR_DRIVER_1_DIR, + .mode_brake = MOTOR_BRAKE_HIGH, + .pwm_mode = PWM_LEFT, + .pwm_frequency = 20000U, + .pwm_resolution = 4200U, + .nb_motors = 1, + .motors = { + { + .pwm_channel = 0, + .gpio_enable = 0, + .gpio_dir0 = 0, + .gpio_dir1_or_brake = 0, + .gpio_dir_reverse = 0, + .gpio_enable_invert = 0, + .gpio_brake_invert = 0, + }, + }, + .cb = NULL, + } +}; + +/** Number of motor drivers */ +#define MOTOR_DRIVER_NUMOF ARRAY_SIZE(motor_driver_config) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#include "stm32_leds.h" +/** @} */ diff --git a/boards/bitcraze-crazyflie21-main/include/gpio_params.h b/boards/bitcraze-crazyflie21-main/include/gpio_params.h new file mode 100644 index 0000000000..a1e485a2dd --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/include/gpio_params.h @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2025 TU Dresden + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup boards_bitcraze_crazyflie21_main + * @{ + * + * @file + * @brief Board specific definitions for the Crazyflie 2.1 main application MCU + * + * @author Leonard Herbst + */ + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief GPIO pin configuration + */ +static const saul_gpio_params_t saul_gpio_params[] = +{ + { + .name = "red LED top right", + .pin = LED0_PIN, + .mode = GPIO_OUT + }, + { + .name = "green LED top left", + .pin = LED1_PIN, + .mode = GPIO_OUT + }, + { + .name = "blue LED bottom left", + .pin = LED2_PIN, + .mode = GPIO_OUT + }, + { + .name = "red LED top left", + .pin = LED3_PIN, + .mode = GPIO_OUT + }, + { + .name = "green LED top left", + .pin = LED4_PIN, + .mode = GPIO_OUT + }, +}; +/** @} */ + +#ifdef __cplusplus +} +#endif diff --git a/boards/bitcraze-crazyflie21-main/include/periph_conf.h b/boards/bitcraze-crazyflie21-main/include/periph_conf.h new file mode 100644 index 0000000000..8bf522a10b --- /dev/null +++ b/boards/bitcraze-crazyflie21-main/include/periph_conf.h @@ -0,0 +1,241 @@ +/* + * SPDX-FileCopyrightText: 2025 TU Dresden + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup boards_bitcraze_crazyflie21_main + * @{ + * + * @file + * @brief Configuration of CPU peripherals for Crazyflie 2.1 main application MCU + * + * @author Leonard Herbst + */ + +/* This board provides an LSE */ +#ifndef CONFIG_BOARD_HAS_LSE +# define CONFIG_BOARD_HAS_LSE 1 +#endif + +/* This board provides an HSE */ +#ifndef CONFIG_BOARD_HAS_HSE +# define CONFIG_BOARD_HAS_HSE 1 +#endif + +/* The HSE provides a 8MHz clock */ +#ifndef CONFIG_CLOCK_HSE +# define CONFIG_CLOCK_HSE MHZ(8) +#endif + +#include "periph_cpu.h" +#include "clk_conf.h" +#include "cfg_usb_otg_fs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name DMA streams configuration + * @{ + */ +static const dma_conf_t dma_config[] = { + { .stream = 11 }, /* DMA2 Stream 3 - SPI1_TX */ + { .stream = 10 }, /* DMA2 Stream 2 - SPI1_RX */ + { .stream = 3 }, /* DMA1 Stream 3 - USART3_TX */ + { .stream = 6 }, /* DMA1 Stream 6 - USART2_TX */ +}; + +#define DMA_0_ISR isr_dma2_stream3 +#define DMA_1_ISR isr_dma2_stream2 +#define DMA_2_ISR isr_dma1_stream3 +#define DMA_3_ISR isr_dma1_stream6 + +#define DMA_NUMOF ARRAY_SIZE(dma_config) +/** @} */ + +/** + * @name Timer configuration + * + * Avoiding TIM2 and TIM4 because they are used for pwm + * + * @{ + */ +static const timer_conf_t timer_config[] = { + { + .dev = TIM5, + .max = 0xffffffff, + .rcc_mask = RCC_APB1ENR_TIM5EN, + .bus = APB1, + .irqn = TIM5_IRQn, + } +}; + +#define TIMER_0_ISR isr_tim5 + +#define TIMER_NUMOF ARRAY_SIZE(timer_config) +/** @} */ + +/** + * @name UART configuration + * @{ + */ +static const uart_conf_t uart_config[] = { + { + .dev = USART3, + .rcc_mask = RCC_APB1ENR_USART3EN, + .rx_pin = GPIO_PIN(PORT_C, 11), + .tx_pin = GPIO_PIN(PORT_C, 10), + .rx_af = GPIO_AF7, + .tx_af = GPIO_AF7, + .bus = APB1, + .irqn = USART3_IRQn, +#ifdef MODULE_PERIPH_DMA + .dma = 2, + .dma_chan = 4 +#endif + }, + { + .dev = USART2, + .rcc_mask = RCC_APB1ENR_USART2EN, + .rx_pin = GPIO_PIN(PORT_A, 3), + .tx_pin = GPIO_PIN(PORT_A, 2), + .rx_af = GPIO_AF7, + .tx_af = GPIO_AF7, + .bus = APB1, + .irqn = USART2_IRQn, +#ifdef MODULE_PERIPH_DMA + .dma = 3, + .dma_chan = 4 +#endif + } +}; + +#define UART_0_ISR (isr_usart3) +#define UART_1_ISR (isr_usart2) + +#define UART_NUMOF ARRAY_SIZE(uart_config) +/** @} */ + +/** + * @name ADC configuration + * @{ + */ +static const adc_conf_t adc_config[] = { + { .pin = GPIO_PIN(PORT_A, 2), .dev = 0, .chan = 2 }, + { .pin = GPIO_PIN(PORT_A, 3), .dev = 0, .chan = 3 }, + { .pin = GPIO_PIN(PORT_A, 5), .dev = 1, .chan = 5 }, + { .pin = GPIO_PIN(PORT_A, 6), .dev = 1, .chan = 6 }, + { .pin = GPIO_PIN(PORT_A, 7), .dev = 1, .chan = 7 }, + { .pin = GPIO_UNDEF, .dev = 0, .chan = 0}, /* VBAT */ +}; + +/* The radio MCU takes care of power management -> adc line without proper pin. */ +#define VBAT_ADC ADC_LINE(5) /**< VBAT ADC line */ +#define ADC_NUMOF ARRAY_SIZE(adc_config) +/** @} */ + +/** + * @name PWM configuration + * @{ + */ +static const pwm_conf_t pwm_config[] = { + { + .dev = TIM9, + .rcc_mask = RCC_APB2ENR_TIM9EN, + .chan = { + { .pin = GPIO_PIN(PORT_A, 2), .cc_chan = 0 }, + { .pin = GPIO_PIN(PORT_A, 3), .cc_chan = 1 }, + { .pin = GPIO_UNDEF, .cc_chan = 0 }, + { .pin = GPIO_UNDEF, .cc_chan = 0 } }, + .af = GPIO_AF3, + .bus = APB2, + }, + { + .dev = TIM2, + .rcc_mask = RCC_APB1ENR_TIM2EN, + .chan = { + { .pin = GPIO_PIN(PORT_A, 15), .cc_chan = 0 }, /* Motor 3 */ + { .pin = GPIO_PIN(PORT_A, 1), .cc_chan = 1 }, /* Motor 1 */ + { .pin = GPIO_PIN(PORT_A, 2), .cc_chan = 2 }, /* broken out */ + { .pin = GPIO_PIN(PORT_B, 11), .cc_chan = 3 } /* Motor 2 */ }, + .af = GPIO_AF1, + .bus = APB1 + }, + { + .dev = TIM4, + .rcc_mask = RCC_APB1ENR_TIM4EN, + .chan = { + { .pin = GPIO_PIN(PORT_B, 9), .cc_chan = 3 }, /* Motor 4 */ + { .pin = GPIO_UNDEF, .cc_chan = 0 }, + { .pin = GPIO_UNDEF, .cc_chan = 0 }, + { .pin = GPIO_UNDEF, .cc_chan = 0 } }, + .af = GPIO_AF2, + .bus = APB1 + } +}; + +#define PWM_NUMOF ARRAY_SIZE(pwm_config) +/** @} */ + +/** + * @name SPI configuration + * @{ + */ +static const spi_conf_t spi_config[] = { + { + .dev = SPI1, + .mosi_pin = GPIO_PIN(PORT_A, 7), + .miso_pin = GPIO_PIN(PORT_A, 6), + .sclk_pin = GPIO_PIN(PORT_A, 5), + .cs_pin = GPIO_UNDEF, + .mosi_af = GPIO_AF5, + .miso_af = GPIO_AF5, + .sclk_af = GPIO_AF5, + .cs_af = GPIO_AF5, + .rccmask = RCC_APB2ENR_SPI1EN, + .apbbus = APB2, +#ifdef MODULE_PERIPH_DMA + .tx_dma = 0, + .tx_dma_chan = 3, + .rx_dma = 1, + .rx_dma_chan = 3, +#endif + } +}; + +#define SPI_NUMOF ARRAY_SIZE(spi_config) +/** @} */ + +/** + * @name I2C configuration + * @{ + */ +static const i2c_conf_t i2c_config[] = { + { + .dev = I2C1, + .speed = I2C_SPEED_NORMAL, + .scl_pin = GPIO_PIN(PORT_B, 6), + .sda_pin = GPIO_PIN(PORT_B, 7), + .scl_af = GPIO_AF4, + .sda_af = GPIO_AF4, + .bus = APB1, + .rcc_mask = RCC_APB1ENR_I2C1EN, + .clk = CLOCK_APB1, + .irqn = I2C1_EV_IRQn + } +}; + +#define I2C_0_ISR isr_i2c1_ev + +#define I2C_NUMOF ARRAY_SIZE(i2c_config) +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/tests/sys/usbus_cdc_ecm/Makefile b/tests/sys/usbus_cdc_ecm/Makefile index d5ccfa7354..78df41cbbd 100644 --- a/tests/sys/usbus_cdc_ecm/Makefile +++ b/tests/sys/usbus_cdc_ecm/Makefile @@ -11,6 +11,7 @@ USEMODULE += ps # Boards that don't have enough endpoints to use CDC ACM together with CDC ECM ifeq (,$(filter stdio_%,$(filter-out stdio_cdc_acm,$(USEMODULE)))) BOARD_BLACKLIST += \ + bitcraze-crazyflie21-main \ sipeed-longan-nano \ sipeed-longan-nano-tft \ seeedstudio-gd32 \ diff --git a/tests/sys/xtimer_now32_overflow/Makefile b/tests/sys/xtimer_now32_overflow/Makefile index 88820bb2b2..8b57ab18a4 100644 --- a/tests/sys/xtimer_now32_overflow/Makefile +++ b/tests/sys/xtimer_now32_overflow/Makefile @@ -8,6 +8,7 @@ DISABLE_MODULE += auto_init_xtimer # Boards that can't run only on xtimer or that always select ztimer BOARD_BLACKLIST += \ adafruit-feather-nrf52840-express \ + bitcraze-crazyflie21-main \ esp32s2-wemos-mini \ hamilton \ mulle \