diff options
author | skeys <skeys@google.com> | 2022-03-02 18:05:35 -0800 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-04-04 21:13:39 +0000 |
commit | e520091eebfc1c5527d20b9acf37269b0d8811e3 (patch) | |
tree | 4e58ab051aa28b5e88109c8fc95ea971705b5616 | |
parent | 6ff271a3cda97f38f9bdca80160e82616678fc01 (diff) | |
download | pigweed-e520091eebfc1c5527d20b9acf37269b0d8811e3.tar.gz |
pw_sys_io_emcraft_sf2: Add basic UART I/O support
Introduces a GN-based build for the Emcraft Smartfusion 2 SOM.
* Adds 'emcraft_sf2_som' as a pw_system target.
* Smartfusion MSS HAL added to 'third_party'.
Change-Id: Ibdb4affdd11e5ba57659b90f8182ef0bc24ab9e7
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/86940
Reviewed-by: Keir Mierle <keir@google.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: Sean Keys <skeys@google.com>
22 files changed, 747 insertions, 6 deletions
diff --git a/PIGWEED_MODULES b/PIGWEED_MODULES index 9912ec7fb..dfb7f2725 100644 --- a/PIGWEED_MODULES +++ b/PIGWEED_MODULES @@ -92,6 +92,7 @@ pw_sys_io pw_sys_io_arduino pw_sys_io_baremetal_lm3s6965evb pw_sys_io_baremetal_stm32f429 +pw_sys_io_emcraft_sf2 pw_sys_io_mcuxpresso pw_sys_io_stdio pw_sys_io_stm32cube diff --git a/pw_build/generated_pigweed_modules_lists.gni b/pw_build/generated_pigweed_modules_lists.gni index e5765eec1..f3d3627ef 100644 --- a/pw_build/generated_pigweed_modules_lists.gni +++ b/pw_build/generated_pigweed_modules_lists.gni @@ -126,6 +126,8 @@ declare_args() { get_path_info("../pw_sys_io_baremetal_lm3s6965evb", "abspath") dir_pw_sys_io_baremetal_stm32f429 = get_path_info("../pw_sys_io_baremetal_stm32f429", "abspath") + dir_pw_sys_io_emcraft_sf2 = + get_path_info("../pw_sys_io_emcraft_sf2", "abspath") dir_pw_sys_io_mcuxpresso = get_path_info("../pw_sys_io_mcuxpresso", "abspath") dir_pw_sys_io_stdio = get_path_info("../pw_sys_io_stdio", "abspath") dir_pw_sys_io_stm32cube = get_path_info("../pw_sys_io_stm32cube", "abspath") @@ -254,6 +256,7 @@ declare_args() { dir_pw_sys_io_arduino, dir_pw_sys_io_baremetal_lm3s6965evb, dir_pw_sys_io_baremetal_stm32f429, + dir_pw_sys_io_emcraft_sf2, dir_pw_sys_io_mcuxpresso, dir_pw_sys_io_stdio, dir_pw_sys_io_stm32cube, @@ -439,6 +442,7 @@ declare_args() { "$dir_pw_sys_io:docs", "$dir_pw_sys_io_arduino:docs", "$dir_pw_sys_io_baremetal_stm32f429:docs", + "$dir_pw_sys_io_emcraft_sf2:docs", "$dir_pw_sys_io_mcuxpresso:docs", "$dir_pw_sys_io_stdio:docs", "$dir_pw_sys_io_stm32cube:docs", diff --git a/pw_package/py/BUILD.gn b/pw_package/py/BUILD.gn index bfc46a8d1..1af696e78 100644 --- a/pw_package/py/BUILD.gn +++ b/pw_package/py/BUILD.gn @@ -38,6 +38,7 @@ pw_python_package("py") { "pw_package/packages/nanopb.py", "pw_package/packages/pico_sdk.py", "pw_package/packages/protobuf.py", + "pw_package/packages/smartfusion_mss.py", "pw_package/packages/stm32cube.py", "pw_package/pigweed_packages.py", ] diff --git a/pw_package/py/pw_package/packages/smartfusion_mss.py b/pw_package/py/pw_package/packages/smartfusion_mss.py new file mode 100644 index 000000000..b9dbe49c7 --- /dev/null +++ b/pw_package/py/pw_package/packages/smartfusion_mss.py @@ -0,0 +1,40 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""Install and check status of SmartFusion MSS.""" + +import pathlib +from typing import Sequence + +import pw_package.git_repo +import pw_package.package_manager + + +class SmartfusionMss(pw_package.git_repo.GitRepo): + """Install and check status of SmartFusion MSS.""" + def __init__(self, *args, **kwargs): + super().__init__(*args, + name='smartfusion_mss', + url='https://github.com/seank/smartfusion_mss', + commit='9f47db73d3df786eab04d082645da5e735e63d28', + **kwargs) + + def info(self, path: pathlib.Path) -> Sequence[str]: + return ( + f'{self.name} installed in: {path}', + "Enable by running 'gn args out' and adding this line:", + f' dir_pw_third_party_smartfusion_mss = "{path}"', + ) + + +pw_package.package_manager.register(SmartfusionMss) diff --git a/pw_package/py/pw_package/pigweed_packages.py b/pw_package/py/pw_package/pigweed_packages.py index 59e0919c7..c60468c9b 100644 --- a/pw_package/py/pw_package/pigweed_packages.py +++ b/pw_package/py/pw_package/pigweed_packages.py @@ -27,6 +27,7 @@ from pw_package.packages import micro_ecc # pylint: disable=unused-import from pw_package.packages import nanopb from pw_package.packages import pico_sdk # pylint: disable=unused-import from pw_package.packages import protobuf # pylint: disable=unused-import +from pw_package.packages import smartfusion_mss # pylint: disable=unused-import from pw_package.packages import stm32cube # pylint: disable=unused-import diff --git a/pw_sys_io_emcraft_sf2/BUILD.bazel b/pw_sys_io_emcraft_sf2/BUILD.bazel new file mode 100644 index 000000000..fb10a78c4 --- /dev/null +++ b/pw_sys_io_emcraft_sf2/BUILD.bazel @@ -0,0 +1,39 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +load( + "//pw_build:pigweed.bzl", + "pw_cc_library", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +pw_cc_library( + name = "pw_sys_io_emcraft_sf2", + srcs = [ + "pw_sys_io_emcraft_sf2_private/config.h", + "sys_io_emcraft_sf2.cc", + ], + hdrs = ["public/pw_sys_io_emcraft_sf2/init.h"], + target_compatible_with = [ + "@platforms//os:none", + ], + deps = [ + "//pw_boot_cortex_m:armv7m", + "//pw_preprocessor", + "//pw_sys_io", + ], +) diff --git a/pw_sys_io_emcraft_sf2/BUILD.gn b/pw_sys_io_emcraft_sf2/BUILD.gn new file mode 100644 index 000000000..236722f70 --- /dev/null +++ b/pw_sys_io_emcraft_sf2/BUILD.gn @@ -0,0 +1,60 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/module_config.gni") +import("$dir_pw_build/target_types.gni") +import("$dir_pw_docgen/docs.gni") +import("$dir_pw_third_party/smartfusion_mss/mss.gni") + +declare_args() { + # The build target that overrides the default configuration options for this + # module. This should point to a source set that provides defines through a + # public config (which may -include a file or add defines directly). + pw_sys_io_emcraft_sf2_CONFIG = pw_build_DEFAULT_MODULE_CONFIG +} + +config("public_includes") { + include_dirs = [ "public" ] +} + +pw_source_set("config") { + public_deps = [ pw_sys_io_emcraft_sf2_CONFIG ] + public = [ "pw_sys_io_emcraft_sf2_private/config.h" ] + visibility = [ ":*" ] +} + +pw_source_set("pw_sys_io_emcraft_sf2") { + public_configs = [ ":public_includes" ] + public_deps = [ + "$dir_pw_preprocessor", + "$dir_pw_third_party/smartfusion_mss", + ] + if (dir_pw_third_party_smartfusion_mss != "") { + public_deps += [ "$dir_pw_third_party/smartfusion_mss" ] + } + public = [ "public/pw_sys_io_emcraft_sf2/init.h" ] + sources = [ "sys_io_emcraft_sf2.cc" ] + deps = [ + ":config", + "$dir_pw_status", + "$dir_pw_sys_io:default_putget_bytes", + "$dir_pw_sys_io:facade", + ] +} + +pw_doc_group("docs") { + sources = [ "docs.rst" ] +} diff --git a/pw_sys_io_emcraft_sf2/docs.rst b/pw_sys_io_emcraft_sf2/docs.rst new file mode 100644 index 000000000..66ef6c940 --- /dev/null +++ b/pw_sys_io_emcraft_sf2/docs.rst @@ -0,0 +1,44 @@ +.. _module-pw_sys_io_emcraft_sf2: + +--------------------- +pw_sys_io_emcraft_sf2 +--------------------- + +``pw_sys_io_emcraft_sf2`` implements the ``pw_sys_io`` facade over +UART. + +The Emcraft SF2 sys IO backend provides a UART driver layer that allows +applications built against the ``pw_sys_io`` interface to run on a +SmartFusion/2 chip and do simple input/output via UART. However, this should +work with all Smartfusion/2 variations. + +This backend allows you to configure which UART to use. The point of it is to +provide bare-minimum platform code needed to do UART reads/writes. + +Setup +===== +This module requires relatively minimal setup: + + 1. Write code against the ``pw_sys_io`` facade. + 2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this + backend. + 3. pw_sys_io_Init() provided by this module needs to be called in early boot + to get pw_sys_io into a working state. + 4. Build an executable with a main() function using a toolchain that + supports Cortex-M3. + +.. note:: + This module provides early firmware init, so it will conflict with other + modules that do any early device init. + +Module usage +============ +After building an executable that utilizes this backend, flash the +produced .elf binary to the development board. Then, using a serial +communication terminal like minicom/screen (Linux/Mac) or TeraTerm (Windows), +connect to the device at a baud rate of 57600 (8N1). + +Dependencies +============ + * ``pw_sys_io`` facade + * ``pw_preprocessor`` module diff --git a/pw_sys_io_emcraft_sf2/public/pw_sys_io_emcraft_sf2/init.h b/pw_sys_io_emcraft_sf2/public/pw_sys_io_emcraft_sf2/init.h new file mode 100644 index 000000000..ccfd61e3c --- /dev/null +++ b/pw_sys_io_emcraft_sf2/public/pw_sys_io_emcraft_sf2/init.h @@ -0,0 +1,23 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +#pragma once + +#include "pw_preprocessor/util.h" + +PW_EXTERN_C_START + +// The actual implement of PreMainInit() in sys_io_BACKEND. +void pw_sys_io_Init(void); + +PW_EXTERN_C_END diff --git a/pw_sys_io_emcraft_sf2/pw_sys_io_emcraft_sf2_private/config.h b/pw_sys_io_emcraft_sf2/pw_sys_io_emcraft_sf2_private/config.h new file mode 100644 index 000000000..fb3db3a17 --- /dev/null +++ b/pw_sys_io_emcraft_sf2/pw_sys_io_emcraft_sf2_private/config.h @@ -0,0 +1,22 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#pragma once + +// Defaults to USART1 on the SmartFusion2, but can be overridden. + +// The USART peripheral number to use. (1 for USART1, 2 for USART2, etc.) +#ifndef PW_SYS_IO_EMCRAFT_SF2_USART_NUM +#define PW_SYS_IO_EMCRAFT_SF2_USART_NUM 1 +#endif // PW_SYS_IO_EMCRAFT_SF2_USART_NUM diff --git a/pw_sys_io_emcraft_sf2/sys_io_emcraft_sf2.cc b/pw_sys_io_emcraft_sf2/sys_io_emcraft_sf2.cc new file mode 100644 index 000000000..d94a621b5 --- /dev/null +++ b/pw_sys_io_emcraft_sf2/sys_io_emcraft_sf2.cc @@ -0,0 +1,104 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#include <cinttypes> + +#include "mss_gpio/mss_gpio.h" +#include "mss_uart/mss_uart.h" +#include "pw_preprocessor/concat.h" +#include "pw_status/status.h" +#include "pw_sys_io/sys_io.h" +#include "pw_sys_io_emcraft_sf2_private/config.h" + +namespace { + +// LEDs GPIOs + +constexpr mss_gpio_id_t kDs3LedGPIO = MSS_GPIO_1; +constexpr mss_gpio_id_t kDs4LEDGPIO = MSS_GPIO_2; +constexpr uint32_t kDs3LedMask = MSS_GPIO_1_MASK; +constexpr uint32_t kDs4LedMask = MSS_GPIO_2_MASK; + +constexpr uint32_t kReadDataReady = 0x1u; + +} // namespace + +extern "C" void pw_sys_io_Init() { + // Configure MSS GPIOs. +#if SF2_MSS_NO_BOOTLOADER + MSS_GPIO_init(); +#endif + + MSS_GPIO_config(kDs3LedGPIO, MSS_GPIO_OUTPUT_MODE); + MSS_GPIO_config(kDs4LEDGPIO, MSS_GPIO_OUTPUT_MODE); + // Set LEDs to initial app state + MSS_GPIO_set_outputs(MSS_GPIO_get_outputs() | kDs4LedMask); + + // Initialize the UART0 controller (57600, 8N1) + // Due to a HW eratta in SF2, we need to run at 57600 for + // in-system-programming mode. If we are not upgrading FPGA or flash then we + // can use a faster BAUD. + MSS_UART_init( + &g_mss_uart0, + MSS_UART_57600_BAUD, + MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); +} + +// This whole implementation is very inefficient because it uses the synchronous +// polling UART API and only reads / writes 1 byte at a time. +namespace pw::sys_io { + +Status ReadByte(std::byte* dest) { + while (true) { + if (TryReadByte(dest).ok()) { + return OkStatus(); + } + } +} + +Status TryReadByte(std::byte* dest) { + if (!(g_mss_uart0.hw_reg->LSR & kReadDataReady)) { + return Status::Unavailable(); + } + + *dest = static_cast<std::byte>(g_mss_uart0.hw_reg->RBR); + return OkStatus(); +} + +Status WriteByte(std::byte b) { + // Wait for TX buffer to be empty. When the buffer is empty, we can write + // a value to be dumped out of UART. + const uint8_t pbuff = (uint8_t)b; + + MSS_UART_polled_tx(&g_mss_uart0, &pbuff, 1); + return OkStatus(); +} + +// Writes a string using pw::sys_io, and add newline characters at the end. +StatusWithSize WriteLine(const std::string_view& s) { + size_t chars_written = 0; + StatusWithSize result = WriteBytes(std::as_bytes(std::span(s))); + if (!result.ok()) { + return result; + } + chars_written += result.size(); + + // Write trailing newline. + result = WriteBytes(std::as_bytes(std::span("\r\n", 2))); + chars_written += result.size(); + + return StatusWithSize(OkStatus(), chars_written); +} + +} // namespace pw::sys_io diff --git a/pw_system/BUILD.gn b/pw_system/BUILD.gn index 089fbd1e2..fd5cb5ad8 100644 --- a/pw_system/BUILD.gn +++ b/pw_system/BUILD.gn @@ -16,6 +16,7 @@ import("//build_overrides/pigweed.gni") import("$dir_pigweed/third_party/freertos/freertos.gni") import("$dir_pigweed/third_party/nanopb/nanopb.gni") +import("$dir_pigweed/third_party/smartfusion_mss/mss.gni") import("$dir_pigweed/third_party/stm32cube/stm32cube.gni") import("$dir_pw_build/error.gni") import("$dir_pw_build/facade.gni") @@ -226,6 +227,14 @@ if (dir_pw_third_party_nanopb != "") { dir_pw_third_party_freertos != "") { deps += [ ":system_example($dir_pigweed/targets/stm32f429i_disc1_stm32cube:stm32f429i_disc1_stm32cube.size_optimized)" ] } + if (dir_pw_third_party_smartfusion_mss != "" && + dir_pw_third_party_freertos != "") { + deps += [ + ":system_example($dir_pigweed/targets/emcraft_sf2_som:emcraft_sf2_som.size_optimized)", + ":system_example($dir_pigweed/targets/emcraft_sf2_som:emcraft_sf2_som.speed_optimized)", + ":system_example($dir_pigweed/targets/emcraft_sf2_som:emcraft_sf2_som_debug.debug)", + ] + } } } else { pw_error("system_examples") { diff --git a/targets/emcraft_sf2_som/BUILD.gn b/targets/emcraft_sf2_som/BUILD.gn index 007fa4672..9d778698e 100644 --- a/targets/emcraft_sf2_som/BUILD.gn +++ b/targets/emcraft_sf2_som/BUILD.gn @@ -18,8 +18,10 @@ import("$dir_pw_build/target_types.gni") import("$dir_pw_docgen/docs.gni") import("$dir_pw_malloc/backend.gni") import("$dir_pw_system/system_target.gni") +import("$dir_pw_third_party/smartfusion_mss/mss.gni") import("$dir_pw_tokenizer/backend.gni") import("$dir_pw_toolchain/generate_toolchain.gni") + config("pw_malloc_active") { if (pw_malloc_BACKEND != "") { defines = [ "PW_MALLOC_ACTIVE=1" ] @@ -35,9 +37,9 @@ if (current_toolchain != default_toolchain) { "$dir_pw_malloc", "$dir_pw_preprocessor", "$dir_pw_string", + "$dir_pw_sys_io_emcraft_sf2", "$dir_pw_system", "$dir_pw_third_party/freertos", - "$dir_pw_third_party/smartfusion_mss", ] sources = [ "boot.cc", @@ -51,7 +53,9 @@ if (current_toolchain != default_toolchain) { pw_source_set("sf2_mss_hal_config") { public_configs = [ ":config_includes" ] - public = [ "config/sf2_mss_hal_conf.h" ] + public = + [ "config/sf2_mss_hal_conf.h" ] # SKEYS likely want to put the MDDR + # config by cortex etc stuff here } pw_source_set("sf2_freertos_config") { @@ -61,17 +65,68 @@ if (current_toolchain != default_toolchain) { } } +# Configured for use with a first stage boot loader to configure DDR and +# perform memory remapping. pw_system_target("emcraft_sf2_som") { cpu = PW_SYSTEM_CPU.CORTEX_M3 scheduler = PW_SYSTEM_SCHEDULER.FREERTOS + link_deps = [ "$dir_pigweed/targets/emcraft_sf2_som:pre_init" ] + + build_args = { + pw_log_BACKEND = dir_pw_log_tokenized + pw_tokenizer_GLOBAL_HANDLER_WITH_PAYLOAD_BACKEND = + "$dir_pw_system:log_backend.impl" + pw_third_party_freertos_CONFIG = + "$dir_pigweed/targets/emcraft_sf2_som:sf2_freertos_config" + pw_third_party_freertos_PORT = "$dir_pw_third_party/freertos:arm_cm3" + pw_sys_io_BACKEND = dir_pw_sys_io_emcraft_sf2 + + # Non-debug build for use with the boot loader. + pw_boot_cortex_m_LINK_CONFIG_DEFINES = [ + "PW_BOOT_FLASH_BEGIN=0x00000200", # After vector table. + + # TODO(skeys) Bootloader is capable of loading 16M of uncompressed code + # from SPI flash to external RAM. For now use the allocated eNVM flash + # (256K - Bootloader - InSystemProgrammer = 192K) + "PW_BOOT_FLASH_SIZE=0x30000", + # TODO(pwbug/219): Currently "pw_tokenizer/detokenize_test" requires at + # least 6K bytes in heap when using pw_malloc_freelist. The heap size + # required for tests should be investigated. + "PW_BOOT_HEAP_SIZE=4M", + + # With external RAM remapped, we use the entire internal ram for the + # stack (64K). + "PW_BOOT_MIN_STACK_SIZE=1024K", + + # Using external DDR RAM, we just need to make sure we go past our ROM + # sections. + "PW_BOOT_RAM_BEGIN=0xA1000000", + + # We assume that the bootloader loaded all 16M of text. + "PW_BOOT_RAM_SIZE=48M", + "PW_BOOT_VECTOR_TABLE_BEGIN=0x00000000", + "PW_BOOT_VECTOR_TABLE_SIZE=512", + ] + } +} + +# Debug target configured to work with MSS linker script and startup code. +# TODO(skeys) Add linker script and config for debug builds using SoftConsole. +pw_system_target("emcraft_sf2_som_debug") { + cpu = PW_SYSTEM_CPU.CORTEX_M3 + scheduler = PW_SYSTEM_SCHEDULER.FREERTOS link_deps = [ "$dir_pigweed/targets/emcraft_sf2_som:pre_init" ] + build_args = { pw_log_BACKEND = dir_pw_log_tokenized - pw_tokenizer_GLOBAL_HANDLER_WITH_PAYLOAD_BACKEND = "//pw_system:log" + pw_tokenizer_GLOBAL_HANDLER_WITH_PAYLOAD_BACKEND = + "$dir_pw_system:log_backend.impl" pw_third_party_freertos_CONFIG = "$dir_pigweed/targets/emcraft_sf2_som:sf2_freertos_config" pw_third_party_freertos_PORT = "$dir_pw_third_party/freertos:arm_cm3" + pw_sys_io_BACKEND = dir_pw_sys_io_emcraft_sf2 + pw_boot_cortex_m_LINK_CONFIG_DEFINES = [ "PW_BOOT_FLASH_BEGIN=0x00000200", "PW_BOOT_FLASH_SIZE=200K", diff --git a/targets/emcraft_sf2_som/boot.cc b/targets/emcraft_sf2_som/boot.cc index 284860b2f..bb786c850 100644 --- a/targets/emcraft_sf2_som/boot.cc +++ b/targets/emcraft_sf2_som/boot.cc @@ -17,14 +17,19 @@ #include <array> #include "FreeRTOS.h" +#include "config/sf2_mss_hal_conf.h" +#include "m2sxxx.h" #include "pw_boot_cortex_m/boot.h" #include "pw_malloc/malloc.h" #include "pw_preprocessor/compiler.h" #include "pw_string/util.h" #include "pw_sys_io_emcraft_sf2/init.h" #include "pw_system/init.h" +#include "system_m2sxxx.h" #include "task.h" +#include liberosoc_CONFIG_FILE + namespace { std::array<StackType_t, configMINIMAL_STACK_SIZE> freertos_idle_stack; @@ -68,7 +73,98 @@ extern "C" void vApplicationGetIdleTaskMemory( *pulIdleTaskStackSize = freertos_timer_stack.size(); } -extern "C" void pw_boot_PreStaticMemoryInit() {} +extern "C" void pw_boot_PreStaticMemoryInit() { +#if SF2_MSS_NO_BOOTLOADER + SystemInit(); + // Initialize DDR + // inclusive-language: disable + MDDR->core.ddrc.DYN_SOFT_RESET_CR = 0x0000; + MDDR->core.ddrc.DYN_REFRESH_1_CR = 0x27de; + MDDR->core.ddrc.DYN_REFRESH_2_CR = 0x030f; + MDDR->core.ddrc.DYN_POWERDOWN_CR = 0x0002; + MDDR->core.ddrc.DYN_DEBUG_CR = 0x0000; + MDDR->core.ddrc.MODE_CR = 0x00C1; + MDDR->core.ddrc.ADDR_MAP_BANK_CR = 0x099f; + MDDR->core.ddrc.ECC_DATA_MASK_CR = 0x0000; + MDDR->core.ddrc.ADDR_MAP_COL_1_CR = 0x3333; + MDDR->core.ddrc.ADDR_MAP_COL_2_CR = 0xffff; + MDDR->core.ddrc.ADDR_MAP_ROW_1_CR = 0x7777; + MDDR->core.ddrc.ADDR_MAP_ROW_2_CR = 0x0fff; + MDDR->core.ddrc.INIT_1_CR = 0x0001; + MDDR->core.ddrc.CKE_RSTN_CYCLES_CR[0] = 0x4242; + MDDR->core.ddrc.CKE_RSTN_CYCLES_CR[1] = 0x0008; + MDDR->core.ddrc.INIT_MR_CR = 0x0033; + MDDR->core.ddrc.INIT_EMR_CR = 0x0020; + MDDR->core.ddrc.INIT_EMR2_CR = 0x0000; + MDDR->core.ddrc.INIT_EMR3_CR = 0x0000; + MDDR->core.ddrc.DRAM_BANK_TIMING_PARAM_CR = 0x00c0; + MDDR->core.ddrc.DRAM_RD_WR_LATENCY_CR = 0x0023; + MDDR->core.ddrc.DRAM_RD_WR_PRE_CR = 0x0235; + MDDR->core.ddrc.DRAM_MR_TIMING_PARAM_CR = 0x0064; + MDDR->core.ddrc.DRAM_RAS_TIMING_CR = 0x0108; + MDDR->core.ddrc.DRAM_RD_WR_TRNARND_TIME_CR = 0x0178; + MDDR->core.ddrc.DRAM_T_PD_CR = 0x0033; + MDDR->core.ddrc.DRAM_BANK_ACT_TIMING_CR = 0x1947; + MDDR->core.ddrc.ODT_PARAM_1_CR = 0x0010; + MDDR->core.ddrc.ODT_PARAM_2_CR = 0x0000; + MDDR->core.ddrc.ADDR_MAP_COL_3_CR = 0x3300; + MDDR->core.ddrc.MODE_REG_RD_WR_CR = 0x0000; + MDDR->core.ddrc.MODE_REG_DATA_CR = 0x0000; + MDDR->core.ddrc.PWR_SAVE_1_CR = 0x0514; + MDDR->core.ddrc.PWR_SAVE_2_CR = 0x0000; + MDDR->core.ddrc.ZQ_LONG_TIME_CR = 0x0200; + MDDR->core.ddrc.ZQ_SHORT_TIME_CR = 0x0040; + MDDR->core.ddrc.ZQ_SHORT_INT_REFRESH_MARGIN_CR[0] = 0x0012; + MDDR->core.ddrc.ZQ_SHORT_INT_REFRESH_MARGIN_CR[1] = 0x0002; + MDDR->core.ddrc.PERF_PARAM_1_CR = 0x4000; + MDDR->core.ddrc.HPR_QUEUE_PARAM_CR[0] = 0x80f8; + MDDR->core.ddrc.HPR_QUEUE_PARAM_CR[1] = 0x0007; + MDDR->core.ddrc.LPR_QUEUE_PARAM_CR[0] = 0x80f8; + MDDR->core.ddrc.LPR_QUEUE_PARAM_CR[1] = 0x0007; + MDDR->core.ddrc.WR_QUEUE_PARAM_CR = 0x0200; + MDDR->core.ddrc.PERF_PARAM_2_CR = 0x0001; + MDDR->core.ddrc.PERF_PARAM_3_CR = 0x0000; + MDDR->core.ddrc.DFI_RDDATA_EN_CR = 0x0003; + MDDR->core.ddrc.DFI_MIN_CTRLUPD_TIMING_CR = 0x0003; + MDDR->core.ddrc.DFI_MAX_CTRLUPD_TIMING_CR = 0x0040; + MDDR->core.ddrc.DFI_WR_LVL_CONTROL_CR[0] = 0x0000; + MDDR->core.ddrc.DFI_WR_LVL_CONTROL_CR[1] = 0x0000; + MDDR->core.ddrc.DFI_RD_LVL_CONTROL_CR[0] = 0x0000; + MDDR->core.ddrc.DFI_RD_LVL_CONTROL_CR[1] = 0x0000; + MDDR->core.ddrc.DFI_CTRLUPD_TIME_INTERVAL_CR = 0x0309; + MDDR->core.ddrc.AXI_FABRIC_PRI_ID_CR = 0x0000; + MDDR->core.ddrc.ECC_INT_CLR_REG = 0x0000; + + MDDR->core.phy.LOOPBACK_TEST_CR = 0x0000; + MDDR->core.phy.CTRL_SLAVE_RATIO_CR = 0x0080; + MDDR->core.phy.DATA_SLICE_IN_USE_CR = 0x0003; + MDDR->core.phy.DQ_OFFSET_CR[0] = 0x00000000; + MDDR->core.phy.DQ_OFFSET_CR[2] = 0x0000; + MDDR->core.phy.DLL_LOCK_DIFF_CR = 0x000B; + MDDR->core.phy.FIFO_WE_SLAVE_RATIO_CR[0] = 0x0040; + MDDR->core.phy.FIFO_WE_SLAVE_RATIO_CR[1] = 0x0401; + MDDR->core.phy.FIFO_WE_SLAVE_RATIO_CR[2] = 0x4010; + MDDR->core.phy.FIFO_WE_SLAVE_RATIO_CR[3] = 0x0000; + MDDR->core.phy.LOCAL_ODT_CR = 0x0001; + MDDR->core.phy.RD_DQS_SLAVE_RATIO_CR[0] = 0x0040; + MDDR->core.phy.RD_DQS_SLAVE_RATIO_CR[1] = 0x0401; + MDDR->core.phy.RD_DQS_SLAVE_RATIO_CR[2] = 0x4010; + MDDR->core.phy.WR_DATA_SLAVE_RATIO_CR[0] = 0x0040; + MDDR->core.phy.WR_DATA_SLAVE_RATIO_CR[1] = 0x0401; + MDDR->core.phy.WR_DATA_SLAVE_RATIO_CR[2] = 0x4010; + MDDR->core.phy.WR_RD_RL_CR = 0x0021; + MDDR->core.phy.RDC_WE_TO_RE_DELAY_CR = 0x0003; + MDDR->core.phy.USE_FIXED_RE_CR = 0x0001; + MDDR->core.phy.USE_RANK0_DELAYS_CR = 0x0001; + MDDR->core.phy.CONFIG_CR = 0x0009; + MDDR->core.phy.DYN_RESET_CR = 0x01; + MDDR->core.ddrc.DYN_SOFT_RESET_CR = 0x01; + // inclusive-language: enable + // Wait for config + while ((MDDR->core.ddrc.DDRC_SR) == 0x0000) { + } +#endif +} extern "C" void pw_boot_PreStaticConstructorInit() { // TODO(skeys) add "#if no_bootLoader" and the functions needed for init. diff --git a/targets/emcraft_sf2_som/config/sf2_mss_hal_conf.h b/targets/emcraft_sf2_som/config/sf2_mss_hal_conf.h index 2f16d2e40..0e82d6856 100644 --- a/targets/emcraft_sf2_som/config/sf2_mss_hal_conf.h +++ b/targets/emcraft_sf2_som/config/sf2_mss_hal_conf.h @@ -14,8 +14,12 @@ #pragma once +#if (MSS_SYS_MDDR_CONFIG_BY_CORTEX == 1) +#error "Please turn off DDR initialization! See the comment in this file above." +#endif + #define HAL_GPIO_MODULE_ENABLED -#include "mss_gpio.h" +#include "mss_gpio/mss_gpio.h" #define HAL_UART_MODULE_ENABLED -#include "mss_uart.h" +#include "mss_uart/mss_uart.h" diff --git a/third_party/smartfusion_mss/BUILD.bazel b/third_party/smartfusion_mss/BUILD.bazel new file mode 100644 index 000000000..bf4dfa0d7 --- /dev/null +++ b/third_party/smartfusion_mss/BUILD.bazel @@ -0,0 +1,40 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +load( + "//pw_build:pigweed.bzl", + "pw_cc_library", +) + +# Ready-made configurations +liberosoc_configs = [ + ("default", "configs/config_default.h"), + ("debug", "configs/config_debug.h"), +] + +# Config targets. +[ + pw_cc_library( + name = "%s_config" % config_name, + hdrs = [ + config_header, + "configs/config_pigweed_common.h", + ], + copts = ["-Dmss_CONFIG_FILE=\"%s\"" % config_header], + includes = ["."], + ) + for config_name, config_header in liberosoc_configs +] + +# TODO(skeys): Add build recipe for the library. diff --git a/third_party/smartfusion_mss/BUILD.gn b/third_party/smartfusion_mss/BUILD.gn new file mode 100644 index 000000000..2e3c10888 --- /dev/null +++ b/third_party/smartfusion_mss/BUILD.gn @@ -0,0 +1,112 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import("//build_overrides/pigweed.gni") +import("$dir_pw_build/linker_script.gni") +import("$dir_pw_build/target_types.gni") +import("$dir_pw_third_party/smartfusion_mss/mss.gni") + +declare_args() { + pw_target_smartfusion2_LINK_CONFIG_DEFINES = [] +} + +if (dir_pw_third_party_smartfusion_mss != "") { + # The list currently includes all source files for build. + smartfusion_mss_sources = [ + "exported_firmware/CMSIS/startup_gcc/startup_m2sxxx.S", + "exported_firmware/CMSIS/system_m2sxxx.c", + "exported_firmware/drivers/mss_can/mss_can.c", + "exported_firmware/drivers/mss_ethernet_mac/m88e1340_phy.c", + "exported_firmware/drivers/mss_ethernet_mac/mss_ethernet_mac.c", + "exported_firmware/drivers/mss_gpio/mss_gpio.c", + "exported_firmware/drivers/mss_hpdma/mss_hpdma.c", + "exported_firmware/drivers/mss_i2c/mss_i2c.c", + "exported_firmware/drivers/mss_nvm/mss_nvm.c", + "exported_firmware/drivers/mss_rtc/mss_rtc.c", + "exported_firmware/drivers/mss_spi/mss_spi.c", + "exported_firmware/drivers/mss_sys_services/mss_comblk.c", + "exported_firmware/drivers/mss_sys_services/mss_sys_services.c", + "exported_firmware/drivers/mss_uart/mss_uart.c", + "exported_firmware/drivers/mss_usb/mss_usb_common_cif.c", + "exported_firmware/drivers/mss_usb/mss_usb_device.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_cdc.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_cif.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_hid.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_msd.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_printer.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_rndis.c", + "exported_firmware/drivers/mss_usb/mss_usb_device_vendor.c", + "exported_firmware/drivers/mss_usb/mss_usb_host.c", + "exported_firmware/drivers/mss_usb/mss_usb_host_cif.c", + "exported_firmware/drivers/mss_usb/mss_usb_host_msc.c", + "exported_firmware/drivers_config/sys_config/sys_config.c", + ] + + liberosoc_configs = [ + { + name = "default" + config_header = "configs/config_default.h" + }, + { + name = "debug" + config_header = "configs/config_debug.h" + }, + ] + + foreach(ele, liberosoc_configs) { + config_name = ele.name + "_config" + config(config_name) { + # Custom config file is specified by macro liberosoc_CONFIG_FILE + # for liberosoc + defines = [ "liberosoc_CONFIG_FILE=\"${ele.config_header}\"" ] + } + + srcset_name = ele.name + "_config_srcset" + pw_source_set(srcset_name) { + public = [ + "configs/config_pigweed_common.h", + ele.config_header, + ] + public_configs = [ + ":${config_name}", + ":smartfusion_mss_common_config", + ] + } + } + + config("smartfusion_mss_common_config") { + include_dirs = [ + "$dir_pw_third_party_smartfusion_mss/exported_firmware/CMSIS/V4.5/Include", + "$dir_pw_third_party_smartfusion_mss/exported_firmware/drivers", + "$dir_pw_third_party_smartfusion_mss/exported_firmware/CMSIS", + "$dir_pw_third_party/smartfusion_mss", + ] + cflags = [ + "-Wno-error=cast-qual", + "-Wno-error=redundant-decls", + "-w", + ] + } + + pw_source_set("smartfusion_mss") { + sources = [] + foreach(source, smartfusion_mss_sources) { + sources += [ "$dir_pw_third_party_smartfusion_mss/" + source ] + } + public_deps = [ ":${pw_third_party_smartfusion_mss_CONFIG}_config_srcset" ] + } +} else { + group("smartfusion_mss") { + } +} diff --git a/third_party/smartfusion_mss/README.md b/third_party/smartfusion_mss/README.md new file mode 100644 index 000000000..7532545e2 --- /dev/null +++ b/third_party/smartfusion_mss/README.md @@ -0,0 +1,6 @@ +# LiberoSoC Library + +The folder provides build scripts and configuration recipes for building +the SmartFusion2 Microcontroller Subsystem library. The source code needs to be downloaded by the user, or +via the support in pw_package "pw package install sf2mss". For gn build, +set `dir_pw_third_party_smartfusion_mss` to point to the path of the source code. diff --git a/third_party/smartfusion_mss/configs/config_debug.h b/third_party/smartfusion_mss/configs/config_debug.h new file mode 100644 index 000000000..7eb69608e --- /dev/null +++ b/third_party/smartfusion_mss/configs/config_debug.h @@ -0,0 +1,19 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#pragma once + +#include "configs/config_pigweed_common.h" + +#define SF2_MSS_NO_BOOTLOADER 1 diff --git a/third_party/smartfusion_mss/configs/config_default.h b/third_party/smartfusion_mss/configs/config_default.h new file mode 100644 index 000000000..30aee591f --- /dev/null +++ b/third_party/smartfusion_mss/configs/config_default.h @@ -0,0 +1,17 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#pragma once + +#include "configs/config_pigweed_common.h" diff --git a/third_party/smartfusion_mss/configs/config_pigweed_common.h b/third_party/smartfusion_mss/configs/config_pigweed_common.h new file mode 100644 index 000000000..3f4f6ea45 --- /dev/null +++ b/third_party/smartfusion_mss/configs/config_pigweed_common.h @@ -0,0 +1,20 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// Some common configs for using mbedtls in Pigweed. These include disabling of +// file system, socket and linux/windows specific features. +// See include/mbedtls/config.h for a detail explanation of these +// configurations. + +#pragma once diff --git a/third_party/smartfusion_mss/mss.gni b/third_party/smartfusion_mss/mss.gni new file mode 100644 index 000000000..dd971781a --- /dev/null +++ b/third_party/smartfusion_mss/mss.gni @@ -0,0 +1,24 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +declare_args() { + # If compiling backends with mbedtls, this variable is set to the path to the + # mbedtls source code. When set, a pw_source_set for the mbedtls library is + # created at "$dir_pw_third_party/mbedtls". + dir_pw_third_party_smartfusion_mss = "" + + # configuration for mbedtls. Can be one of `mbedtls_configs` in the BUILD.gn + # file + pw_third_party_smartfusion_mss_CONFIG = "default" +} |