From 009bb06f3830cd5ed5040fdd69c7e3633b0f0c1e Mon Sep 17 00:00:00 2001 From: Thomas Sommer Date: Thu, 19 Aug 2021 08:17:49 +0200 Subject: [PATCH] [board] Add DISCO-F411VE --- README.md | 29 ++-- examples/generic/usb/project.xml | 1 + src/modm/board/disco_f411ve/board.hpp | 231 ++++++++++++++++++++++++++ src/modm/board/disco_f411ve/board.xml | 14 ++ src/modm/board/disco_f411ve/module.lb | 46 +++++ 5 files changed, 307 insertions(+), 14 deletions(-) create mode 100644 src/modm/board/disco_f411ve/board.hpp create mode 100644 src/modm/board/disco_f411ve/board.xml create mode 100644 src/modm/board/disco_f411ve/module.lb diff --git a/README.md b/README.md index 3d6b9e4338..f549319882 100644 --- a/README.md +++ b/README.md @@ -624,73 +624,74 @@ We have out-of-box support for many development boards including documentation. DISCO-F303VC DISCO-F401VC DISCO-F407VG -DISCO-F429ZI +DISCO-F411VE +DISCO-F429ZI DISCO-F469NI DISCO-F746NG DISCO-F769NI -DISCO-L152RC +DISCO-L152RC DISCO-L476VG FEATHER-M0 FEATHER-M4 -FEATHER-RP2040 +FEATHER-RP2040 MEGA-2560-PRO NUCLEO-F031K6 NUCLEO-F042K6 -NUCLEO-F072RB +NUCLEO-F072RB NUCLEO-F091RC NUCLEO-F103RB NUCLEO-F303K8 -NUCLEO-F303RE +NUCLEO-F303RE NUCLEO-F334R8 NUCLEO-F401RE NUCLEO-F411RE -NUCLEO-F429ZI +NUCLEO-F429ZI NUCLEO-F439ZI NUCLEO-F446RE NUCLEO-F446ZE -NUCLEO-F746ZG +NUCLEO-F746ZG NUCLEO-F767ZI NUCLEO-G070RB NUCLEO-G071RB -NUCLEO-G431KB +NUCLEO-G431KB NUCLEO-G431RB NUCLEO-G474RE NUCLEO-H723ZG -NUCLEO-H743ZI +NUCLEO-H743ZI NUCLEO-L031K6 NUCLEO-L053R8 NUCLEO-L152RE -NUCLEO-L432KC +NUCLEO-L432KC NUCLEO-L452RE NUCLEO-L476RG NUCLEO-L496ZG-P -NUCLEO-L552ZE-Q +NUCLEO-L552ZE-Q NUCLEO-U575ZI-Q OLIMEXINO-STM32 Raspberry Pi Pico -SAMD21-MINI +SAMD21-MINI SAMD21-XPLAINED-PRO SAME54-XPLAINED-PRO SAME70-XPLAINED -SAMG55-XPLAINED-PRO +SAMG55-XPLAINED-PRO SAMV71-XPLAINED-ULTRA Smart Response XE STM32-F4VE -STM32F030-DEMO +STM32F030-DEMO THINGPLUS-RP2040 diff --git a/examples/generic/usb/project.xml b/examples/generic/usb/project.xml index 91e2aceba2..4abc6e9b9f 100644 --- a/examples/generic/usb/project.xml +++ b/examples/generic/usb/project.xml @@ -5,6 +5,7 @@ + diff --git a/src/modm/board/disco_f411ve/board.hpp b/src/modm/board/disco_f411ve/board.hpp new file mode 100644 index 0000000000..0e4b470a2b --- /dev/null +++ b/src/modm/board/disco_f411ve/board.hpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2024, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- +#pragma once + +#include +#include +#include + +using namespace modm::platform; + +namespace Board +{ +/// @ingroup modm_board_disco_f411ve +/// @{ +using namespace modm::literals; + +/// STM32F411 running at 96MHz generated from the external 8MHz crystal +struct SystemClock +{ + static constexpr uint32_t Frequency = 96_MHz; + static constexpr uint32_t Ahb = Frequency; + static constexpr uint32_t Apb1 = Frequency / 2; + static constexpr uint32_t Apb2 = Frequency; + + static constexpr uint32_t Adc = Apb2; + + static constexpr uint32_t Spi1 = Apb2; + static constexpr uint32_t Spi2 = Apb1; + static constexpr uint32_t Spi3 = Apb1; + static constexpr uint32_t Spi4 = Apb2; + static constexpr uint32_t Spi5 = Apb2; + + static constexpr uint32_t Usart1 = Apb2; + static constexpr uint32_t Usart2 = Apb1; + static constexpr uint32_t Usart3 = Apb1; + static constexpr uint32_t Uart4 = Apb1; + static constexpr uint32_t Uart5 = Apb1; + static constexpr uint32_t Usart6 = Apb2; + static constexpr uint32_t Uart7 = Apb1; + static constexpr uint32_t Uart8 = Apb1; + + static constexpr uint32_t I2c1 = Apb1; + static constexpr uint32_t I2c2 = Apb1; + static constexpr uint32_t I2c3 = Apb1; + + static constexpr uint32_t Apb1Timer = Apb1 * 2; + static constexpr uint32_t Apb2Timer = Apb2 * 2; + static constexpr uint32_t Timer1 = Apb2Timer; + static constexpr uint32_t Timer2 = Apb1Timer; + static constexpr uint32_t Timer3 = Apb1Timer; + static constexpr uint32_t Timer4 = Apb1Timer; + static constexpr uint32_t Timer5 = Apb1Timer; + static constexpr uint32_t Timer9 = Apb2Timer; + static constexpr uint32_t Timer10 = Apb2Timer; + static constexpr uint32_t Timer11 = Apb2Timer; + + static constexpr uint32_t Usb = 48_MHz; + + static bool inline enable() + { + Rcc::enableExternalCrystal(); // 8MHz + const Rcc::PllFactors pllFactors{ + .pllM = 7, // 8MHz / M=7 -> ~1.14MHz + .pllN = 336, // 1.14MHz * N=336 -> 384MHz + .pllP = 4, // 384MHz / P=4 -> 96MHz = F_cpu + .pllQ = 8, // 384MHz / P=8 -> 48MHz = F_usb + }; + Rcc::enablePll(Rcc::PllSource::ExternalCrystal, pllFactors); + // set flash latency for 100MHz + Rcc::setFlashLatency(); + // switch system clock to PLL output + Rcc::enableSystemClock(Rcc::SystemClockSource::Pll); + Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1); + // APB1 has max. 50MHz + // APB2 has max. 100MHz + Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div2); + Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div1); + // update frequencies for busy-wait delay functions + Rcc::updateCoreFrequency(); + + return true; + } +}; + +using LedUsb = GpioOutputA9; +using ClockOut = GpioOutputA8; +using SystemClockOut = GpioOutputC9; + +using Button = GpioInputA0; + +// 4 user colored LEDs aligned in a circle +using LedGreen = GpioOutputD12; +using LedOrange = GpioOutputD13; +using LedRed = GpioOutputD14; +using LedBlue = GpioOutputD15; +using Leds = SoftwareGpioPort; +/// @} + +namespace lis3 +{ +/// @ingroup modm_board_disco_f411ve +/// @{ +using Int = GpioInputE1; // LIS302DL_INT2 + +using Cs = GpioOutputE3; // LIS302DL_CS_I2C/SPI +using Sck = GpioOutputA5; // SPI1_SCK +using Mosi = GpioOutputA7; // SPI1_MOSI +using Miso = GpioInputA6; // SPI1_MISO + +using SpiMaster = SpiMaster1; +using Transport = modm::Lis3TransportSpi; +/// @} +} + + +namespace cs43 +{ +/// @ingroup modm_board_disco_f411ve +/// @{ +using Lrck = GpioOutputA4; // I2S3_WS +using Mclk = GpioOutputC7; // I2S3_MCK +using Sclk = GpioOutputC10; // I2S3_SCK +using Sdin = GpioOutputC12; // I2S3_SD + +using Reset = GpioOutputD4; // Audio_RST +using Scl = GpioB6; // Audio_SCL +using Sda = GpioB9; // Audio_SDA + +using I2cMaster = I2cMaster1; +// using I2sMaster = I2sMaster3; +/// @} +} + + +namespace mp45 +{ +/// @ingroup modm_board_disco_f411ve +/// @{ +using Clk = GpioOutputB10; // CLK_IN: I2S2_CK +using Dout = GpioInputC3; // PDM_OUT: I2S2_SD +// using I2sMaster = I2sMaster2; +/// @} +} + + +namespace usb +{ +/// @ingroup modm_board_disco_f411ve +/// @{ +using Vbus = GpioInputA9; // VBUS_FS: USB_OTG_HS_VBUS +using Id = GpioA10; // OTG_FS_ID: USB_OTG_FS_ID +using Dm = GpioA11; // OTG_FS_DM: USB_OTG_FS_DM +using Dp = GpioA12; // OTG_FS_DP: USB_OTG_FS_DP + +using Overcurrent = GpioInputD5; // OTG_FS_OverCurrent +using Power = GpioOutputC0; // OTG_FS_PowerSwitchOn + +using Device = UsbFs; +/// @} +} + +/// @ingroup modm_board_disco_f411ve +/// @{ +inline void +initialize() +{ + SystemClock::enable(); + SysTickTimer::initialize(); + + Leds::setOutput(modm::Gpio::Low); + LedUsb::setOutput(modm::Gpio::Low); + + Button::setInput(Gpio::InputType::Floating); +} + +inline void +initializeLis3() +{ + lis3::Int::setInput(); + lis3::Cs::setOutput(modm::Gpio::High); + + lis3::SpiMaster::connect(); + lis3::SpiMaster::initialize(); + lis3::SpiMaster::setDataMode(lis3::SpiMaster::DataMode::Mode3); +} + +/// not supported yet, due to missing I2S driver +inline void +initializeCs43() +{ + // cs43::Lrck::connect(cs43::I2sMaster::Ws); + // cs43::Mclk::connect(cs43::I2sMaster::Mck); + // cs43::Sclk::connect(cs43::I2sMaster::Ck); + // cs43::Sdin::connect(cs43::I2sMaster::Sd); + + cs43::Reset::setOutput(modm::Gpio::High); + + cs43::I2cMaster::connect(); + cs43::I2cMaster::initialize(); +} + +/// not supported yet, due to missing I2S driver +inline void +initializeMp45() +{ + // mp45::Clk::connect(mp45::I2sMaster::Ck); + // mp45::Dout::connect(mp45::I2sMaster::Sd); +} + +inline void +initializeUsbFs(uint8_t priority=3) +{ + usb::Device::initialize(priority); + usb::Device::connect(); + + usb::Overcurrent::setInput(); + usb::Vbus::setInput(); + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} +/// @} +} diff --git a/src/modm/board/disco_f411ve/board.xml b/src/modm/board/disco_f411ve/board.xml new file mode 100644 index 0000000000..ee97f5e7f9 --- /dev/null +++ b/src/modm/board/disco_f411ve/board.xml @@ -0,0 +1,14 @@ + + + + ../../../../repo.lb + + + + + + + + modm:board:disco-f411ve + + diff --git a/src/modm/board/disco_f411ve/module.lb b/src/modm/board/disco_f411ve/module.lb new file mode 100644 index 0000000000..3d736c326f --- /dev/null +++ b/src/modm/board/disco_f411ve/module.lb @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2024, Thomas Sommer +# +# This file is part of the modm project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# ----------------------------------------------------------------------------- + +def init(module): + module.name = ":board:disco-f411ve" + module.description = """\ +# STM32F4DISCOVERY + +[Discovery kit for STM32F411](https://www.st.com/en/evaluation-tools/32f411ediscovery.html) +""" + +def prepare(module, options): + if not options[":target"].partname.startswith("stm32f411ve"): + return False + + module.depends( + ":architecture:clock", + ":driver:lis3dsh", + ":driver:lsm303a", + ":driver:l3gd20", + ":platform:clock", + ":platform:core", + ":platform:gpio", + ":platform:i2c:1", + ":platform:spi:1", + ":platform:usb:fs") + return True + +def build(env): + env.outbasepath = "modm/src/modm/board" + env.substitutions = { + "with_logger": False, + "with_assert": env.has_module(":architecture:assert") + } + env.template("../board.cpp.in", "board.cpp") + env.copy('.') + env.collect(":build:openocd.source", "board/stm32f4discovery.cfg");