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
10 changes: 10 additions & 0 deletions modm-project-files/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ sys.path.append(repopath("scripts/lbuild-helpers"))
MCU_VARIANTS_BY_BOARD = {
"rm-dev-board-a": "stm32f427iih6",
"rm-dev-board-c": "stm32f407igh6",
"stm32f446re": "stm32f446ret6"
}

DEFAULT_MODM_OPTIONS_BY_BOARD = {
Expand All @@ -46,6 +47,15 @@ DEFAULT_MODM_OPTIONS_BY_BOARD = {
modm:platform:uart:3:buffer.rx 256\n\
modm:platform:uart:6:buffer.rx 256\n\
modm:platform:uart:6:buffer.tx 256",
"stm32f446re": "\
modm:platform:uart:1:buffer.rx 256\n\
modm:platform:uart:1:buffer.tx 256\n\
modm:platform:uart:3:buffer.rx 256\n\
modm:platform:uart:3:buffer.tx 256\n\
modm:platform:uart:4:buffer.rx 256\n\
modm:platform:uart:4:buffer.tx 256\n\
modm:platform:uart:5:buffer.rx 256\n\
modm:platform:uart:5:buffer.tx 256",
}

def get_modm_repo_lb_file() -> str:
Expand Down
19 changes: 12 additions & 7 deletions modm-project-files/project.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,8 @@
<module>modm:platform:flash</module>
<module>modm:platform:gpio</module>
<module>modm:platform:heap</module>
<module>modm:platform:random</module>
<module>modm:platform:timer:8</module>
<module>modm:platform:uart:1</module>
<module>modm:platform:uart:3</module>
<module>modm:platform:uart:6</module>
<module>modm:platform:adc:1</module>
<module>modm:platform:spi:1</module>
<!-- Remove random module since F446RE has no RNG peripheral -->
<!-- <module>modm:platform:random</module> -->
%% if options[":dev_board"] == "rm-dev-board-a"
<module>modm:platform:i2c:2</module>
<module>modm:platform:timer:3</module>
Expand All @@ -61,6 +56,16 @@
<module>modm:platform:timer:4</module>
<module>modm:platform:timer:10</module>
<module>modm:platform:adc:3</module>
%% elif options[":dev_board"] == "stm32f446re"
<module>modm:platform:uart:1</module>
<module>modm:platform:uart:2</module>
<module>modm:platform:uart:3</module>
<module>modm:platform:uart:4</module>
<module>modm:platform:uart:5</module>
<module>modm:platform:timer:8</module>
<!-- <module>modm:platform:spi:2</module> -->
<!-- <module>modm:platform:i2c:1</module> -->
<module>modm:platform:adc:1</module>
%% endif

{% for m in modm_hal_modules %} {{ m }}{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion repo.lb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def init(repo):
EnumerationOption(
name="dev_board",
description="Which development board to be used",
enumeration=["rm-dev-board-a", "rm-dev-board-c"]))
enumeration=["rm-dev-board-a", "rm-dev-board-c", "stm32f446re"]))

def prepare(repo, options):
repo.add_modules_recursive("./src", modulefile="*.lb")
Expand Down
182 changes: 182 additions & 0 deletions src/tap/board/stm32f446re/board.hpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Copyright (c) 2020-2021 Advanced Robotics at the University of Washington <[email protected]>
*
* This file is part of Taproot.
*
* Taproot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Taproot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Taproot. If not, see <https://www.gnu.org/licenses/>.
*/

/*
* Copyright (c) 2016-2018, Niklas Hauser
* Copyright (c) 2017, Sascha Schade
* Copyright (c) 2018, Antal Szabó
* Copyright (c) 2019 Sebastian Birke
*
* 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/.
*/
// ----------------------------------------------------------------------------

#ifndef TAPROOT_BOARD_HPP_
#define TAPROOT_BOARD_HPP_

#ifndef PLATFORM_HOSTED
#include "modm/architecture/interface/clock.hpp"
#include "modm/platform.hpp"

using namespace modm::platform;
#else
#include "modm/math/units.hpp"
#endif

/// @ingroup modm_board_nucleo_f446re
namespace Board
{
using namespace modm::literals;

/// STM32F446RE running at 180MHz generated from the internal 16MHz crystal
// Dummy clock for devices
struct SystemClock {
static constexpr uint32_t Frequency = 180_MHz;
static constexpr uint32_t Ahb = Frequency;
static constexpr uint32_t Apb1 = Frequency / 4;
static constexpr uint32_t Apb2 = Frequency / 2;

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 Can1 = Apb1;
static constexpr uint32_t Can2 = 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 * 1;
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 bool inline
enable()
{
#ifndef PLATFORM_HOSTED
Rcc::enableInternalClock(); // 16MHz
const Rcc::PllFactors pllFactors{
.pllM = 8, // 16MHz / M= 8 -> 2MHz
.pllN = 180, // 2MHz * N=180 -> 360MHz
.pllP = 2, // 360MHz / P= 2 -> 180MHz = F_cpu
};
Rcc::enablePll(Rcc::PllSource::InternalClock, pllFactors);
// Required for 180 MHz clock
Rcc::enableOverdriveMode();
// set flash latency
Rcc::setFlashLatency<Frequency>();
// switch system clock to PLL output
Rcc::enableSystemClock(Rcc::SystemClockSource::Pll);
Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1);
// APB1 has max. 50MHz
Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div4);
Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div2);
// update frequencies for busy-wait delay functions
Rcc::updateCoreFrequency<Frequency>();
#endif

return true;
}
};

#ifndef PLATFORM_HOSTED
// Arduino Footprint
// #include "nucleo64_arduino.hpp"

using Button = GpioInverted<GpioInputC13>;
using LedD13 = GpioOutputA5;
using LED1 = GpioOutputC0;
using LED2 = GpioOutputC1;
using LED3 = GpioOutputB0;

using LedsPort = SoftwareGpioPort< LedD13,LED1,LED2,LED3 >;

%% macro configure_pins(comment, pin_group_name, pins)
%% if pins|length > 0
// {{ comment }}
{% if pins|length > 0 %}
%% for pin in pins
using {{ pin_group_name }}{{ pin }} = {{ pin_mappings[pin] }};
%% endfor
{% endif %}
using {{ pin_group_name }}s = SoftwareGpioPort<{% for pin in pins %}{{ pin_group_name }}{{ pin }}{% if not loop.last %}, {% endif %}{% endfor %}>;
%% endif
%% endmacro

{{ configure_pins("Initialize analog input pins", "AnalogInPin", analog_in_pins) }}
{{ configure_pins("Initialize PWM pins", "PWMOutPin", pwm_pins) }}
{{ configure_pins("Initialize digital input pins", "DigitalInPin", digital_in_pins) }}
{{ configure_pins("Initialize digital output pins", "DigitalOutPin", digital_out_pins) }}
// gpio pins used for SPI communication to the onboard MPU6500 IMU


namespace stlink
{
using Rx = GpioInputA3;
using Tx = GpioOutputA2;
using Uart = Usart2;
}

using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockIfFull >;

#endif

inline void
initialize()
{
SystemClock::enable();
#ifndef PLATFORM_HOSTED
SysTickTimer::initialize<SystemClock>();

stlink::Uart::connect<stlink::Tx::Tx, stlink::Rx::Rx>();
stlink::Uart::initialize<SystemClock, 115200_Bd>();

Button::setInput();
Button::setInputTrigger(Gpio::InputTrigger::RisingEdge);
Button::enableExternalInterrupt();
#endif
// Button::enableExternalInterruptVector(12);
}

}

#endif // MODM_STM32_NUCLEO_F446RE_HPP
18 changes: 18 additions & 0 deletions src/tap/communication/gpio/leds.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ void Leds::set(Leds::LedPin pin, bool isSet)
case Leds::LedPin::Blue:
LedBlue::set(isSet);
}
%% elif options[":dev_board"] == "stm32f446re"
switch (pin)
{
case Leds::LedPin::Green:
LedD13::set(isSet); // LD2 on PA5/D13
break;

case Leds::LedPin::A:
LED1::set(isSet);
break;

case Leds::LedPin::B:
LED2::set(isSet);
break;

case Leds::LedPin::C:
LED3::set(isSet);
}
%% endif
#endif
}
Expand Down
13 changes: 13 additions & 0 deletions src/tap/communication/gpio/leds.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ public:
Blue
};

%% elif options[":dev_board"] == "stm32f446re"
/**
* The LED corresponds to the built-in LED (LD2) on the Nucleo-F446RE board.
* - Green LED (LD2) is connected to PA5 (Arduino D13)
*/
enum LedPin
{
Green, // LD2 on PA5
A,
B,
C
};

%% endif

/**
Expand Down
7 changes: 5 additions & 2 deletions src/tap/communication/sensors/buzzer/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ def init(module):

def prepare(module, options):
metadata = board_info_parser.parse_board_info(options[":dev_board"])
pins = metadata.find("gpio-pins")
buzzer_pins = [pin for pin in pins if pin.get("alias") == BUZZER_PIN]
pins_element = metadata.find("gpio-pins")
if pins_element is None:
raise Exception("No <gpio-pins> found in board metadata. Check your board XML.")

buzzer_pins = [pin for pin in pins_element.findall("gpio") if pin.get("alias") == BUZZER_PIN]
if len(buzzer_pins) == 1:
global buzzer_timer
buzzer_timer = buzzer_pins[0].find("timer").get("name")
Expand Down
1 change: 1 addition & 0 deletions src/tap/communication/serial/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import board_info_parser
REMOTE_UART_PORTS_BY_BOARD = {
"rm-dev-board-a": "Uart1",
"rm-dev-board-c": "Uart3",
"stm32f446re": "Uart1",
}

class Remote(Module):
Expand Down
61 changes: 61 additions & 0 deletions supported-devices/stm32f446re.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<board>
<can-pins>
<gpio alias="Can1Rx" name="GpioA11"/>
<gpio alias="Can1Tx" name="GpioA12"/>
<gpio alias="Can2Rx" name="GpioB12"/>
<gpio alias="Can2Tx" name="GpioB13"/>
</can-pins>

<gpio-pins>
<!-- Digital Input Pins
<gpio alias="PA0" name="GpioA0">
<adc name="Adc1" in="In0"/>
</gpio>
<gpio alias="PA1" name="GpioA1">
<adc name="Adc1" in="In1"/>
</gpio>
<gpio alias="PA4" name="GpioA4">
<adc name="Adc1" in="In4"/>
</gpio> -->

<gpio alias="PB5" name="GpioB5"/>


<!-- Digital Output Pins -->
<gpio alias="LED1" name="GpioC0"/>
<gpio alias="LED2" name="GpioC1"/>
<gpio alias="LED3" name="GpioB0"/>

<!-- PWM Pins -->
<!-- <gpio alias="PB1" name="GpioB1">
<timer name="Timer8" channel="Ch3"/>
</gpio>
<gpio alias="PC9" name="GpioC9">
<timer name="Timer8" channel="Ch4"/>
</gpio> -->

<!-- Analog Input Pins -->
<gpio alias="PA7" name="GpioA7">
<adc name="Adc1" in="In7"/>
</gpio>
<gpio alias="PA6" name="GpioA6">
<adc name="Adc1" in="In6"/>
</gpio>

<!-- <gpio alias="PC8" name="GpioC8"/> -->
</gpio-pins>

<uart-ports>
<uart sync="true" name="1" tx="GpioB6" rx="GpioA10"/>
<uart sync="false" name="5" tx="GpioC12" rx="GpioD2"/>
<uart sync="true" name="3" tx="GpioC10" rx="GpioC11"/>
<uart sync="false" name="4" tx="GpioA0" rx="GpioA1"/>
<uart sync="true" name="2" tx="GpioA2" rx="GpioA3"/>
</uart-ports>
<!-- <i2c-ports>
<i2c name="1" scl="GpioB8" sda="GpioB7"></i2c>
</i2c-ports>
<spi-ports>
<spi name="1" sck="GpioA9" miso="GpioB14" mosi="GpioB15" nss="GpioB9"/>
</spi-ports> -->
</board>