Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Adafruit Feather RP2040 board #898

Merged
merged 5 commits into from
Aug 17, 2022
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
- name: Examples RP20 Devices
if: always()
run: |
(cd examples && ../tools/scripts/examples_compile.py rp_pico)
(cd examples && ../tools/scripts/examples_compile.py rp_pico feather_rp2040)
- name: Execute Python Scripts
if: always()
run: |
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git

## Microcontrollers

modm can create a HAL for <!--allcount-->3287<!--/allcount--> devices of these vendors:
modm can create a HAL for <!--allcount-->3304<!--/allcount--> devices of these vendors:

- STMicroelectronics STM32: <!--stmcount-->2712<!--/stmcount--> devices.
- STMicroelectronics STM32: <!--stmcount-->2729<!--/stmcount--> devices.
- Microchip SAM: <!--samcount-->186<!--/samcount--> devices.
- Microchip AVR: <!--avrcount-->388<!--/avrcount--> devices.
- Raspberry Pi: <!--rpicount-->1<!--/rpicount--> device.
Expand Down Expand Up @@ -566,55 +566,56 @@ We have out-of-box support for many development boards including documentation.
<td align="center"><a href="https://modm.io/reference/config/modm-disco-l476vg">DISCO-L476VG</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-feather-m0">FEATHER-M0</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-feather-rp2040">FEATHER-RP2040</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-mega-2560-pro">MEGA-2560-PRO</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f031k6">NUCLEO-F031K6</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f042k6">NUCLEO-F042K6</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f042k6">NUCLEO-F042K6</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f072rb">NUCLEO-F072RB</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f091rc">NUCLEO-F091RC</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f103rb">NUCLEO-F103RB</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f303k8">NUCLEO-F303K8</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f303k8">NUCLEO-F303K8</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f303re">NUCLEO-F303RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f334r8">NUCLEO-F334R8</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f401re">NUCLEO-F401RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f411re">NUCLEO-F411RE</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f411re">NUCLEO-F411RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f429zi">NUCLEO-F429ZI</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f439zi">NUCLEO-F439ZI</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f446re">NUCLEO-F446RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f446ze">NUCLEO-F446ZE</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f446ze">NUCLEO-F446ZE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f746zg">NUCLEO-F746ZG</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-f767zi">NUCLEO-F767ZI</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-g071rb">NUCLEO-G071RB</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-g431kb">NUCLEO-G431KB</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-g431kb">NUCLEO-G431KB</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-g431rb">NUCLEO-G431RB</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-g474re">NUCLEO-G474RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-h723zg">NUCLEO-H723ZG</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-h743zi">NUCLEO-H743ZI</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-h743zi">NUCLEO-H743ZI</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l031k6">NUCLEO-L031K6</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l053r8">NUCLEO-L053R8</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l152re">NUCLEO-L152RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l432kc">NUCLEO-L432KC</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l432kc">NUCLEO-L432KC</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l452re">NUCLEO-L452RE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l476rg">NUCLEO-L476RG</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l496zg-p">NUCLEO-L496ZG-P</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l552ze-q">NUCLEO-L552ZE-Q</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-nucleo-l552ze-q">NUCLEO-L552ZE-Q</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-olimexino-stm32">OLIMEXINO-STM32</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-raspberrypi">Raspberry Pi</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-rp-pico">Raspberry Pi Pico</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-samd21-mini">SAMD21-MINI</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-samd21-mini">SAMD21-MINI</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-samg55-xplained-pro">SAMG55-XPLAINED-PRO</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-srxe">Smart Response XE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-stm32_f4ve">STM32-F4VE</a></td>
<td align="center"><a href="https://modm.io/reference/config/modm-stm32f030_demo">STM32F030-DEMO</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/config/modm-stm32f030_demo">STM32F030-DEMO</a></td>
</tr>
</table>
<!--/bsptable-->
Expand Down
39 changes: 39 additions & 0 deletions examples/feather_rp2040/blink/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, Sascha Schade
* Copyright (c) 2017, Niklas Hauser
*
* 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/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>

using namespace Board;

/*
* Blinks the green user LED with 1 Hz.
* It is on for 90% of the time and off for 10% of the time.
*/

int
main()
{
Board::initialize();

Led::setOutput();

while (true)
{
Led::set();
modm::delay(900ms);

Led::reset();
modm::delay(100ms);
}

return 0;
}
9 changes: 9 additions & 0 deletions examples/feather_rp2040/blink/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<library>
<extends>modm:feather-rp2040</extends>
<options>
<option name="modm:build:build.path">../../../build/feather_rp2040/blink</option>
</options>
<modules>
<module>modm:build:scons</module>
</modules>
</library>
104 changes: 104 additions & 0 deletions src/modm/board/feather_rp2040/board.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
*
* Copyright (c) 2022, Andrey Kunitsyn
* Copyright (c) 2022, Nikolay Semenov
*
* 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 <modm/architecture/interface/clock.hpp>
#include <modm/platform.hpp>

using namespace modm::platform;

namespace Board
{
using namespace modm::literals;

/// RP2040 running at 125MHz generated from the external 12MHz crystal
/// @ingroup modm_board_feather_rp2040
struct SystemClock
{
static constexpr uint32_t Frequency = 125_MHz;
static constexpr uint32_t XOSCFrequency = 12_MHz;
// https://github.com/raspberrypi/pico-sdk/pull/457
static constexpr uint16_t XOSCDelayMultiplier = 64;
static constexpr uint32_t PllSysFrequency = Frequency;
static constexpr uint32_t PllUsbFrequency = 48_MHz;
static constexpr uint32_t SysPLLMul = 125;
static constexpr uint32_t UsbPLLMul = 40;
static constexpr uint32_t RefFrequency = XOSCFrequency;
static constexpr uint32_t UsbFrequency = PllUsbFrequency;
static constexpr uint32_t SysFrequency = Frequency;
static constexpr uint32_t PeriFrequency = SysFrequency;

static bool inline enable()
{
ClockControl::disableResus();
ClockControl::enableExternalCrystal(XOSCFrequency, XOSCDelayMultiplier);
ClockControl::disableAux<ClockControl::Clock::Sys>();
ClockControl::disableAux<ClockControl::Clock::Ref>();
// PLL SYS: 12MHz / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
ClockControl::initPll<ClockControl::Pll::Sys, 1, SysPLLMul, 6, 2>();
// PLL USB: 12MHz / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz
ClockControl::initPll<ClockControl::Pll::Usb, 1, UsbPLLMul, 5, 2>();

// CLK_REF = XOSC (12MHz) / 1 = 12MHz
ClockControl::configureClock<ClockControl::Clock::Ref, ClockControl::ClockSrc::Xosc,
XOSCFrequency, RefFrequency>();
// CLK SYS = PLL SYS (125MHz) / 1 = 125MHz
ClockControl::configureClock<ClockControl::Clock::Sys, ClockControl::ClockSrc::PllSys,
PllSysFrequency, SysFrequency>();
// CLK USB = PLL USB (48MHz) / 1 = 48MHz
ClockControl::configureClock<ClockControl::Clock::Usb, ClockControl::ClockSrc::PllUsb,
PllUsbFrequency, UsbFrequency>();
// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select
// and enable Normally choose clk_sys or clk_usb
ClockControl::configureClock<ClockControl::Clock::Peri, ClockControl::ClockSrc::Sys,
SysFrequency, PeriFrequency>();

ClockControl::updateCoreFrequency<Frequency>();
return true;
}
};

namespace usb
{
/// @ingroup modm_board_feather_rp2040
using Device = Usb;
}

/// @ingroup modm_board_feather_rp2040
/// @{
// User LED
using LedRed = GpioOutput13;
using Led = LedRed;
using Leds = SoftwareGpioPort<Led>;

using Button = GpioUnused;

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

Led::setOutput();
}

inline void
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<>();
}
/// @}

} // namespace Board
16 changes: 16 additions & 0 deletions src/modm/board/feather_rp2040/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">rp2040</option>
<option name="modm:platform:core:boot2">generic_03h</option>
<option name="modm:platform:core:boot2_size">8*1024*1024</option>
</options>
<modules>
<module>modm:board:feather-rp2040</module>
</modules>
</library>
49 changes: 49 additions & 0 deletions src/modm/board/feather_rp2040/module.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, Andrey Kunitsyn
# Copyright (c) 2022, Nikolay Semenov
#
# 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:feather-rp2040"
module.description = """\
# Adafruit Feather RP2040

A board with RP2040 chip and 8MB of flash memory.

https://www.adafruit.com/product/4884

See `modm:rp-pico` for programming instructions.
"""

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

module.depends(
":platform:clock",
":platform:core",
":platform:gpio",
":platform:usb",
":platform:clockgen")
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.outbasepath = "modm/openocd/modm/board/"
env.copy(repopath("tools/openocd/modm/rp2040_picoprobe.cfg"), "rp2040_picoprobe.cfg")
env.collect(":build:openocd.source", "modm/board/rp2040_picoprobe.cfg")
8 changes: 2 additions & 6 deletions src/modm/platform/clock/rp/clocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@

#include "../device.hpp"

#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 1
#endif

// CMSIS Core compliance
constinit uint32_t modm_fastdata SystemCoreClock(modm::platform::ClockControl::BootFrequency);

Expand All @@ -30,12 +26,12 @@ constinit uint16_t modm_fastdata delay_ns_per_loop(computeDelayNsPerLoop(ClockCo
static uint32_t configured_freq[CLK_COUNT];

void
ClockControl::enableExternalCrystal(uint32_t freq)
ClockControl::enableExternalCrystal(uint32_t freq, uint16_t delay_multiplier)
{
// Assumes 1-15 MHz input, checked above.
xosc_hw->ctrl = XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ;

uint32_t delay = ((((freq / 1000) + 128) / 256) * PICO_XOSC_STARTUP_DELAY_MULTIPLIER);
uint32_t delay = ((((freq / 1000) + 128) / 256) * delay_multiplier);

// Set xosc startup delay
xosc_hw->startup = delay;
Expand Down
2 changes: 1 addition & 1 deletion src/modm/platform/clock/rp/clocks.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public:
}

static void
enableExternalCrystal(uint32_t freq);
enableExternalCrystal(uint32_t freq, uint16_t delay_multiplier = 1);

template<Clock clk>
static void
Expand Down
9 changes: 8 additions & 1 deletion src/modm/platform/core/cortex/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ def common_memories(env):
memories = listify(device.get_driver("core")["memory"])

# Convert from string to int and add offsets
flash_size = env.get(":platform:core:boot2_size", 0)
if flash_size:
memories.append({
"name": "flash",
"access": "rx",
"start": "0x10000000",
"size": hex(flash_size)})
flash_offset = env.get(":platform:cortex-m:linkerscript.flash_offset", 0)
for m in memories:
if m["name"] == "flash":
Expand Down Expand Up @@ -213,7 +220,7 @@ def prepare(module, options):
default=default_location))

# Find the size of the flash memory
flash_size = next(int(x['size']) for x in memories if x['name'] == 'flash')
flash_size = next((int(x['size']) for x in memories if x['name'] == 'flash'), 16*1024*1024)
module.add_option(
NumericOption(
name="linkerscript.flash_offset",
Expand Down
7 changes: 7 additions & 0 deletions src/modm/platform/core/rp/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ def prepare(module, options):
description="Second-stage bootloader variant",
enumeration=["generic_03h", "at25sf128a", "is25lp080", "w25q080", "w25x10cl"],
default="generic_03h"))
module.add_option(
NumericOption(
name="boot2_size",
description="Specify the size of external QSPI FLASH chip",
minimum=0,
maximum=2 ** 24,
default=2 ** 21))
return True


Expand Down
7 changes: 7 additions & 0 deletions tools/build_script_generator/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ def common_memories(env):
}
for memory in core_driver["memory"]
])
flash_size = env.get(":platform:core:boot2_size", 0)
if flash_size:
memories.append({
"name": "flash",
"access": "rx",
"start": 0x10000000,
"size": flash_size})
return memories

def common_avrdude_options(env):
Expand Down
Loading