diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a160691 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +#ignore +build/* +out/* +debug/* +.vscode/* +CMakeUserPresets.json + +#allow +!debug/*.jdebug diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f70a36b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cmake"] + path = cmake + url = git@github.com:embedded-office/cmake-scripts.git diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d673ff9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] - 23.08.2022 + +### Add + +- Add quickstart application running on my ST Nucleo-144 Board with a STM32F446ZE. +- Provide driver for CAN1 on STM32F4xx devices +- Provide driver for FMPI2C on STM32F4xx devices +- Provide driver for TIM2 on STM32F4xx devices + +[unreleased]: https://github.com/embedded-office/canopen-stack/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/embedded-office/canopen-stack/releases/tag/v1.0.0 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..42827c9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,41 @@ +#***************************************************************************** +# Copyright 2020 Embedded Office GmbH & Co. KG +# +# 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 +# +# http://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. +#****************************************************************************** + +#--- +# preamble +# +cmake_minimum_required(VERSION 3.20) # buildPresets is introduced in 3.20 +project(canopen-stm32f4xx) +enable_language(C ASM) + +#--- +# project wide setup +# +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED OFF) +set(CMAKE_C_EXTENSIONS OFF) + +#--- +# externally provided content +# +include(cmake/CPM.cmake) +add_subdirectory(dependencies) + +#--- +# main targets built by this project +# +add_subdirectory(src) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..c7d01e9 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,31 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "build/${presetName}", + "toolchainFile": "cmake/toolchain-gcc_cortex-m4.cmake", + "cacheVariables": { + "CPM_SOURCE_CACHE": "build/_deps" + } + }, + { + "name": "debug", + "inherits": "base", + "displayName": "GCC-ARM (Cortex-M4) - Debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "release", + "inherits": "base", + "displayName": "GCC-ARM (Cortex-M4) - Release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..13e6ceb --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ + +# Repository Structure + +``` ++- cmake : submodule referencing the repository 'cmake-scripts' ++- debug : debugger configurations ++- dependencies : external managed components ++- src : canopen example project +| +- app : application source code +| +- config : configuration of startup and HAL +| +- driver : canopen target specific drivers +``` + +# CANopen Demo for STM32F4xx Microcontrollers + +This project demonstrates the usage of the free [CANopen Stack Project](https://canopen-stack.org). The included application is the Quickstart - "*CANopen clock application*", described in detail at the [project website](https://canopen-stack.org/latest/start/quickstart/). + +We use the [STM32Cube MCU Full Package for the STM32F4 series](https://github.com/STMicroelectronics/STM32CubeF4) made by ST Microelectronics as the low-level foundation for the chip configuration, the startup, and the driver implementation. With some slight enhancements to match our CMake build environment, we provide a small source code package out of a [forked repository](https://github.com/embedded-office/STM32CubeF4) for integration in our demo projects. + +My hardware setup for this development and testing is: +- the [Nucleo-144 STM32F446](https://www.st.com/en/evaluation-tools/nucleo-f446ze.html) +- a CAN tranceiver [Waveshare SN65HVD230 CAN Board](https://www.waveshare.com/sn65hvd230-can-board.htm) +- an Atmel [AT24C256 I2C EEPROM](https://www.microchip.com/en-us/product/AT24C256C) +- the [KVaser USBcan II HS/HS](https://www.kvaser.com/product/kvaser-usbcan-ii-hshs/) for CAN bus monitoring +- the [Saleae Logic Analyzer](https://www.saleae.com/) for low level measurements + +The wiring is pretty simple. For your reference, see the essence in a small diagram: + +![Collection of relevant hardware information](doc/image/nucleo144-can-connection.jpg) + +For details, check: +- the [User Manual for STM32 Nucleo-144 boards](https://www.st.com/resource/en/user_manual/um1974-stm32-nucleo144-boards-mb1137-stmicroelectronics.pdf) +- the [STM32F446xx Datasheet](https://www.st.com/resource/en/datasheet/stm32f446re.pdf) +- the [Reference Manual for STM32446xx MCUs](https://www.st.com/resource/en/reference_manual/dm00135183-stm32f446xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf) + +## Usage + +### Development Tools + +Download and install these free tools for your system: + +- Install the build tools [Cmake](https://cmake.org/) +- Install the build system [Ninja](https://ninja-build.org/) +- Install the cross-compiler [Arm GNU Toolchain](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain) + +*Note: on my Windows machine, I use the [Ozone debugger](https://www.segger.com/downloads/jlink/) with the free [ST-Link Reflash Utility](https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/) from Segger. The generated debug information in the ELF image should be suitable for all other debuggers, too.* + + +### Submodule: cmake-scripts + +The basic collection of re-usable CMake scripts are placed as a Git submodule in the directory `/cmake`. The Git submodule is a reference to a specific commit hash of the Git repository [cmake-scripts](https://github.com/embedded-office/cmake-scripts). + +*Small reminder: when cloning this repository you need to initialize and update the submodules:* + +```bash +# clone Git repository and initialize submodules: +$ git clone --recurse-submodules + +# or, in case you have already cloned the Git repository: +$ git clone +$ cd +$ git submodule update --init +``` + + +### Project dependencies + +We use two extern managed components to build our target application. When using external projects it is important to define naming rules for exported CMake `target` names to eliminate name collisions. + +For the example application in this repository we use: + +- Target [stm32f4xx-hal](https://github.com/embedded-office/STM32CubeF4) - a fork of the STM32CubeF4 package with enhancements for usage with CMake +- Target [canopen-stack](https://github.com/embedded-office/canopen-stack) - the free CANopen Stack, provided by Embedded Office + +*Note: The used versions of the dependencies are defined in the directory `/dependencies`.* + + +## Build instructions + +Just type in the project root directory: + +```bash +# configure the project for debugging +$ cmake --preset debug + +# build the application for your target +$ cmake --build ./build/debug +``` + +The target image file `canopen-stm32f4xx.elf` and the corresponding map file `canopen-stm32f4xx.map` are generated and placed in `out/debug`. + + +## Load and Executing on target + +For the Ozone debugger there is a basic debugger configuration `debug/ozone.jdebug`, which loads the image to the target and runs to function `main()`. + +- power up your STM32F446 nucleo board +- double-click the debugger configuration +- watch the uploading and running to main ... + +... and have fun playing with this tiny CANopen quickstart application :) + +If you encounter any improvement in descriptions, project setup, build system, implementation or documentation, please rise an issue and help me to simplify the life of Embedded software engineers. diff --git a/cmake b/cmake new file mode 160000 index 0000000..8f8cfd6 --- /dev/null +++ b/cmake @@ -0,0 +1 @@ +Subproject commit 8f8cfd6425621c8a62835f743045369efddea824 diff --git a/debug/ozone.jdebug b/debug/ozone.jdebug new file mode 100644 index 0000000..e612863 --- /dev/null +++ b/debug/ozone.jdebug @@ -0,0 +1,347 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +File : quickstart.jdebug +Created : 18 Jul 2022 15:08 +Ozone Version : V3.26h +*/ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // + // Dialog-generated settings + // + Project.AddPathSubstitute ("../", "$(ProjectDir)"); + Project.SetDevice ("STM32F769NI"); + Project.SetHostIF ("USB", ""); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("4 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); + // + // User settings + // + File.Open ("../out/debug/canopen-stm32f4xx.elf"); +} + +/********************************************************************* +* +* OnStartupComplete +* +* Function description +* Called when program execution has reached/passed +* the startup completion point. Optional. +* +********************************************************************** +*/ +//void OnStartupComplete (void) { +//} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging an application in RAM on a Cortex-M target device. +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// VectorTableAddr = Elf.GetBaseAddr(); +// // +// // Set up initial stack pointer +// // +// if (VectorTableAddr != 0xFFFFFFFF) { +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// } +// // +// // Set up entry point PC +// // +// PC = Elf.GetEntryPointPC(); +// +// if (PC != 0xFFFFFFFF) { +// Target.SetReg("PC", PC); +// } else if (VectorTableAddr != 0xFFFFFFFF) { +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } else { +// Util.Error("Project file error: failed to set entry point PC", 1); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +** +********************************************************************** +*/ +void AfterTargetReset (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetConnect (void) { +//} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} + +/********************************************************************* +* +* BeforeTargetResume +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetResume (void) { +//} + +/********************************************************************* +* +* OnSnapshotLoad +* +* Function description +* Called upon loading a snapshot. Optional. +* +* Additional information +* This function is used to restore the target state in cases +* where values cannot simply be written to the target. +* Typical use: GPIO clock needs to be enabled, before +* GPIO is configured. +* +********************************************************************** +*/ +//void OnSnapshotLoad (void) { +//} + +/********************************************************************* +* +* OnSnapshotSave +* +* Function description +* Called upon saving a snapshot. Optional. +* +* Additional information +* This function is usually used to save values of the target +* state which can either not be trivially read, +* or need to be restored in a specific way or order. +* Typically use: Memory Mapped Registers, +* such as PLL and GPIO configuration. +* +********************************************************************** +*/ +//void OnSnapshotSave (void) { +//} + +/********************************************************************* +* +* OnError +* +* Function description +* Called when an error ocurred. Optional. +* +********************************************************************** +*/ +//void OnError (void) { +//} + +/********************************************************************* +* +* AfterProjectLoad +* +* Function description +* After Project load routine. Optional. +* +********************************************************************** +*/ +//void AfterProjectLoad (void) { +//} + +/********************************************************************* +* +* _SetupTarget +* +* Function description +* Setup the target. +* Called by AfterTargetReset() and AfterTargetDownload(). +* +* Auto-generated function. May be overridden by Ozone. +* +********************************************************************** +*/ +void _SetupTarget(void) { + unsigned int SP; + unsigned int PC; + unsigned int VectorTableAddr; + + VectorTableAddr = Elf.GetBaseAddr(); + // + // Set up initial stack pointer + // + SP = Target.ReadU32(VectorTableAddr); + if (SP != 0xFFFFFFFF) { + Target.SetReg("SP", SP); + } + // + // Set up entry point PC + // + PC = Elf.GetEntryPointPC(); + if (PC != 0xFFFFFFFF) { + Target.SetReg("PC", PC); + } else { + Util.Error("Project script error: failed to set up entry point PC", 1); + } +} \ No newline at end of file diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt new file mode 100644 index 0000000..e55b750 --- /dev/null +++ b/dependencies/CMakeLists.txt @@ -0,0 +1,52 @@ +#***************************************************************************** +# Copyright 2020 Embedded Office GmbH & Co. KG +# +# 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 +# +# http://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. +#****************************************************************************** + +#--- +# Add the CANopen Stack project from Embedded Office +# +set(CO_TARGET "canopen-stack") +set(CO_PROJECT "embedded-office/canopen-stack") +set(CO_VERSION "4.4.0") +CPMAddPackage( + NAME canopen-stack + URL https://github.com/${CO_PROJECT}/releases/download/v${CO_VERSION}/${CO_TARGET}-src.zip + VERSION ${CO_VERSION} +) + +#--- +# Add the ST Microelectronics HAL drivers with some small patches +# - to get a smaller package size +# - eliminate compilation errors with -Wpedantic +# +set(HAL_TARGET "stm32f4xx-hal") +set(HAL_PROJECT "embedded-office/STM32CubeF4") +set(HAL_VERSION "1.27.1-p2") +# +# configure component build for: +# +set(HAL_DEVICE "STM32F446xx") +set(HAL_CONFIG "${CMAKE_SOURCE_DIR}/src/config") +CPMAddPackage( + NAME ${HAL_TARGET} + URL https://github.com/${HAL_PROJECT}/releases/download/v${HAL_VERSION}/${HAL_TARGET}-src.zip + VERSION ${HAL_VERSION} + OPTIONS + "STM_HAL_CONF_DIR ${HAL_CONFIG}" + "STM_HAL_DEVICE ${HAL_DEVICE}" + "STM_USE_HAL_DRIVER true" + "STM_USE_FULL_LL_DRIVER true" + "STM_USE_FULL_ASSERT false" +) diff --git a/doc/image/nucleo144-can-connection.jpg b/doc/image/nucleo144-can-connection.jpg new file mode 100644 index 0000000..5182ae2 Binary files /dev/null and b/doc/image/nucleo144-can-connection.jpg differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..afda756 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,57 @@ +#***************************************************************************** +# Copyright 2020 Embedded Office GmbH & Co. KG +# +# 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 +# +# http://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. +#****************************************************************************** + +#--- +# define the application executable +# +add_executable(canopen-stm32f4xx) + +#--- +# application with object dictionary and driver functions +# +target_sources(canopen-stm32f4xx + PRIVATE + # application + app/clock_app.c + app/clock_hw.c + app/clock_spec.c + # system startup + config/startup_main.c + config/startup_stm32f446xx.s + config/system_stm32f4xx.c + # driver + driver/stm32f4xx-hal/drv_can_can1.c + driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24C256.c + driver/stm32f4xx-hal/drv_timer_tim2.c +) + +target_include_directories(canopen-stm32f4xx + PRIVATE + app + config + driver/stm32f4xx-hal +) + +#--- +# specify the dependencies for this application +# +target_link_libraries(canopen-stm32f4xx canopen-stack stm32f4xx-hal) + +#--- +# specify the linker file and the resulting image +# +setLinkerScript(canopen-stm32f4xx "${CMAKE_CURRENT_SOURCE_DIR}/config/stm32f446zehx_flash") +setOutfile(canopen-stm32f4xx "canopen-stm32f4xx") diff --git a/src/app/clock_app.c b/src/app/clock_app.c new file mode 100644 index 0000000..b747de0 --- /dev/null +++ b/src/app/clock_app.c @@ -0,0 +1,119 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "clock_app.h" + +/****************************************************************************** +* PRIVATE VARIABLES +******************************************************************************/ + +/* Allocate a global CANopen node object */ +CO_NODE Clk; + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +/* timer callback function */ +static void AppClock(void *p_arg) +{ + CO_NODE *node; + CO_OBJ *od_sec; + CO_OBJ *od_min; + CO_OBJ *od_hr; + uint8_t second; + uint8_t minute; + uint32_t hour; + + /* For flexible usage (not needed, but nice to show), we use the argument + * as reference to the CANopen node object. If no node is given, we ignore + * the function call by returning immediatelly. + */ + node = (CO_NODE *)p_arg; + if (node == 0) { + return; + } + + /* Main functionality: when we are in operational mode, we get the current + * clock values out of the object dictionary, increment the seconds and + * update all clock values in the object dictionary. + */ + if (CONmtGetMode(&node->Nmt) == CO_OPERATIONAL) { + + od_sec = CODictFind(&node->Dict, CO_DEV(0x2100, 3)); + od_min = CODictFind(&node->Dict, CO_DEV(0x2100, 2)); + od_hr = CODictFind(&node->Dict, CO_DEV(0x2100, 1)); + + COObjRdValue(od_sec, node, (void *)&second, sizeof(second)); + COObjRdValue(od_min, node, (void *)&minute, sizeof(minute)); + COObjRdValue(od_hr , node, (void *)&hour , sizeof(hour) ); + + second++; + if (second >= 60) { + second = 0; + minute++; + } + if (minute >= 60) { + minute = 0; + hour++; + } + + COObjWrValue(od_hr , node, (void *)&hour , sizeof(hour) ); + COObjWrValue(od_min, node, (void *)&minute, sizeof(minute)); + COObjWrValue(od_sec, node, (void *)&second, sizeof(second)); + } +} + +/****************************************************************************** +* PUBLIC FUNCTIONS +******************************************************************************/ + +void AppStart(void) +{ + uint32_t ticks; + + /* Initialize the CANopen stack. Stop execution if an + * error is detected. + */ + CONodeInit(&Clk, &AppSpec); + if (CONodeGetErr(&Clk) != CO_ERR_NONE) { + while(1); /* error not handled */ + } + + /* Use CANopen software timer to create a cyclic function + * call to the callback function 'AppClock()' with a period + * of 1s (equal: 1000ms). + */ + ticks = COTmrGetTicks(&Clk.Tmr, 1000, CO_TMR_UNIT_1MS); + COTmrCreate(&Clk.Tmr, 0, ticks, AppClock, &Clk); + + /* Start the CANopen node and set it automatically to + * NMT mode: 'OPERATIONAL'. + */ + CONodeStart(&Clk); + CONmtSetMode(&Clk.Nmt, CO_OPERATIONAL); + + /* In the background loop we execute elapsed action + * callback functions. + */ + while (1) { + COTmrProcess(&Clk.Tmr); + } +} diff --git a/src/app/clock_app.h b/src/app/clock_app.h new file mode 100644 index 0000000..4d2047d --- /dev/null +++ b/src/app/clock_app.h @@ -0,0 +1,46 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +#ifndef CLOCK_APP_H_ +#define CLOCK_APP_H_ + +#ifdef __cplusplus /* for compatibility with C++ environments */ +extern "C" { +#endif + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "clock_spec.h" + +/****************************************************************************** +* EXTERNAL SYMBOLS +******************************************************************************/ + +extern CO_NODE Clk; + +/****************************************************************************** +* PUBLIC FUNCTIONS +******************************************************************************/ + +void AppStart(void); + +#ifdef __cplusplus /* for compatibility with C++ environments */ +} +#endif + +#endif /* CLOCK_APP_H_ */ diff --git a/src/app/clock_hw.c b/src/app/clock_hw.c new file mode 100644 index 0000000..279566f --- /dev/null +++ b/src/app/clock_hw.c @@ -0,0 +1,57 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "clock_hw.h" +#include "clock_app.h" + +/****************************************************************************** +* PUBLIC VARIABLES +******************************************************************************/ + +/* Select the drivers for your application. For possible + * selections, see the directory /drivers. + */ +struct CO_IF_DRV_T AppDriver = { + &STM32F4xx_CAN1_CanDriver, + &STM32F4xx_TIM2_TimerDriver, + &STM32F4xx_FMPI2C1_AT24C256_NvmDriver +}; + +/****************************************************************************** +* PUBLIC FUNCTIONS +******************************************************************************/ + +/* ST HAL CAN receive interrupt callback */ +void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) +{ + /* process CAN frame with CANopen protocol */ + if (hcan->Instance == CAN1) { + CONodeProcess(&Clk); + }; +} + +/* ST HAL TIM2 overflow interrupt callback */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htmr) +{ + /* collect elapsed timed actions */ + if (htmr->Instance == TIM2) { + COTmrService(&Clk.Tmr); + } +} diff --git a/src/app/clock_hw.h b/src/app/clock_hw.h new file mode 100644 index 0000000..147d8c3 --- /dev/null +++ b/src/app/clock_hw.h @@ -0,0 +1,45 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +#ifndef CLOCK_HW_H_ +#define CLOCK_HW_H_ + +#ifdef __cplusplus /* for compatibility with C++ environments */ +extern "C" { +#endif + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "stm32f4xx_hal.h" /* for connecting interrupts */ + + /* select application drivers: */ +#include "drv_can_can1.h" /* CAN driver (CAN1) */ +#include "drv_timer_tim2.h" /* Timer driver (TIM2) */ +#include "drv_nvm_fmpi2c1_at24c256.h" /* NVM driver (AT24C256 via FMPI2C1) */ + +/****************************************************************************** +* PUBLIC SYMBOLS +******************************************************************************/ + +extern struct CO_IF_DRV_T AppDriver; + +#ifdef __cplusplus /* for compatibility with C++ environments */ +} +#endif + +#endif /* CLOCK_HW_H_ */ diff --git a/src/app/clock_spec.c b/src/app/clock_spec.c new file mode 100644 index 0000000..7bfcb5a --- /dev/null +++ b/src/app/clock_spec.c @@ -0,0 +1,139 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "clock_spec.h" +#include "clock_hw.h" + +/****************************************************************************** +* PRIVATE DEFINES +******************************************************************************/ + +/* Define some default values for our CANopen node: */ +#define APP_NODE_ID 1u /* CANopen node ID */ +#define APP_BAUDRATE 250000u /* CAN baudrate */ +#define APP_TMR_N 16u /* Number of software timers */ +#define APP_TICKS_PER_SEC 1000000u /* Timer clock frequency in Hz */ +#define APP_OBJ_N 128u /* Object dictionary max size */ + +/****************************************************************************** +* PRIVATE VARIABLES +******************************************************************************/ + +/* allocate variables for dynamic runtime value in RAM */ +static uint8_t Obj1001_00_08 = 0; + +static uint16_t Obj1017_00_10 = 0; + +static uint32_t Obj2100_01_20 = 0; +static uint8_t Obj2100_02_08 = 0; +static uint8_t Obj2100_03_08 = 0; + +/* allocate variables for constant values in FLASH */ +const uint32_t Obj1000_00_20 = 0x00000000L; + +const uint32_t Obj1014_00_20 = 0x00000080L; + +const uint32_t Obj1018_01_20 = 0x00000000L; +const uint32_t Obj1018_02_20 = 0x00000000L; +const uint32_t Obj1018_03_20 = 0x00000000L; +const uint32_t Obj1018_04_20 = 0x00000000L; + +const uint32_t Obj1200_01_20 = CO_COBID_SDO_REQUEST(); +const uint32_t Obj1200_02_20 = CO_COBID_SDO_RESPONSE(); + +const uint32_t Obj1800_01_20 = CO_COBID_TPDO_DEFAULT(0); + +const uint32_t Obj1A00_01_20 = CO_LINK(0x2100, 0x01, 32); +const uint32_t Obj1A00_02_20 = CO_LINK(0x2100, 0x02, 8); +const uint32_t Obj1A00_03_20 = CO_LINK(0x2100, 0x03, 8); + +/* define the static object dictionary */ +static struct CO_OBJ_T ClockOD[APP_OBJ_N] = { + {CO_KEY(0x1000, 0, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1000_00_20)}, + {CO_KEY(0x1001, 0, CO_OBJ_____R_), CO_TUNSIGNED8 , (CO_DATA)(&Obj1001_00_08)}, + {CO_KEY(0x1014, 0, CO_OBJ__N__R_), CO_TEMCY_ID, (CO_DATA)(&Obj1014_00_20)}, + {CO_KEY(0x1017, 0, CO_OBJ_____RW), CO_THB_PROD, (CO_DATA)(&Obj1017_00_10)}, + + {CO_KEY(0x1018, 0, CO_OBJ_D___R_), CO_TUNSIGNED8 , (CO_DATA)(4) }, + {CO_KEY(0x1018, 1, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1018_01_20)}, + {CO_KEY(0x1018, 2, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1018_02_20)}, + {CO_KEY(0x1018, 3, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1018_03_20)}, + {CO_KEY(0x1018, 4, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1018_04_20)}, + + {CO_KEY(0x1200, 0, CO_OBJ_D___R_), CO_TUNSIGNED8 , (CO_DATA)(2) }, + {CO_KEY(0x1200, 1, CO_OBJ__N__R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1200_01_20)}, + {CO_KEY(0x1200, 2, CO_OBJ__N__R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1200_02_20)}, + + {CO_KEY(0x1800, 0, CO_OBJ_D___R_), CO_TUNSIGNED8 , (CO_DATA)(2) }, + {CO_KEY(0x1800, 1, CO_OBJ__N__R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1800_01_20)}, + {CO_KEY(0x1800, 2, CO_OBJ_D___R_), CO_TUNSIGNED8 , (CO_DATA)(254) }, + + {CO_KEY(0x1A00, 0, CO_OBJ_D___R_), CO_TUNSIGNED8 , (CO_DATA)(3) }, + {CO_KEY(0x1A00, 1, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1A00_01_20)}, + {CO_KEY(0x1A00, 2, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1A00_02_20)}, + {CO_KEY(0x1A00, 3, CO_OBJ_____R_), CO_TUNSIGNED32, (CO_DATA)(&Obj1A00_03_20)}, + + {CO_KEY(0x2100, 0, CO_OBJ_D___R_), CO_TUNSIGNED8 , (CO_DATA)(3) }, + {CO_KEY(0x2100, 1, CO_OBJ____PR_), CO_TUNSIGNED32, (CO_DATA)(&Obj2100_01_20)}, + {CO_KEY(0x2100, 2, CO_OBJ____PR_), CO_TUNSIGNED8 , (CO_DATA)(&Obj2100_02_08)}, + {CO_KEY(0x2100, 3, CO_OBJ___APR_), CO_TUNSIGNED8 , (CO_DATA)(&Obj2100_03_08)}, + + CO_OBJ_DICT_ENDMARK /* mark end of used objects */ +}; + +/* Each software timer needs some memory for managing + * the lists and states of the timed action events. + */ +static CO_TMR_MEM TmrMem[APP_TMR_N]; + +/* Each SDO server needs memory for the segmented or + * block transfer requests. + */ +static uint8_t SdoSrvMem[CO_SSDO_N * CO_SDO_BUF_BYTE]; + +/* Specify the EMCY error codes with the corresponding + * error register bit. There is a collection of defines + * for the predefined emergency codes CO_EMCY_CODE... + * and for the error register bits CO_EMCY_REG... for + * readability. You can use plain numbers, too. + */ +static CO_EMCY_TBL AppEmcyTbl[APP_ERR_ID_NUM] = { + { CO_EMCY_REG_GENERAL, CO_EMCY_CODE_HW_ERR } /* APP_ERR_ID_EEPROM */ +}; + +/****************************************************************************** +* PUBLIC VARIABLES +******************************************************************************/ + +/* Collect all node specification settings in a single + * structure for initializing the node easily. + */ +struct CO_NODE_SPEC_T AppSpec = { + APP_NODE_ID, /* default Node-Id */ + APP_BAUDRATE, /* default Baudrate */ + &ClockOD[0], /* pointer to object dictionary */ + APP_OBJ_N, /* object dictionary max length */ + &AppEmcyTbl[0], /* EMCY code & register bit table */ + &TmrMem[0], /* pointer to timer memory blocks */ + APP_TMR_N, /* number of timer memory blocks */ + APP_TICKS_PER_SEC, /* timer clock frequency in Hz */ + &AppDriver, /* select drivers for application */ + &SdoSrvMem[0] /* SDO Transfer Buffer Memory */ +}; diff --git a/src/app/clock_spec.h b/src/app/clock_spec.h new file mode 100644 index 0000000..7f0c707 --- /dev/null +++ b/src/app/clock_spec.h @@ -0,0 +1,51 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +#ifndef CLOCK_SPEC_H_ +#define CLOCK_SPEC_H_ + +#ifdef __cplusplus /* for compatibility with C++ environments */ +extern "C" { +#endif + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "co_core.h" + +/****************************************************************************** +* PUBLIC DEFINES +******************************************************************************/ + +/* Specify the EMCY-IDs for the application */ +enum EMCY_CODES { + APP_ERR_ID_EEPROM = 0, + + APP_ERR_ID_NUM /* number of EMCY error codes in application */ +}; + +/****************************************************************************** +* PUBLIC SYMBOLS +******************************************************************************/ + +extern struct CO_NODE_SPEC_T AppSpec; + +#ifdef __cplusplus /* for compatibility with C++ environments */ +} +#endif + +#endif /* CLOCK_SPEC_H_ */ diff --git a/src/config/startup_main.c b/src/config/startup_main.c new file mode 100644 index 0000000..23eba26 --- /dev/null +++ b/src/config/startup_main.c @@ -0,0 +1,108 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "stm32f4xx_hal.h" +#include "clock_app.h" + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void SystemClock_Config(void); + +/****************************************************************************** +* PUBLIC FUNCTIONS +******************************************************************************/ + +void _init(void) {;} /* stub function, called in __libc_init_array() */ + +void SysTick_Handler(void) /* ST HAL system tick as 1ms timebase */ +{ + HAL_IncTick(); +} + +void HAL_MspInit(void) /* ST HAL lowlevel initialization callback */ +{ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_RCC_SYSCFG_CLK_ENABLE(); +} + +int main(void) /* main entry point for controller startup */ +{ + HAL_Init(); /* must be the first call in main() */ + SystemClock_Config(); /* setup the clock tree (activate the PLL) */ + + AppStart(); /* ok, we are ready to start the application */ +} + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +/* This function is generated with STM32CubeMX with the default clock + * settings for the STM32F446 microcontroller. When you intend to port + * this example application to a different microcontroller, please + * don't forget to check (or re-create) this essential clock setup! + */ +static void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + HAL_StatusTypeDef ret = HAL_OK; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + + /* Input frequency HSE = 25MHz */ + /* SYSCLK = ((HSE / 15) * 216) / 2 = 180 MHz */ + RCC_OscInitStruct.PLL.PLLM = 15; + RCC_OscInitStruct.PLL.PLLN = 216; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); + if (ret != HAL_OK) { + while(1); /* error not handled */ + } + + /* Activate the Over-Drive mode */ + ret = HAL_PWREx_EnableOverDrive(); + if (ret != HAL_OK) { + while(1); /* error not handled */ + } + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* SYSCLK : 180 MHz */ + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /* FCLK, HCLK: 180 MHz */ + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; /* APB1: 45 MHz, APB1-TMR: 90 MHz */ + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; /* APB2: 90 MHz, APB2-TMR: 180 MHz */ + ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + if (ret != HAL_OK) { + while(1); /* error not handled */ + } +} diff --git a/src/config/startup_stm32f446xx.s b/src/config/startup_stm32f446xx.s new file mode 100644 index 0000000..97404b7 --- /dev/null +++ b/src/config/startup_stm32f446xx.s @@ -0,0 +1,535 @@ +/** + ****************************************************************************** + * @file startup_stm32f446xx.s + * @author MCD Application Team + * @brief STM32F446xx Devices vector table for GCC based toolchains. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss + +FillZerobss: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + +/* Call the clock system initialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + /* External Interrupts */ + .word WWDG_IRQHandler /* Window WatchDog */ + .word PVD_IRQHandler /* PVD through EXTI Line detection */ + .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ + .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ + .word FLASH_IRQHandler /* FLASH */ + .word RCC_IRQHandler /* RCC */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ + .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ + .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ + .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ + .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ + .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ + .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ + .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ + .word CAN1_TX_IRQHandler /* CAN1 TX */ + .word CAN1_RX0_IRQHandler /* CAN1 RX0 */ + .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ + .word CAN1_SCE_IRQHandler /* CAN1 SCE */ + .word EXTI9_5_IRQHandler /* External Line[9:5]s */ + .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ + .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ + .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word EXTI15_10_IRQHandler /* External Line[15:10]s */ + .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ + .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ + .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ + .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ + .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ + .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */ + .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ + .word FMC_IRQHandler /* FMC */ + .word SDIO_IRQHandler /* SDIO */ + .word TIM5_IRQHandler /* TIM5 */ + .word SPI3_IRQHandler /* SPI3 */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ + .word TIM7_IRQHandler /* TIM7 */ + .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ + .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ + .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ + .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ + .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word CAN2_TX_IRQHandler /* CAN2 TX */ + .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ + .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ + .word CAN2_SCE_IRQHandler /* CAN2 SCE */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ + .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ + .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ + .word USART6_IRQHandler /* USART6 */ + .word I2C3_EV_IRQHandler /* I2C3 event */ + .word I2C3_ER_IRQHandler /* I2C3 error */ + .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ + .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ + .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ + .word OTG_HS_IRQHandler /* USB OTG HS */ + .word DCMI_IRQHandler /* DCMI */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word SPI4_IRQHandler /* SPI4 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word SAI1_IRQHandler /* SAI1 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word SAI2_IRQHandler /* SAI2 */ + .word QUADSPI_IRQHandler /* QuadSPI */ + .word CEC_IRQHandler /* CEC */ + .word SPDIF_RX_IRQHandler /* SPDIF RX */ + .word FMPI2C1_EV_IRQHandler /* FMPI2C 1 Event */ + .word FMPI2C1_ER_IRQHandler /* FMPI2C 1 Error */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_IRQHandler + .thumb_set PVD_IRQHandler,Default_Handler + + .weak TAMP_STAMP_IRQHandler + .thumb_set TAMP_STAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Stream0_IRQHandler + .thumb_set DMA1_Stream0_IRQHandler,Default_Handler + + .weak DMA1_Stream1_IRQHandler + .thumb_set DMA1_Stream1_IRQHandler,Default_Handler + + .weak DMA1_Stream2_IRQHandler + .thumb_set DMA1_Stream2_IRQHandler,Default_Handler + + .weak DMA1_Stream3_IRQHandler + .thumb_set DMA1_Stream3_IRQHandler,Default_Handler + + .weak DMA1_Stream4_IRQHandler + .thumb_set DMA1_Stream4_IRQHandler,Default_Handler + + .weak DMA1_Stream5_IRQHandler + .thumb_set DMA1_Stream5_IRQHandler,Default_Handler + + .weak DMA1_Stream6_IRQHandler + .thumb_set DMA1_Stream6_IRQHandler,Default_Handler + + .weak ADC_IRQHandler + .thumb_set ADC_IRQHandler,Default_Handler + + .weak CAN1_TX_IRQHandler + .thumb_set CAN1_TX_IRQHandler,Default_Handler + + .weak CAN1_RX0_IRQHandler + .thumb_set CAN1_RX0_IRQHandler,Default_Handler + + .weak CAN1_RX1_IRQHandler + .thumb_set CAN1_RX1_IRQHandler,Default_Handler + + .weak CAN1_SCE_IRQHandler + .thumb_set CAN1_SCE_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_TIM9_IRQHandler + .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM10_IRQHandler + .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM11_IRQHandler + .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak OTG_FS_WKUP_IRQHandler + .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler + + .weak TIM8_BRK_TIM12_IRQHandler + .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler + + .weak TIM8_UP_TIM13_IRQHandler + .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler + + .weak TIM8_TRG_COM_TIM14_IRQHandler + .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler + + .weak TIM8_CC_IRQHandler + .thumb_set TIM8_CC_IRQHandler,Default_Handler + + .weak DMA1_Stream7_IRQHandler + .thumb_set DMA1_Stream7_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak SDIO_IRQHandler + .thumb_set SDIO_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak TIM6_DAC_IRQHandler + .thumb_set TIM6_DAC_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak DMA2_Stream0_IRQHandler + .thumb_set DMA2_Stream0_IRQHandler,Default_Handler + + .weak DMA2_Stream1_IRQHandler + .thumb_set DMA2_Stream1_IRQHandler,Default_Handler + + .weak DMA2_Stream2_IRQHandler + .thumb_set DMA2_Stream2_IRQHandler,Default_Handler + + .weak DMA2_Stream3_IRQHandler + .thumb_set DMA2_Stream3_IRQHandler,Default_Handler + + .weak DMA2_Stream4_IRQHandler + .thumb_set DMA2_Stream4_IRQHandler,Default_Handler + + .weak CAN2_TX_IRQHandler + .thumb_set CAN2_TX_IRQHandler,Default_Handler + + .weak CAN2_RX0_IRQHandler + .thumb_set CAN2_RX0_IRQHandler,Default_Handler + + .weak CAN2_RX1_IRQHandler + .thumb_set CAN2_RX1_IRQHandler,Default_Handler + + .weak CAN2_SCE_IRQHandler + .thumb_set CAN2_SCE_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_IRQHandler,Default_Handler + + .weak DMA2_Stream5_IRQHandler + .thumb_set DMA2_Stream5_IRQHandler,Default_Handler + + .weak DMA2_Stream6_IRQHandler + .thumb_set DMA2_Stream6_IRQHandler,Default_Handler + + .weak DMA2_Stream7_IRQHandler + .thumb_set DMA2_Stream7_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak OTG_HS_EP1_OUT_IRQHandler + .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler + + .weak OTG_HS_EP1_IN_IRQHandler + .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler + + .weak OTG_HS_WKUP_IRQHandler + .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler + + .weak OTG_HS_IRQHandler + .thumb_set OTG_HS_IRQHandler,Default_Handler + + .weak DCMI_IRQHandler + .thumb_set DCMI_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak SAI2_IRQHandler + .thumb_set SAI2_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak SPDIF_RX_IRQHandler + .thumb_set SPDIF_RX_IRQHandler,Default_Handler + + .weak FMPI2C1_EV_IRQHandler + .thumb_set FMPI2C1_EV_IRQHandler,Default_Handler + + .weak FMPI2C1_ER_IRQHandler + .thumb_set FMPI2C1_ER_IRQHandler,Default_Handler diff --git a/src/config/stm32f446zehx_flash.lds b/src/config/stm32f446zehx_flash.lds new file mode 100644 index 0000000..0323acb --- /dev/null +++ b/src/config/stm32f446zehx_flash.lds @@ -0,0 +1,187 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : STM32CubeMX +** +** Abstract : Linker script for STM32F446ZEHx series +** 512Kbytes FLASH and 128Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed “as is,” without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2019 STMicroelectronics

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of STMicroelectronics nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/src/config/stm32f4xx_hal_conf.h b/src/config/stm32f4xx_hal_conf.h new file mode 100644 index 0000000..c0c4484 --- /dev/null +++ b/src/config/stm32f4xx_hal_conf.h @@ -0,0 +1,500 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f4xx_hal_conf.h. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +#define HAL_CEC_MODULE_ENABLED +#define HAL_CRYP_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DCMI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_DMA2D_MODULE_ENABLED +#define HAL_ETH_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_NOR_MODULE_ENABLED +#define HAL_PCCARD_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_SDRAM_MODULE_ENABLED +#define HAL_HASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_SMBUS_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_DSI_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_QSPI_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +#define HAL_SAI_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_IRDA_MODULE_ENABLED +#define HAL_SMARTCARD_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED +#define HAL_FMPI2C_MODULE_ENABLED +#define HAL_FMPSMBUS_MODULE_ENABLED +#define HAL_SPDIFRX_MODULE_ENABLED +#define HAL_DFSDM_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_FMPSMBUS_REGISTER_CALLBACKS 0U /* FMPSMBUS register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE 1528U /* ETH Max buffer size for receive */ +#define ETH_TX_BUF_SIZE 1528U /* ETH Max buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 1U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_FMPSMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_fmpsmbus.h" +#endif /* HAL_FMPSMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + + diff --git a/src/config/system_stm32f4xx.c b/src/config/system_stm32f4xx.c new file mode 100644 index 0000000..3bd40f7 --- /dev/null +++ b/src/config/system_stm32f4xx.c @@ -0,0 +1,747 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + + +#include "stm32f4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\ + STM32F412Zx || STM32F412Vx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +/* #define DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\ + STM32F479xx */ + +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate the vector table + anywhere in Flash or Sram, else the vector table is kept at the automatic + remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line if you need to relocate your vector Table + in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 16000000; +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + /* Configure the Vector Table location -------------------------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM) +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; + + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */ + RCC->AHB1ENR |= 0x000001F8; + + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + FMC_Bank5_6->SDCR[0] = 0x000019E4; + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ + FMC_Bank5_6->SDCMR = 0x00000073; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ + FMC_Bank5_6->SDCMR = 0x00046014; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ + + (void)(tmp); +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ +#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#if defined (DATA_IN_ExtSDRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + +#if defined(STM32F446xx) + /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface + clock */ + RCC->AHB1ENR |= 0x0000007D; +#else + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001F8; +#endif /* STM32F446xx */ + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + +#if defined(STM32F446xx) + /* Connect PAx pins to FMC Alternate function */ + GPIOA->AFR[0] |= 0xC0000000; + GPIOA->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOA->MODER |= 0x00008000; + /* Configure PDx pins speed to 50 MHz */ + GPIOA->OSPEEDR |= 0x00008000; + /* Configure PDx pins Output type to push-pull */ + GPIOA->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOA->PUPDR |= 0x00000000; + + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] |= 0x00CC0000; + GPIOC->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOC->MODER |= 0x00000A00; + /* Configure PDx pins speed to 50 MHz */ + GPIOC->OSPEEDR |= 0x00000A00; + /* Configure PDx pins Output type to push-pull */ + GPIOC->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOC->PUPDR |= 0x00000000; +#endif /* STM32F446xx */ + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + /* Configure and enable SDRAM bank1 */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCR[0] = 0x00001954; +#else + FMC_Bank5_6->SDCR[0] = 0x000019E4; +#endif /* STM32F446xx */ + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x000000F3; +#else + FMC_Bank5_6->SDCMR = 0x00000073; +#endif /* STM32F446xx */ + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x00044014; +#else + FMC_Bank5_6->SDCMR = 0x00046014; +#endif /* STM32F446xx */ + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; +#if defined(STM32F446xx) + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1)); +#else + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); +#endif /* STM32F446xx */ + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); +#endif /* DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) + +#if defined(DATA_IN_ExtSRAM) +/*-- GPIOs Configuration -----------------------------------------------------*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x000000C0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00085AAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000CAFFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FMC/FSMC Configuration --------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\ + || defined(STM32F412Zx) || defined(STM32F412Vx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN); + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */ + +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */ + (void)(tmp); +} +#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/src/driver/stm32f4xx-hal/drv_can_can1.c b/src/driver/stm32f4xx-hal/drv_can_can1.c new file mode 100644 index 0000000..56eaf1a --- /dev/null +++ b/src/driver/stm32f4xx-hal/drv_can_can1.c @@ -0,0 +1,235 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "drv_can_can1.h" +#include "stm32f4xx_hal.h" + +/****************************************************************************** +* PRIVATE TYPE DEFINITION +******************************************************************************/ + +typedef struct BAUDRATE_TBL_T { + uint32_t Baudrate; + uint32_t Prescaler; + uint32_t SyncJumpWidth; + uint32_t TimeSeg1; + uint32_t TimeSeg2; +} BAUDRATE_TBL; + +typedef struct PIN_ASSIGN_T { + GPIO_TypeDef *Port; + uint16_t Pin; + uint8_t Alternate; +} PIN_ASSIGN; + +/****************************************************************************** +* PRIVATE DEFINES +******************************************************************************/ + +/* default pin assignment: CAN_RX -> PB8, CAN_TX -> PB9 */ +#define CAN1_PIN_RX_SEL 0 +#define CAN1_PIN_TX_SEL 0 + +/****************************************************************************** +* PRIVATE VARIABLES +******************************************************************************/ + +static PIN_ASSIGN Can1Pin_Rx[] = { + { GPIOA, GPIO_PIN_11, GPIO_AF9_CAN1 }, /* #0: PA11 */ + { GPIOB, GPIO_PIN_8, GPIO_AF9_CAN1 }, /* #1: PB8 */ + { GPIOD, GPIO_PIN_0, GPIO_AF9_CAN1 }, /* #3: PD0 */ + { GPIOH, GPIO_PIN_14, GPIO_AF9_CAN1 }, /* #4: PH14 */ +}; +static PIN_ASSIGN Can1Pin_Tx[] = { + { GPIOA, GPIO_PIN_12, GPIO_AF9_CAN1 }, /* #0: PA12 */ + { GPIOB, GPIO_PIN_9, GPIO_AF9_CAN1 }, /* #1: PB9 */ + { GPIOD, GPIO_PIN_1, GPIO_AF9_CAN1 }, /* #2: PD1 */ + { GPIOH, GPIO_PIN_13, GPIO_AF9_CAN1 } /* #3: PH13 */ +}; + +static BAUDRATE_TBL BaudrateTbl[] = { + { 10000, 300, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 20000, 150, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 50000, 60, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 125000, 24, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 250000, 12, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 500000, 6, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 800000, 4, CAN_SJW_1TQ, CAN_BS1_13TQ, CAN_BS2_3TQ }, /* SP: 82,4%, ERR: -0,74% */ + { 1000000, 3, CAN_SJW_1TQ, CAN_BS1_15TQ, CAN_BS2_2TQ }, /* SP: 88,9%, ERR: 0% */ + { 0, 0, 0, 0, 0 } +}; + +static CAN_HandleTypeDef DrvCan1; + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void DrvCanInit (void); +static void DrvCanEnable (uint32_t baudrate); +static int16_t DrvCanSend (CO_IF_FRM *frm); +static int16_t DrvCanRead (CO_IF_FRM *frm); +static void DrvCanReset (void); +static void DrvCanClose (void); + +/****************************************************************************** +* PUBLIC VARIABLE +******************************************************************************/ + +const CO_IF_CAN_DRV STM32F4xx_CAN1_CanDriver = { + DrvCanInit, + DrvCanEnable, + DrvCanRead, + DrvCanSend, + DrvCanReset, + DrvCanClose +}; + +/****************************************************************************** +* PUBLIC FUNCTIONS +******************************************************************************/ + +/* ST HAL CAN Receive Interrupt Handler */ +void CAN1_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&DrvCan1); +} + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void DrvCanInit(void) +{ + GPIO_InitTypeDef gpio = {0}; + + /* Peripheral clocks enable (for simplicity: enable all possible ports) */ + __HAL_RCC_CAN1_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + /* setup CAN RX and TX pins */ + gpio.Mode = GPIO_MODE_AF_PP; + gpio.Pull = GPIO_NOPULL; + gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio.Alternate = Can1Pin_Rx[CAN1_PIN_RX_SEL].Alternate; + gpio.Pin = Can1Pin_Rx[CAN1_PIN_RX_SEL].Pin; + HAL_GPIO_Init(Can1Pin_Rx[CAN1_PIN_RX_SEL].Port, &gpio); + gpio.Alternate = Can1Pin_Rx[CAN1_PIN_TX_SEL].Alternate; + gpio.Pin = Can1Pin_Tx[CAN1_PIN_TX_SEL].Pin; + HAL_GPIO_Init(Can1Pin_Tx[CAN1_PIN_TX_SEL].Port, &gpio); + + /* CAN interrupt init */ + HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); +} + +static void DrvCanEnable(uint32_t baudrate) +{ + uint8_t idx = 0; + + /* find the given baudrate in baudrate table */ + while (BaudrateTbl[idx].Baudrate != 0) { + if (baudrate == BaudrateTbl[idx].Baudrate) { + break; + } + idx++; + } + if (baudrate != BaudrateTbl[idx].Baudrate) { + while(1); /* error not handled */ + } + + /* can controller mode */ + DrvCan1.Instance = CAN1; + DrvCan1.Init.Mode = CAN_MODE_NORMAL; + + /* baudrate settings */ + DrvCan1.Init.Prescaler = BaudrateTbl[idx].Prescaler; + DrvCan1.Init.SyncJumpWidth = BaudrateTbl[idx].SyncJumpWidth; + DrvCan1.Init.TimeSeg1 = BaudrateTbl[idx].TimeSeg1; + DrvCan1.Init.TimeSeg2 = BaudrateTbl[idx].TimeSeg2; + + /* feature select */ + DrvCan1.Init.TimeTriggeredMode = DISABLE; + DrvCan1.Init.AutoBusOff = DISABLE; + DrvCan1.Init.AutoWakeUp = DISABLE; + DrvCan1.Init.AutoRetransmission = DISABLE; + DrvCan1.Init.ReceiveFifoLocked = DISABLE; + DrvCan1.Init.TransmitFifoPriority = DISABLE; + HAL_CAN_Init(&DrvCan1); + HAL_CAN_Start(&DrvCan1); +} + +static int16_t DrvCanSend(CO_IF_FRM *frm) +{ + HAL_StatusTypeDef result; + CAN_TxHeaderTypeDef frmHead; + uint32_t mailbox; + + /* RTR is not supported */ + frmHead.RTR = 0; + + /* extended identifiers are not supported */ + frmHead.ExtId = 0; + frmHead.IDE = 0; + + /* fill identifier, DLC and data payload in transmit buffer */ + frmHead.StdId = frm->Identifier; + frmHead.DLC = frm->DLC; + result = HAL_CAN_AddTxMessage(&DrvCan1, &frmHead, &frm->Data[0], &mailbox); + if (result != HAL_OK) { + return (-1); + } + return (0u); +} + +static int16_t DrvCanRead (CO_IF_FRM *frm) +{ + HAL_StatusTypeDef err; + CAN_RxHeaderTypeDef frmHead; + uint8_t frmData[8] = { 0 }; + uint8_t n; + + err = HAL_CAN_GetRxMessage(&DrvCan1, CAN_RX_FIFO0, &frmHead, &frmData[0]); + if (err != HAL_OK) { + return (-1); + } + + /* fill CAN frame on success */ + frm->Identifier = frmHead.StdId; + frm->DLC = frmHead.DLC; + for (n = 0; n < 8; n++) { + frm->Data[n] = frmData[n]; + } + return (frm->DLC); +} + +static void DrvCanReset(void) +{ + HAL_CAN_Init(&DrvCan1); + HAL_CAN_Start(&DrvCan1); +} + +static void DrvCanClose(void) +{ + HAL_CAN_Stop(&DrvCan1); +} diff --git a/src/driver/stm32f4xx-hal/drv_can_can1.h b/src/driver/stm32f4xx-hal/drv_can_can1.h new file mode 100644 index 0000000..ec46d9c --- /dev/null +++ b/src/driver/stm32f4xx-hal/drv_can_can1.h @@ -0,0 +1,40 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +#ifndef DRV_CAN1_STM32F7XX_H_ +#define DRV_CAN1_STM32F7XX_H_ + +#ifdef __cplusplus /* for compatibility with C++ environments */ +extern "C" { +#endif + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "co_if.h" + +/****************************************************************************** +* PUBLIC SYMBOLS +******************************************************************************/ + +extern const CO_IF_CAN_DRV STM32F4xx_CAN1_CanDriver; + +#ifdef __cplusplus /* for compatibility with C++ environments */ +} +#endif + +#endif diff --git a/src/driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24c256.c b/src/driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24c256.c new file mode 100644 index 0000000..bdb2755 --- /dev/null +++ b/src/driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24c256.c @@ -0,0 +1,274 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "drv_nvm_fmpi2c1_at24C256.h" +#include "stm32f4xx_hal.h" + +/****************************************************************************** +* PRIVATE TYPE DEFINITION +******************************************************************************/ + +typedef struct PIN_ASSIGN_T { + GPIO_TypeDef *Port; + uint16_t Pin; + uint8_t Alternate; +} PIN_ASSIGN; + +/****************************************************************************** +* PRIVATE DEFINES +******************************************************************************/ + +#define EEPROM_ADDRESS (uint16_t)0xA0 /* address of I2C device bit 1..7 */ +#define EEPROM_TIMEOUT (uint32_t)1000 /* timeout for each transfer: 1s */ +#define EEPROM_PAGE_SIZE (uint16_t)64 /* EEPROM page size */ +#define EEPROM_ACK_POLLING 1000 /* retry on ack polling */ + +/* default pin assignment: FMPI2C_SCL -> PD14, FMPI2C1_SDA -> PD15 */ +#define FMPI2C1_PIN_SCL_SEL 2 +#define FMPI2C1_PIN_SDA_SEL 2 + +/****************************************************************************** +* PRIVATE VARIABLES +******************************************************************************/ + +static PIN_ASSIGN FMPI2C1Pin_Scl[] = { + { GPIOC, GPIO_PIN_6, GPIO_AF4_FMPI2C1 }, /* #0: PC6 */ + { GPIOD, GPIO_PIN_12, GPIO_AF4_FMPI2C1 }, /* #1: PD12 */ + { GPIOD, GPIO_PIN_14, GPIO_AF4_FMPI2C1 }, /* #2: PD14 */ + { GPIOF, GPIO_PIN_14, GPIO_AF4_FMPI2C1 } /* #3: PF14 */ +}; +static PIN_ASSIGN FMPI2C1Pin_Sda[] = { + { GPIOC, GPIO_PIN_7, GPIO_AF4_FMPI2C1 }, /* #0: PC7 */ + { GPIOD, GPIO_PIN_13, GPIO_AF4_FMPI2C1 }, /* #1: PD13 */ + { GPIOD, GPIO_PIN_15, GPIO_AF4_FMPI2C1 }, /* #2: PD15 */ + { GPIOF, GPIO_PIN_15, GPIO_AF4_FMPI2C1 } /* #3: PF15 */ +}; + +static FMPI2C_HandleTypeDef DrvFPMI2CBus; + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void DrvNvmInit (void); +static uint32_t DrvNvmRead (uint32_t start, uint8_t *buffer, uint32_t size); +static uint32_t DrvNvmWrite (uint32_t start, uint8_t *buffer, uint32_t size); + +/****************************************************************************** +* PUBLIC VARIABLE +******************************************************************************/ + +const CO_IF_NVM_DRV STM32F4xx_FMPI2C1_AT24C256_NvmDriver = { + DrvNvmInit, + DrvNvmRead, + DrvNvmWrite +}; + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void DrvNvmInit(void) +{ + HAL_StatusTypeDef err; + GPIO_InitTypeDef gpio = {0}; + RCC_PeriphCLKInitTypeDef pclk = {0}; + + /* Peripheral clocks enable */ + pclk.PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1; + pclk.Fmpi2c1ClockSelection = RCC_FMPI2C1CLKSOURCE_APB; + err = HAL_RCCEx_PeriphCLKConfig(&pclk); + if (err != HAL_OK) { + while(1); /* error not handled */ + } + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + + /* FMPI2C1 GPIO Configuration */ + gpio.Mode = GPIO_MODE_AF_OD; + gpio.Pull = GPIO_NOPULL; + gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio.Alternate = FMPI2C1Pin_Scl[FMPI2C1_PIN_SCL_SEL].Alternate; + gpio.Pin = FMPI2C1Pin_Scl[FMPI2C1_PIN_SCL_SEL].Pin; + HAL_GPIO_Init(FMPI2C1Pin_Scl[FMPI2C1_PIN_SCL_SEL].Port, &gpio); + gpio.Alternate = FMPI2C1Pin_Sda[FMPI2C1_PIN_SDA_SEL].Alternate; + gpio.Pin = FMPI2C1Pin_Sda[FMPI2C1_PIN_SDA_SEL].Pin; + HAL_GPIO_Init(FMPI2C1Pin_Sda[FMPI2C1_PIN_SDA_SEL].Port, &gpio); + + DrvFPMI2CBus.Instance = FMPI2C1; + DrvFPMI2CBus.Init.Timing = 0x0020081B; + DrvFPMI2CBus.Init.OwnAddress1 = 0; + DrvFPMI2CBus.Init.AddressingMode = FMPI2C_ADDRESSINGMODE_7BIT; + DrvFPMI2CBus.Init.DualAddressMode = FMPI2C_DUALADDRESS_DISABLE; + DrvFPMI2CBus.Init.OwnAddress2 = 0; + DrvFPMI2CBus.Init.OwnAddress2Masks = FMPI2C_OA2_NOMASK; + DrvFPMI2CBus.Init.GeneralCallMode = FMPI2C_GENERALCALL_DISABLE; + DrvFPMI2CBus.Init.NoStretchMode = FMPI2C_NOSTRETCH_DISABLE; + err = HAL_FMPI2C_Init(&DrvFPMI2CBus); + if (err != HAL_OK) { + while(1); /* error not handled */ + } + + /** Configure Analogue filter */ + err = HAL_FMPI2CEx_ConfigAnalogFilter(&DrvFPMI2CBus, FMPI2C_ANALOGFILTER_ENABLE); + if (err != HAL_OK) { + while(1); /* error not handled */ + } + + /** I2C Fast mode Plus enable */ + HAL_FMPI2CEx_EnableFastModePlus(FMPI2C_FASTMODEPLUS_SCL); + HAL_FMPI2CEx_EnableFastModePlus(FMPI2C_FASTMODEPLUS_SDA); +} + +static uint32_t DrvNvmRead(uint32_t start, uint8_t *buffer, uint32_t size) +{ + HAL_StatusTypeDef err; + uint32_t result = 0; + uint16_t memStart = (uint16_t)start; + uint16_t memSize = (uint16_t)size; + uint8_t *memData = buffer; + + while (memSize > EEPROM_PAGE_SIZE) { + err = HAL_FMPI2C_Mem_Read( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + memStart, + I2C_MEMADD_SIZE_16BIT, + memData, + EEPROM_PAGE_SIZE, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + memStart += EEPROM_PAGE_SIZE; + memSize -= EEPROM_PAGE_SIZE; + memData += EEPROM_PAGE_SIZE; + result += EEPROM_PAGE_SIZE; + } + err = HAL_FMPI2C_Mem_Read( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + memStart, + I2C_MEMADD_SIZE_16BIT, + memData, + memSize, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + result += memSize; + + return (result); +} + +static uint32_t DrvNvmWrite(uint32_t start, uint8_t *buffer, uint32_t size) +{ + HAL_StatusTypeDef err; + uint32_t result = 0; + uint16_t memStart = (uint16_t)start; + uint16_t memSize = (uint16_t)size; + uint8_t *memData = buffer; + uint16_t memPart = 0; + + /* write data up to the next block boundary */ + memPart = EEPROM_PAGE_SIZE - (memStart % EEPROM_PAGE_SIZE); + if ((memPart < memSize) && + (memPart > 0 )) { + err = HAL_FMPI2C_Mem_Write( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + memStart, + I2C_MEMADD_SIZE_16BIT, + memData, + memPart, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + memStart += memPart; + memData += memPart; + memSize -= memPart; + result += memPart; + /* ACK polling during EEPROM internal write operations */ + err = HAL_FMPI2C_IsDeviceReady( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + EEPROM_ACK_POLLING, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + } + + /* write all full blocks */ + while (memSize > EEPROM_PAGE_SIZE) { + err = HAL_FMPI2C_Mem_Write( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + memStart, + I2C_MEMADD_SIZE_16BIT, + memData, + EEPROM_PAGE_SIZE, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + memStart += EEPROM_PAGE_SIZE; + memData += EEPROM_PAGE_SIZE; + memSize -= EEPROM_PAGE_SIZE; + result += EEPROM_PAGE_SIZE; + /* ACK polling during EEPROM internal write operations */ + err = HAL_FMPI2C_IsDeviceReady( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + EEPROM_ACK_POLLING, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + } + + /* write the last partly filled block */ + if (memSize > 0) { + err = HAL_FMPI2C_Mem_Write( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + memStart, + I2C_MEMADD_SIZE_16BIT, + memData, + memSize, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + result += memSize; + /* ACK polling during EEPROM internal write operations */ + err = HAL_FMPI2C_IsDeviceReady( + &DrvFPMI2CBus, + EEPROM_ADDRESS, + EEPROM_ACK_POLLING, + EEPROM_TIMEOUT); + if (err != HAL_OK) { + return (result); + } + } + return (result); +} diff --git a/src/driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24c256.h b/src/driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24c256.h new file mode 100644 index 0000000..8647ff9 --- /dev/null +++ b/src/driver/stm32f4xx-hal/drv_nvm_fmpi2c1_at24c256.h @@ -0,0 +1,40 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +#ifndef DRV_NVM_FMPI2C1_AT24C256_H_ +#define DRV_NVM_FMPI2C1_AT24C256_H_ + +#ifdef __cplusplus /* for compatibility with C++ environments */ +extern "C" { +#endif + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "co_if.h" + +/****************************************************************************** +* PUBLIC SYMBOLS +******************************************************************************/ + +extern const CO_IF_NVM_DRV STM32F4xx_FMPI2C1_AT24C256_NvmDriver; + +#ifdef __cplusplus /* for compatibility with C++ environments */ +} +#endif + +#endif diff --git a/src/driver/stm32f4xx-hal/drv_timer_tim2.c b/src/driver/stm32f4xx-hal/drv_timer_tim2.c new file mode 100644 index 0000000..de8b143 --- /dev/null +++ b/src/driver/stm32f4xx-hal/drv_timer_tim2.c @@ -0,0 +1,148 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "drv_timer_tim2.h" +#include "stm32f4xx_hal.h" + +/****************************************************************************** +* PRIVATE VARIABLES +******************************************************************************/ + +static TIM_HandleTypeDef DrvTimer2; + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void DrvTimerInit (uint32_t freq); +static void DrvTimerStart (void); +static uint8_t DrvTimerUpdate (void); +static uint32_t DrvTimerDelay (void); +static void DrvTimerReload (uint32_t reload); +static void DrvTimerStop (void); + +/****************************************************************************** +* PUBLIC VARIABLE +******************************************************************************/ + +const CO_IF_TIMER_DRV STM32F4xx_TIM2_TimerDriver = { + DrvTimerInit, + DrvTimerReload, + DrvTimerDelay, + DrvTimerStop, + DrvTimerStart, + DrvTimerUpdate +}; + +/****************************************************************************** +* PUBLIC FUNCTIONS +******************************************************************************/ + +/* ST HAL Timer2 Interrupt Handler */ +void TIM2_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&DrvTimer2); +} + +/****************************************************************************** +* PRIVATE FUNCTIONS +******************************************************************************/ + +static void DrvTimerInit(uint32_t freq) +{ + /* For simplicity, we implement a fixed frequency of 1MHz: + - the input frequency TIM2_CLK (APB1) is: 90 MHz + - with a prescaler of: 90, we get a counting frequency of: 1MHz + - in other words we get a tick every: dt = 1us + - with the timer width 32bit we get: max. time = 4294s (1h 11min 34s) + */ + if (freq != 1000000) { + while(1); /* see comments above */ + } + + /* Peripheral clocks enable */ + __HAL_RCC_TIM2_CLK_ENABLE(); + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* configure timer to: up-counting timer with tick rate 1MHz, + * with overflow interrupt at given (unbuffered) autoreload register + * (note: the timer reloads to 0 on this overflow) + */ + DrvTimer2.Instance = TIM2; + DrvTimer2.Init.Prescaler = 90; + DrvTimer2.Init.CounterMode = TIM_COUNTERMODE_UP; + DrvTimer2.Init.Period = 4294967295; + DrvTimer2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + DrvTimer2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&DrvTimer2) != HAL_OK) { + while(1); /* error not handled */ + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&DrvTimer2, &sClockSourceConfig) != HAL_OK) { + while(1); /* error not handled */ + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&DrvTimer2, &sMasterConfig) != HAL_OK) { + while(1); /* error not handled */ + } + + /* clear pending update interrupt */ + __HAL_TIM_CLEAR_FLAG(&DrvTimer2, TIM_FLAG_UPDATE); + + /* enable timer interrupts */ + HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); +} + +static void DrvTimerStart(void) +{ + /* start the hardware timer counting */ + HAL_TIM_Base_Start_IT(&DrvTimer2); +} + +static uint8_t DrvTimerUpdate(void) +{ + /* a hardware timer interrupt is always an elapsed event */ + return 1u; +} + +static uint32_t DrvTimerDelay(void) +{ + uint32_t current = __HAL_TIM_GET_COUNTER(&DrvTimer2); + uint32_t reload = __HAL_TIM_GET_AUTORELOAD(&DrvTimer2); + + /* return remaining ticks until interrupt occurs */ + return (reload - current); +} + +static void DrvTimerReload(uint32_t reload) +{ + /* configure the next hardware timer interrupt */ + __HAL_TIM_SET_AUTORELOAD(&DrvTimer2, reload); +} + +static void DrvTimerStop(void) +{ + /* stop the hardware timer counting */ + HAL_TIM_Base_Stop_IT(&DrvTimer2); +} diff --git a/src/driver/stm32f4xx-hal/drv_timer_tim2.h b/src/driver/stm32f4xx-hal/drv_timer_tim2.h new file mode 100644 index 0000000..525a74e --- /dev/null +++ b/src/driver/stm32f4xx-hal/drv_timer_tim2.h @@ -0,0 +1,40 @@ +/****************************************************************************** + Copyright 2020 Embedded Office GmbH & Co. KG + + 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 + + http://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. +******************************************************************************/ + +#ifndef CO_TIMER2_STM32F4XX_H_ +#define CO_TIMER2_STM32F4XX_H_ + +#ifdef __cplusplus /* for compatibility with C++ environments */ +extern "C" { +#endif + +/****************************************************************************** +* INCLUDES +******************************************************************************/ + +#include "co_if.h" + +/****************************************************************************** +* PUBLIC SYMBOLS +******************************************************************************/ + +extern const CO_IF_TIMER_DRV STM32F4xx_TIM2_TimerDriver; + +#ifdef __cplusplus /* for compatibility with C++ environments */ +} +#endif + +#endif