Skip to content

Commit

Permalink
[board] Add Nucleo-L496-P
Browse files Browse the repository at this point in the history
  • Loading branch information
rleh committed May 9, 2021
1 parent 8e40754 commit 1e12c26
Show file tree
Hide file tree
Showing 5 changed files with 340 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,11 @@ We have out-of-box support for many development boards including documentation.
<td align="center"><a href="https://modm.io/reference/module/modm-board-nucleo-l452re">NUCLEO-L452RE</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-board-nucleo-l476rg">NUCLEO-L476RG</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-board-nucleo-l496zg-p">NUCLEO-L496ZG-P</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-board-olimexino-stm32">OLIMEXINO-STM32</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-board-raspberrypi">Raspberry Pi</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-board-samd21-mini">SAMD21-MINI</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-board-samd21-mini">SAMD21-MINI</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-board-stm32_f4ve">STM32-F4VE</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-board-stm32f030_demo">STM32F030-DEMO</a></td>
</tr>
Expand Down
95 changes: 95 additions & 0 deletions src/modm/board/nucleo144_arduino_l4.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Nucleo144 Arduino Header Footprint for STM32L4xxZx
// Schematic: https://www.st.com/resource/en/schematic_pack/mb1312-l4xxzx-a03_schematic.pdf

#ifndef MODM_STM32_NUCLEO144_ARDUINO_L4_HPP
#define MODM_STM32_NUCLEO144_ARDUINO_L4_HPP

// Arduino Footprint
using A0 = GpioA3;
using A1 = GpioC0;
using A2 = GpioC3;
using A3 = GpioC1;
using A4 = GpioC4;
using A5 = GpioC5;
// Zio Footprint
using A6 = GpioB1;
using A7 = GpioC2;
using A8 = GpioA1;

// Arduino Footprint
using D0 = GpioD9;
using D1 = GpioD8;
using D2 = GpioF15;
using D3 = GpioE13;
using D4 = GpioF14;
using D5 = GpioE11;
using D6 = GpioE9;
using D7 = GpioF13;
using D8 = GpioF12;
using D9 = GpioD15;
using D10 = GpioD14;
using D11 = GpioA7;
using D12 = GpioA6;
using D13 = GpioA5;
using D14 = GpioB9;
using D15 = GpioB8;
// Zio Footprint
using D16 = GpioC6;
using D17 = GpioB15;
using D18 = GpioB13;
using D19 = GpioB12;
using D20 = GpioA4;
using D21 = GpioB4;
using D22 = GpioB5;
using D23 = GpioB3;
using D24 = GpioA4;
using D25 = GpioB4;
using D26 = GpioA2;
using D27 = GpioB10;
using D28 = GpioE15;
using D29 = GpioB0;
using D30 = GpioE12;
using D31 = GpioE14;
using D32 = GpioA0;
using D33 = GpioB0;
using D34 = GpioE0;
using D35 = GpioUnused; // SMPSVDD12 on Nucleo-P (SMPS variants), otherwise GpioB11
using D36 = GpioB10;
using D37 = GpioE15;
using D38 = GpioE14;
using D39 = GpioE12;
using D40 = GpioE10;
using D41 = GpioE7;
using D42 = GpioE8;
using D43 = GpioC8;
using D44 = GpioC9;
using D45 = GpioC10;
using D46 = GpioC11;
using D47 = GpioC12;
using D48 = GpioD2;
using D49 = GpioF3;
using D50 = GpioF5;
using D51 = GpioD7;
using D52 = GpioD6;
using D53 = GpioD5;
using D54 = GpioD4;
using D55 = GpioD3;
using D56 = GpioE2;
using D57 = GpioE4;
using D58 = GpioE5;
using D59 = GpioE6;
using D60 = GpioE3;
using D61 = GpioF8;
using D62 = GpioF7;
using D63 = GpioF9;
using D64 = GpioG1;
using D65 = GpioG0;
using D66 = GpioD1;
using D67 = GpioD0;
using D68 = GpioF0;
using D69 = GpioF1;
using D70 = GpioF2;
using D71 = GpioB6;
using D72 = GpioB2;

#endif // MODM_STM32_NUCLEO144_ARDUINO_L4_HPP
182 changes: 182 additions & 0 deletions src/modm/board/nucleo_l496zg-p/board.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// coding: utf-8
/*
* Copyright (c) 2021, Raphael Lehmann
*
* 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_L496ZG_P_HPP
#define MODM_STM32_NUCLEO_L496ZG_P_HPP

#include <modm/platform.hpp>
#include <modm/architecture/interface/clock.hpp>
#include <modm/debug/logger.hpp>

/// @ingroup modm_board_nucleo_l496zg_p
#define MODM_BOARD_HAS_LOGGER

using namespace modm::platform;

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

/// STM32L4 running at 80MHz generated from the
/// internal Multispeed oscillator

// Dummy clock for devices
struct SystemClock {
static constexpr uint32_t Frequency = 80_MHz;
static constexpr uint32_t Ahb = Frequency;
static constexpr uint32_t Apb1 = Frequency;
static constexpr uint32_t Apb2 = Frequency;
static constexpr uint32_t Apb1Timer = Apb1;
static constexpr uint32_t Apb2Timer = Apb2;

static constexpr uint32_t Can1 = Apb1;
static constexpr uint32_t Can2 = Apb1;

static constexpr uint32_t Comp1 = Apb2;
static constexpr uint32_t Comp2 = Apb2;

static constexpr uint32_t Dac1 = 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 Sai1 = Apb2;
static constexpr uint32_t Sai2 = Apb2;

static constexpr uint32_t Spi1 = Apb2;
static constexpr uint32_t Spi2 = Apb1;
static constexpr uint32_t Spi3 = 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 Timer15 = Apb2Timer;
static constexpr uint32_t Timer16 = Apb2Timer;
static constexpr uint32_t Timer17 = Apb2Timer;

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 Lpuart1 = Frequency; // Clock mux default: 0b00 -> PCLK

static constexpr uint32_t Usb = 48_MHz;
static constexpr uint32_t Rng = 48_MHz;
static constexpr uint32_t Sdmmc = 48_MHz;

static bool inline
enable()
{
Rcc::enableMultiSpeedInternalClock(Rcc::MsiFrequency::MHz16);
const Rcc::PllFactors pllFactors{
.pllM = 2, // 16MHz / M=2 -> 8MHz
.pllN = 40, // 8MHz * N=40 -> 320MHz
.pllR = 4, // 320MHz / R=4 -> 80MHz = F_cpu
.pllQ = 2, // 320MHz / Q=2 -> 160MHz
};
Rcc::enablePll(Rcc::PllSource::Msi, pllFactors);
Rcc::setFlashLatency<Frequency>();
Rcc::enableSystemClock(Rcc::SystemClockSource::Pll);
Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1);
Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div1);
Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div1);
// update clock frequencies
Rcc::updateCoreFrequency<Frequency>();

// Enable Hsi48 clock
uint32_t waitCycles = 2048;
RCC->CRRCR |= RCC_CRRCR_HSI48ON;
while (not (RCC->CRRCR & RCC_CRRCR_HSI48RDY) and --waitCycles)
;

// Select Hsi48 as source for CLK48 MUX (USB, SDMMC, RNG)
RCC->CCIPR = (RCC->CCIPR & ~RCC_CCIPR_CLK48SEL_Msk) | (0b00 << RCC_CCIPR_CLK48SEL_Pos);

return true;
}
};

// Arduino Footprint
#include "nucleo144_arduino_l4.hpp"

using Button = GpioInputC13;

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

namespace usb
{
using Vbus = GpioA9;
using Id = GpioA10;
using Dm = GpioA11;
using Dp = GpioA12;

using Overcurrent = GpioInputG5; // OTG_FS_OverCurrent
using Power = GpioOutputG6; // OTG_FS_PowerSwitchOn

using Device = UsbFs;
}

namespace stlink
{
using Rx = GpioOutputG8;
using Tx = GpioInputG7;
using Uart = Lpuart1;
}

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);
}

inline void
initializeUsbFs()
{
usb::Device::initialize<SystemClock>();
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
usb::Vbus::setInput();
}

} // Board namespace

#endif // MODM_STM32_NUCLEO_L496ZG_P_HPP
16 changes: 16 additions & 0 deletions src/modm/board/nucleo_l496zg-p/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">stm32l496zgt6p</option>
<option name="modm:platform:uart:lpuart1:buffer.tx">2048</option>
</options>

<modules>
<module>modm:board:nucleo-l496zg-p</module>
</modules>
</library>
45 changes: 45 additions & 0 deletions src/modm/board/nucleo_l496zg-p/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) 2021, Raphael Lehmann
#
# 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-l496zg-p"
module.description = """\
# NUCLEO-L496ZG-P
[Nucleo kit for STM32L496ZG-P](https://www.st.com/en/evaluation-tools/nucleo-l496zg-p.html)
"""

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

module.depends(
":debug",
":architecture:clock",
":platform:core",
":platform:gpio",
":platform:clock",
":platform:uart:lpuart1",
":platform:usb:fs")

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_l4.hpp", "nucleo144_arduino_l4.hpp")
env.collect(":build:openocd.source", "board/st_nucleo_l4.cfg")

0 comments on commit 1e12c26

Please sign in to comment.