Skip to content

Commit

Permalink
[board] Add NUCLEO-F746ZG support
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixPetriconi authored and salkinium committed May 11, 2020
1 parent a2ca836 commit a010cbb
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 3 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,16 @@ documentation.
<td align="center">NUCLEO-F429ZI</td>
<td align="center">NUCLEO-F446RE</td>
</tr><tr>
<td align="center">NUCLEO-F746ZG</td>
<td align="center">NUCLEO-G071RB</td>
<td align="center">NUCLEO-G474RE</td>
<td align="center">NUCLEO-L152RE</td>
<td align="center">NUCLEO-L432KC</td>
</tr><tr>
<td align="center">NUCLEO-L432KC</td>
<td align="center">NUCLEO-L476RG</td>
<td align="center">OLIMEXINO-STM32</td>
<td align="center">STM32F030F4P6-DEMO</td>
</tr><tr>
</tr>
</table>
<!--/bsptable-->
Expand Down
13 changes: 11 additions & 2 deletions docs/src/guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ with modm:
- [Software Construct][scons] or [CMake][]
- [Library Builder][lbuild]
- AVR toolchain: [avr-gcc][] and [avrdude][]
- ARM toolchain: [gcc-arm-toolchain][] and [OpenOCD][].
- ARM toolchain: [gcc-arm-toolchain][] and [OpenOCD][] (HEAD version!).
- Optional: [Doxygen][] or [Doxypress][]
- Optional: [gdbgui][] for IDE-independent debugging

Expand Down Expand Up @@ -71,7 +71,7 @@ some of these libraries as well, depending on what modm modules you use:

For Ubuntu 18.04LTS, these commands install the basic build system:

sudo apt-get install python3 python3-pip scons git openocd
sudo apt-get install python3 python3-pip scons git
sudo apt-get --no-install-recommends install doxygen
pip3 install modm

Expand All @@ -95,6 +95,14 @@ for 64-bit Linux and adding its `/bin` directory to your path.
**Even though your distribution may ship their own ARM toolchain, we very strongly
recommend using the official toolchain, since all of modm is tested with it.**

Install OpenOCD via your package manager:

sudo apt-get install openocd

The latest OpenOCD release v0.10.0 (as of May 2020) is too old for some targets
(STM32G0, STM32G4, STM32F7). To program these targets you need to compile the
[HEAD version of OpenOCD from source][openocd-source].

We recommend the use of a graphical frontend for GDB called [gdbgui][]:

pip3 install gdbgui
Expand Down Expand Up @@ -141,6 +149,7 @@ You'll need to add both `/bin` paths to your `PATH` variable manually.
[examples]: https://github.com/modm-io/modm/tree/develop/examples
[gcc-arm-toolchain]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm
[openocd]: http://openocd.org
[openocd-source]: https://github.com/ntfreak/openocd
[avr-gcc]: https://www.nongnu.org/avr-libc
[avrdude]: https://www.nongnu.org/avrdude
[lbuild]: https://github.com/modm-io/lbuild
Expand Down
152 changes: 152 additions & 0 deletions src/modm/board/nucleo_f746zg/board.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2016-2017, Sascha Schade
* Copyright (c) 2016-2018, Niklas Hauser
* Cpoyright (c) 2020, Felix Petriconi
*
* 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 MODM_STM32_NUCLEO_F746ZG_HPP
#define MODM_STM32_NUCLEO_F746ZG_HPP

#include <modm/platform.hpp>
#include <modm/architecture/interface/clock.hpp>
#include <modm/debug/logger.hpp>
/// @ingroup modm_board_nucleo_f746zg
#define MODM_BOARD_HAS_LOGGER

using namespace modm::platform;

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

/// STM32F7 running at 216MHz from the external 8MHz clock
struct SystemClock
{
static constexpr uint32_t Frequency = 216_MHz;
static constexpr uint32_t Apb1 = Frequency / 4;
static constexpr uint32_t Apb2 = Frequency / 2;
static constexpr uint32_t Apb1Timer = Apb1 * 2;
static constexpr uint32_t Apb2Timer = Apb2 * 2;

static constexpr uint32_t Ethernet = Frequency;

static constexpr uint32_t Adc1 = Apb2;
static constexpr uint32_t Adc2 = Apb2;
static constexpr uint32_t Adc3 = Apb2;

static constexpr uint32_t Dac = Apb1;

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 Spi6 = 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 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 I2c4 = Apb1;

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 Timer6 = Apb1Timer;
static constexpr uint32_t Timer7 = Apb1Timer;
static constexpr uint32_t Timer8 = Apb2Timer;
static constexpr uint32_t Timer9 = Apb2Timer;
static constexpr uint32_t Timer10 = Apb2Timer;
static constexpr uint32_t Timer11 = Apb2Timer;
static constexpr uint32_t Timer12 = Apb1Timer;
static constexpr uint32_t Timer13 = Apb1Timer;
static constexpr uint32_t Timer14 = Apb1Timer;

static bool inline
enable()
{
Rcc::enableExternalClock(); // 8 MHz
const Rcc::PllFactors pllFactors{
.pllM = 4, // 8MHz / M=4 -> 2MHz
.pllN = 216, // 2MHz * N=216 -> 432MHz
.pllP = 2 // 432MHz / P=2 -> 216MHz = F_cpu
//.pllQ = 9 // 432MHz / P=2 -> 48MHz (USB, etc.)
};
Rcc::enablePll(Rcc::PllSource::ExternalClock, pllFactors);
PWR->CR1 |= PWR_CR1_ODEN; // Enable overdrive mode
while (not (PWR->CSR1 & PWR_CSR1_ODRDY)) ;
Rcc::setFlashLatency<Frequency>();
Rcc::enableSystemClock(Rcc::SystemClockSource::Pll);
// APB1 is running at 54MHz, since AHB / 4 = 54MHz (= limit)
Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div4);
// APB2 is running at 108MHz, since AHB / 2 = 108MHz (= limit)
Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div2);
Rcc::updateCoreFrequency<Frequency>();

return true;
}
};

// Arduino Footprint
#include "nucleo144_arduino.hpp"

using Button = GpioInputC13;

using LedGreen = GpioOutputB0; // LED1 [Green]
using LedBlue = GpioOutputB7; // LED2 [Blue]
using LedRed = GpioOutputB14; // LED3 [Red]
using Leds = SoftwareGpioPort< LedRed, LedBlue, LedGreen >;

namespace stlink
{
using Tx = GpioOutputD8;
using Rx = GpioInputD9;
using Uart = Usart3;
}

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


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

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

LedGreen::setOutput(modm::Gpio::Low);
LedBlue::setOutput(modm::Gpio::Low);
LedRed::setOutput(modm::Gpio::Low);

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

}

#endif // MODM_STM32_NUCLEO_F746ZG_HPP
16 changes: 16 additions & 0 deletions src/modm/board/nucleo_f746zg/board.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<library>
<repositories>
<repository>
<path>../../../../repo.lb</path>
</repository>
</repositories>

<options>
<option name="modm:target">stm32f746zgt6</option>

<option name="modm:platform:uart:3:buffer.tx">2048</option>
</options>
<modules>
<module>modm:board:nucleo-f746zg</module>
</modules>
</library>
45 changes: 45 additions & 0 deletions src/modm/board/nucleo_f746zg/module.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2016-2018, Niklas Hauser
# Copyright (c) 2017, Fabian Greif
#
# 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:nucleo-f746zg"
module.description = """\
# NUCLEO-F746ZG
[Nucleo kit for STM32F746ZG](https://www.st.com/en/evaluation-tools/nucleo-f746zg.html)
"""

def prepare(module, options):
if not options[":target"].partname.startswith("stm32f746zg"):
return False

module.depends(
":architecture:clock",
":debug",
":platform:clock",
":platform:core",
":platform:gpio",
":platform:uart:3")

return True

def build(env):
env.outbasepath = "modm/src/modm/board"
env.substitutions = {
"with_logger": True,
"with_assert": env.has_module(":architecture:assert")
}
env.template("../board.cpp.in", "board.cpp")
env.copy('.')
env.copy("../nucleo144_arduino.hpp", "nucleo144_arduino.hpp")
env.collect(":build:openocd.source", "board/st_nucleo_f7.cfg");

0 comments on commit a010cbb

Please sign in to comment.