From 47e5e984dfa9551fc40f3187acafab71a593d9d4 Mon Sep 17 00:00:00 2001 From: cpq Date: Mon, 17 May 2021 17:36:57 +0100 Subject: [PATCH] stm32f7 example starts on real h/w, with plus-TCP driver --- docs/README.md | 89 +- .../stm32-freertos-tcp/FreeRTOSIPConfig.h | 66 -- .../Legacy/stm32_hal_legacy.h | 0 .../stm32-freertos-tcp/HAL/stm32f7xx_hal.c | 620 ++++++++++++++ .../HAL/stm32f7xx_hal_conf.h | 267 +++++- .../HAL/stm32f7xx_hal_cortex.c | 505 ++++++++++++ .../HAL/stm32f7xx_hal_cortex.h | 406 +++++++++ .../HAL/stm32f7xx_hal_gpio.c | 531 ++++++++++++ .../HAL/stm32f7xx_hal_gpio.h | 309 +++++++ .../HAL/stm32f7xx_hal_gpio_ex.h | 658 +++++++++++++++ examples/stm32-freertos-tcp/Makefile | 84 +- examples/stm32-freertos-tcp/main.c | 101 ++- .../stm32f7/FreeRTOSConfig.h | 60 +- .../stm32f7/FreeRTOSIPConfig.h | 45 + examples/stm32-freertos-tcp/stm32f7/boot.s | 42 +- examples/stm32-freertos-tcp/stm32f7/device.h | 82 +- examples/stm32-freertos-tcp/stm32f7/link.ld | 37 +- examples/stm32-freertos-tcp/stm32f7/port.c | 773 ------------------ mongoose.c | 234 +----- mongoose.h | 15 + src/arch.h | 2 + src/arch_freertos_tcp.h | 13 + src/http.c | 2 +- src/iobuf.c | 4 +- src/net.c | 2 +- src/private.h | 11 - src/sock.c | 4 +- src/str.c | 2 +- src/util.c | 8 +- test/freertos-tcp/FreeRTOS_IP.c | 1 + 30 files changed, 3716 insertions(+), 1257 deletions(-) delete mode 100644 examples/stm32-freertos-tcp/FreeRTOSIPConfig.h rename examples/stm32-freertos-tcp/{stm32f7 => HAL}/Legacy/stm32_hal_legacy.h (100%) create mode 100644 examples/stm32-freertos-tcp/HAL/stm32f7xx_hal.c create mode 100644 examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.c create mode 100644 examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.h create mode 100644 examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.c create mode 100644 examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.h create mode 100644 examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio_ex.h create mode 100644 examples/stm32-freertos-tcp/stm32f7/FreeRTOSIPConfig.h delete mode 100644 examples/stm32-freertos-tcp/stm32f7/port.c diff --git a/docs/README.md b/docs/README.md index 2bba29da..92ed1175 100644 --- a/docs/README.md +++ b/docs/README.md @@ -192,40 +192,60 @@ Mongoose source code ships in two files: - [mongoose.c](https://github.com/cesanta/mongoose/blob/master/mongoose.c) - implementation Therefore to integrate Mongoose into an application, simply copy these two -files to the application's source tree. +files to the application's source tree. The `mongoose.c` and `mongoose.h` files +are, actually, an amalgamation - a non-amalgamated sources can be found at +https://github.com/cesanta/mongoose/tree/master/src -The `mongoose.c` and `mongoose.h` files are, actually, an amalgamation - -a non-amalgamated sources can be found at https://github.com/cesanta/mongoose/tree/master/src - -Mongoose source code uses a bunch of build constants defined at -https://github.com/cesanta/mongoose/blob/master/src/config.h, together with -their default values. - -In order to change the constant during build time, use the `-D -` compiler option. For example, to disable both MQTT, -compile the application `my_app.c` like this (assumed UNIX system): +Mongoose have two types of build constants (preprocessor definitions) that +affect the build: a target architecture, and tunables. In order to set the +option during build time, use the `-D OPTION` compiler flag: ```sh -$ cc my_app.c mongoose.c -D MG_MQTT_ENABLE=0 +$ cc app0.c mongoose.c # Use defaults! +$ cc app1.c mongoose.c -D MG_ENABLE_IPV6=1 # Build with IPv6 enabled +$ cc app2.c mongoose.c -D MG_ARCH=MG_ARCH_UNIX # Set UNIX architecture +$ cc app3.c mongoose.c -D MG_ENABLE_FS=0 -D MG_ENABLE_LOG=0 # Multiple options ``` +The list of supported +architectures is defined in the +[arch.h](https://github.com/cesanta/mongoose/blob/master/src/arch.h) header +file. Normally, there is no need to explicitly specify the architecture. The +architecture is guessed during the build, so setting it is not usually required. + +| Name | Description | +| ---- | ----------- | +|MG_ARCH_UNIX | All UNIX-like systems like Linux, MacOS, FreeBSD, etc | +|MG_ARCH_WIN32 | Windows systems | +|MG_ARCH_ESP32 | Espressif's ESP32 | +|MG_ARCH_ESP8266 | Espressif's ESP8266 | +|MG_ARCH_FREERTOS_TCP | All systems with FreeRTOS kernel and FreeRTOS-Plus-TCP IP stack | +|MG_ARCH_CUSTOM | A custom architecture, discussed in the next section | + + +The other class of build constants is defined in +[src/config.h](https://github.com/cesanta/mongoose/blob/master/src/config.h) +together with their default values. They are tunables that include/exclude +a certain functionality or change relevant parameters. + + Here is a list of build constants and their default values: | Name | Default | Description | | ---- | ------- | ----------- | -|`MG_ENABLE_SOCKET` | 1 | Use BSD socket low-level API | -|`MG_ENABLE_MBEDTLS` | 0 | Enable Mbed TLS library | -|`MG_ENABLE_OPENSSL` | 0 | Enable OpenSSL library | -|`MG_ENABLE_FS` | 1 | Enable API that use filesystem, like `mg_http_send_file()` | -|`MG_ENABLE_IPV6` | 0 | Enable IPv6 | -|`MG_ENABLE_LOG` | 1 | Enable `LOG()` macro | -|`MG_ENABLE_MD5` | 0 | Use native MD5 implementation | -|`MG_ENABLE_DIRECTORY_LISTING` | 0 | Enable directory listing for HTTP server | -|`MG_ENABLE_SOCKETPAIR` | 0 | Enable `mg_socketpair()` for multi-threading | -|`MG_ENABLE_SSI` | 0 | Enable serving SSI files by `mg_http_serve_dir()` | -|`MG_IO_SIZE` | 512 | Granularity of the send/recv IO buffer growth | -|`MG_MAX_RECV_BUF_SIZE` | (3 * 1024 * 1024) | Maximum recv buffer size | -|`MG_MAX_HTTP_HEADERS` | 40 | Maximum number of HTTP headers | +|MG_ENABLE_SOCKET | 1 | Use BSD socket low-level API | +|MG_ENABLE_MBEDTLS | 0 | Enable Mbed TLS library | +|MG_ENABLE_OPENSSL | 0 | Enable OpenSSL library | +|MG_ENABLE_FS | 1 | Enable API that use filesystem, like `mg_http_send_file()` | +|MG_ENABLE_IPV6 | 0 | Enable IPv6 | +|MG_ENABLE_LOG | 1 | Enable `LOG()` macro | +|MG_ENABLE_MD5 | 0 | Use native MD5 implementation | +|MG_ENABLE_DIRECTORY_LISTING | 0 | Enable directory listing for HTTP server | +|MG_ENABLE_SOCKETPAIR | 0 | Enable `mg_socketpair()` for multi-threading | +|MG_ENABLE_SSI | 0 | Enable serving SSI files by `mg_http_serve_dir()` | +|MG_IO_SIZE | 512 | Granularity of the send/recv IO buffer growth | +|MG_MAX_RECV_BUF_SIZE | (3 * 1024 * 1024) | Maximum recv buffer size | +|MG_MAX_HTTP_HEADERS | 40 | Maximum number of HTTP headers | NOTE: `MG_IO_SIZE` controls the maximum UDP message size, see @@ -234,21 +254,10 @@ uses large UDP messages, increase the `MG_IO_SIZE` limit accordingly. ## Custom build -The list of supported architectures is defined in the -[arch.h](https://github.com/cesanta/mongoose/blob/master/src/arch.h) header -file. Normally, there is no need to explicitly specify the architecture. -The architecture is guessed during the build, so a simple compilation like -`cc main.c mongoose.c` should work fine in most cases. - -However if you're building on embedded system like STM32, NXP, Xilinx or other, -an architecture should be specified explicitly: -- `-DMG_ARCH=MG_ARCH_FREERTOS_TCP` - for environments with FreeRTOS and - FreeRTOS-TCP stack -- `-DMG_ARCH=MG_ARCH_CUSTOM` for all other cases, for example on systems with - FreeRTOS+LWIP, or bare metal + custom IP stack - -Below is the guide for building with `MG_ARCH_CUSTOM` architecture: - +A custom build should be used for cases which is not covered by the +existing architecture options. For example, an embedded architecture that +uses some proprietary RTOS and network stack. In order to build on such +systems, follow the guideline outlined below: 1. Add `-DMG_ARCH=MG_ARCH_CUSTOM` to your build flags. diff --git a/examples/stm32-freertos-tcp/FreeRTOSIPConfig.h b/examples/stm32-freertos-tcp/FreeRTOSIPConfig.h deleted file mode 100644 index b180374b..00000000 --- a/examples/stm32-freertos-tcp/FreeRTOSIPConfig.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -#define FREERTOS_IP_CONFIG_H - -#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 -#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1 -#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 -#define ipconfigZERO_COPY_RX_DRIVER 1 -#define ipconfigZERO_COPY_TX_DRIVER 1 -#define ipconfigUSE_LINKED_RX_MESSAGES 1 - -extern void vLoggingPrintf(const char *pcFormatString, ...); -#define ipconfigHAS_DEBUG_PRINTF 0 -#if (ipconfigHAS_DEBUG_PRINTF == 1) -#define FreeRTOS_debug_printf(X) vLoggingPrintf X -#endif - -#define ipconfigHAS_PRINTF 0 -#if (ipconfigHAS_PRINTF == 1) -#define FreeRTOS_printf(X) vLoggingPrintf X -#endif - -#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN -#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME (2000) -#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME (5000) -#define ipconfigUSE_LLMNR (0) -#define ipconfigUSE_NBNS (0) -#define ipconfigUSE_DNS_CACHE (0) -#define ipconfigDNS_CACHE_NAME_LENGTH (32) -#define ipconfigDNS_CACHE_ENTRIES (4) -#define ipconfigDNS_REQUEST_ATTEMPTS (2) -#define ipconfigIP_TASK_PRIORITY (configMAX_PRIORITIES - 2) -#define ipconfigIP_TASK_STACK_SIZE_WORDS (configMINIMAL_STACK_SIZE * 5) -#define ipconfigRAND32() uxRand() -#define ipconfigUSE_NETWORK_EVENT_HOOK 0 -#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS (5000 / portTICK_PERIOD_MS) -#define ipconfigUSE_DHCP 0 -#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD (120000 / portTICK_PERIOD_MS) -#define ipconfigARP_CACHE_ENTRIES 6 -#define ipconfigMAX_ARP_RETRANSMISSIONS (5) -#define ipconfigMAX_ARP_AGE 150 -#define ipconfigINCLUDE_FULL_INET_ADDR 0 -#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 10 -#define ipconfigEVENT_QUEUE_LENGTH (ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5) -#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 -#define ipconfigUDP_TIME_TO_LIVE 128 -#define ipconfigTCP_TIME_TO_LIVE 128 -#define ipconfigUSE_TCP (1) -#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK_WITH_CONTEXT (1) -#define ipconfigUSE_TCP_WIN (1) -#define ipconfigNETWORK_MTU 1200 -#define ipconfigUSE_DNS 0 -#define ipconfigREPLY_TO_INCOMING_PINGS 0 -#define ipconfigSUPPORT_OUTGOING_PINGS 0 -#define ipconfigSUPPORT_SELECT_FUNCTION 1 -#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 -#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY (20 / portTICK_PERIOD_MS) -#define ipconfigPACKET_FILLER_SIZE 2 -#define ipconfigTCP_WIN_SEG_COUNT 240 -#define ipconfigTCP_RX_BUFFER_LENGTH (1000) -#define ipconfigTCP_TX_BUFFER_LENGTH (1000) -#define ipconfigIS_VALID_PROG_ADDRESS(x) ((x) != NULL) -#define ipconfigTCP_HANG_PROTECTION (0) -#define ipconfigTCP_HANG_PROTECTION_TIME (30) -#define ipconfigTCP_KEEP_ALIVE (0) -#define ipconfigTCP_KEEP_ALIVE_INTERVAL (20) /* in seconds */ -#define portINLINE __inline diff --git a/examples/stm32-freertos-tcp/stm32f7/Legacy/stm32_hal_legacy.h b/examples/stm32-freertos-tcp/HAL/Legacy/stm32_hal_legacy.h similarity index 100% rename from examples/stm32-freertos-tcp/stm32f7/Legacy/stm32_hal_legacy.h rename to examples/stm32-freertos-tcp/HAL/Legacy/stm32_hal_legacy.h diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal.c b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal.c new file mode 100644 index 00000000..e65e36fd --- /dev/null +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal.c @@ -0,0 +1,620 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal.c + * @author MCD Application Team + * @brief HAL module driver. + * This is the common part of the HAL initialization + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The common HAL driver contains a set of generic and common APIs that can be + used by the PPP peripheral drivers and the user to start using the HAL. + [..] + The HAL contains two APIs' categories: + (+) Common HAL APIs + (+) Services HAL APIs + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL HAL + * @brief HAL module driver. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup HAL_Private_Constants + * @{ + */ +/** + * @brief STM32F7xx HAL Driver version number V1.2.9 + */ +#define __STM32F7xx_HAL_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32F7xx_HAL_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */ +#define __STM32F7xx_HAL_VERSION_SUB2 (0x09) /*!< [15:8] sub2 version */ +#define __STM32F7xx_HAL_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F7xx_HAL_VERSION ((__STM32F7xx_HAL_VERSION_MAIN << 24)\ + |(__STM32F7xx_HAL_VERSION_SUB1 << 16)\ + |(__STM32F7xx_HAL_VERSION_SUB2 << 8 )\ + |(__STM32F7xx_HAL_VERSION_RC)) + +#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Exported variables ---------------------------------------------------------*/ +/** @addtogroup HAL_Exported_Variables + * @{ + */ +__IO uint32_t uwTick; +uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */ +HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HAL_Exported_Functions HAL Exported Functions + * @{ + */ + +/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initializes the Flash interface the NVIC allocation and initial clock + configuration. It initializes the systick also when timeout is needed + and the backup domain when enabled. + (+) De-Initializes common part of the HAL. + (+) Configure the time base source to have 1ms time base with a dedicated + Tick interrupt priority. + (++) SysTick timer is used by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + (++) Time base configuration function (HAL_InitTick ()) is called automatically + at the beginning of the program after reset by HAL_Init() or at any time + when clock is configured, by HAL_RCC_ClockConfig(). + (++) Source of time base is configured to generate interrupts at regular + time intervals. Care must be taken if HAL_Delay() is called from a + peripheral ISR process, the Tick interrupt line must have higher priority + (numerically lower) than the peripheral interrupt. Otherwise the caller + ISR process will be blocked. + (++) functions affecting time base configurations are declared as __weak + to make override possible in case of other implementations in user file. +@endverbatim + * @{ + */ + +/** + * @brief This function is used to initialize the HAL Library; it must be the first + * instruction to be executed in the main program (before to call any other + * HAL function), it performs the following: + * Configure the Flash prefetch, and instruction cache through ART accelerator. + * Configures the SysTick to generate an interrupt each 1 millisecond, + * which is clocked by the HSI (at this stage, the clock is not yet + * configured and thus the system is running from the internal HSI at 16 MHz). + * Set NVIC Group Priority to 4. + * Calls the HAL_MspInit() callback function defined in user file + * "stm32f7xx_hal_msp.c" to do the global low level hardware initialization + * + * @note SysTick is used as time base for the HAL_Delay() function, the application + * need to ensure that the SysTick time base is always set to 1 millisecond + * to have correct HAL operation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_Init(void) +{ + /* Configure Instruction cache through ART accelerator */ +#if (ART_ACCLERATOR_ENABLE != 0) + __HAL_FLASH_ART_ENABLE(); +#endif /* ART_ACCLERATOR_ENABLE */ + + /* Configure Flash prefetch */ +#if (PREFETCH_ENABLE != 0U) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); +#endif /* PREFETCH_ENABLE */ + + /* Set Interrupt Group Priority */ + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ + HAL_InitTick(TICK_INT_PRIORITY); + + /* Init the low level hardware */ + HAL_MspInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief This function de-Initializes common part of the HAL and stops the systick. + * This function is optional. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DeInit(void) +{ + /* Reset of all peripherals */ + __HAL_RCC_APB1_FORCE_RESET(); + __HAL_RCC_APB1_RELEASE_RESET(); + + __HAL_RCC_APB2_FORCE_RESET(); + __HAL_RCC_APB2_RELEASE_RESET(); + + __HAL_RCC_AHB1_FORCE_RESET(); + __HAL_RCC_AHB1_RELEASE_RESET(); + + __HAL_RCC_AHB2_FORCE_RESET(); + __HAL_RCC_AHB2_RELEASE_RESET(); + + __HAL_RCC_AHB3_FORCE_RESET(); + __HAL_RCC_AHB3_RELEASE_RESET(); + + /* De-Init the low level hardware */ + HAL_MspDeInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize the MSP. + * @retval None + */ +__weak void HAL_MspInit(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the MSP. + * @retval None + */ +__weak void HAL_MspDeInit(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief This function configures the source of the time base. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). + * @note In the default implementation, SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals. + * Care must be taken if HAL_Delay() is called from a peripheral ISR process, + * The SysTick interrupt must have higher priority (numerically lower) + * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. + * The function is declared as __weak to be overwritten in case of other + * implementation in user file. + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /* Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) + { + return HAL_ERROR; + } + + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions + * @brief HAL Control functions + * +@verbatim + =============================================================================== + ##### HAL Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Provide a tick value in millisecond + (+) Provide a blocking delay in millisecond + (+) Suspend the time base source interrupt + (+) Resume the time base source interrupt + (+) Get the HAL API driver version + (+) Get the device identifier + (+) Get the device revision identifier + (+) Enable/Disable Debug module during SLEEP mode + (+) Enable/Disable Debug module during STOP mode + (+) Enable/Disable Debug module during STANDBY mode + +@endverbatim + * @{ + */ + +/** + * @brief This function is called to increment a global variable "uwTick" + * used as application time base. + * @note In the default implementation, this variable is incremented each 1ms + * in SysTick ISR. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + uwTick += uwTickFreq; +} + +/** + * @brief Provides a tick value in millisecond. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + return uwTick; +} + +/** + * @brief This function returns a tick priority. + * @retval tick priority + */ +uint32_t HAL_GetTickPrio(void) +{ + return uwTickPrio; +} + +/** + * @brief Set new tick Freq. + * @retval Status + */ +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_TickFreqTypeDef prevTickFreq; + + assert_param(IS_TICKFREQ(Freq)); + + if (uwTickFreq != Freq) + { + /* Back up uwTickFreq frequency */ + prevTickFreq = uwTickFreq; + + /* Update uwTickFreq global variable used by HAL_InitTick() */ + uwTickFreq = Freq; + + /* Apply the new tick Freq */ + status = HAL_InitTick(uwTickPrio); + + if (status != HAL_OK) + { + /* Restore previous tick frequency */ + uwTickFreq = prevTickFreq; + } + } + + return status; +} + +/** + * @brief Return tick frequency. + * @retval tick period in Hz + */ +HAL_TickFreqTypeDef HAL_GetTickFreq(void) +{ + return uwTickFreq; +} + +/** + * @brief This function provides minimum delay (in milliseconds) based + * on variable incremented. + * @note In the default implementation , SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals where uwTick + * is incremented. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @param Delay specifies the delay time length, in milliseconds. + * @retval None + */ +__weak void HAL_Delay(uint32_t Delay) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t wait = Delay; + + /* Add a freq to guarantee minimum wait */ + if (wait < HAL_MAX_DELAY) + { + wait += (uint32_t)(uwTickFreq); + } + + while ((HAL_GetTick() - tickstart) < wait) + { + } +} + +/** + * @brief Suspend Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() + * is called, the SysTick interrupt will be disabled and so Tick increment + * is suspended. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_SuspendTick(void) +{ + /* Disable SysTick Interrupt */ + SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; +} + +/** + * @brief Resume Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() + * is called, the SysTick interrupt will be enabled and so Tick increment + * is resumed. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_ResumeTick(void) +{ + /* Enable SysTick Interrupt */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; +} + +/** + * @brief Returns the HAL revision + * @retval version : 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t HAL_GetHalVersion(void) +{ + return __STM32F7xx_HAL_VERSION; +} + +/** + * @brief Returns the device revision identifier. + * @retval Device revision identifier + */ +uint32_t HAL_GetREVID(void) +{ + return((DBGMCU->IDCODE) >> 16U); +} + +/** + * @brief Returns the device identifier. + * @retval Device identifier + */ +uint32_t HAL_GetDEVID(void) +{ + return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); +} + +/** + * @brief Returns first word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw0(void) +{ + return(READ_REG(*((uint32_t *)UID_BASE))); +} + +/** + * @brief Returns second word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw1(void) +{ + return(READ_REG(*((uint32_t *)(UID_BASE + 4U)))); +} + +/** + * @brief Returns third word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw2(void) +{ + return(READ_REG(*((uint32_t *)(UID_BASE + 8U)))); +} + +/** + * @brief Enable the Debug Module during SLEEP mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGSleepMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Disable the Debug Module during SLEEP mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGSleepMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Enable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStopMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Disable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStopMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Enable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStandbyMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Disable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStandbyMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Enables the I/O Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_EnableCompensationCell(void) +{ + SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD; +} + +/** + * @brief Power-down the I/O Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_DisableCompensationCell(void) +{ + SYSCFG->CMPCR &= (uint32_t)~((uint32_t)SYSCFG_CMPCR_CMP_PD); +} + +/** + * @brief Enables the FMC Memory Mapping Swapping. + * + * @note SDRAM is accessible at 0x60000000 + * and NOR/RAM is accessible at 0xC0000000 + * + * @retval None + */ +void HAL_EnableFMCMemorySwapping(void) +{ + SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_0; +} + +/** + * @brief Disables the FMC Memory Mapping Swapping + * + * @note SDRAM is accessible at 0xC0000000 (default mapping) + * and NOR/RAM is accessible at 0x60000000 (default mapping) + * + * @retval None + */ +void HAL_DisableFMCMemorySwapping(void) +{ + + SYSCFG->MEMRMP &= (uint32_t)~((uint32_t)SYSCFG_MEMRMP_SWP_FMC); +} + +#if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) +/** +* @brief Enable the Internal FLASH Bank Swapping. +* +* @note This function can be used only for STM32F77xx/STM32F76xx devices. +* +* @note Flash Bank2 mapped at 0x08000000 (AXI) (aliased at 0x00200000 (TCM)) +* and Flash Bank1 mapped at 0x08100000 (AXI) (aliased at 0x00300000 (TCM)) +* +* @retval None +*/ +void HAL_EnableMemorySwappingBank(void) +{ + SET_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_SWP_FB); +} + +/** +* @brief Disable the Internal FLASH Bank Swapping. +* +* @note This function can be used only for STM32F77xx/STM32F76xx devices. +* +* @note The default state : Flash Bank1 mapped at 0x08000000 (AXI) (aliased at 0x00200000 (TCM)) +* and Flash Bank2 mapped at 0x08100000 (AXI)( aliased at 0x00300000 (TCM)) +* +* @retval None +*/ +void HAL_DisableMemorySwappingBank(void) +{ + CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_SWP_FB); +} +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_conf.h b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_conf.h index 5fbf8199..d9533fd5 100644 --- a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_conf.h +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_conf.h @@ -2,13 +2,241 @@ #define HAL_ETH_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED #include "stm32f7xx.h" +#include "stm32f7xx_hal_cortex.h" +#include "stm32f7xx_hal_def.h" +#include "stm32f7xx_hal_rcc.h" +#include "stm32f7xx_hal_gpio.h" + +#define UID_BASE 0x1FF0F420UL +#define __HAL_FLASH_ART_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_ARTEN) +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTEN) + +#define assert_param(expr) ((void) 0U) + +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +#define HAL_CEC_MODULE_ENABLED +#define HAL_CRC_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_SRAM_MODULE_ENABLED +#define HAL_SDRAM_MODULE_ENABLED +#define HAL_HASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +//#define HAL_I2S_MODULE_ENABLED +//#define HAL_IWDG_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_LTDC_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 + +/* ########################## 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 \ + ((uint32_t) 25000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT \ + ((uint32_t) 5000) /*!< 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 \ + ((uint32_t) 16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +#define LSI_VALUE ((uint32_t) 40000) +#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 \ + ((uint32_t) 32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @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 \ + ((uint32_t) 12288000) /*!< Value of the Internal 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 ((uint32_t) 3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t) 0x0F) /*!< tick interrupt priority */ +#define USE_RTOS 0 +#define ART_ACCLERATOR_ENABLE 1 /* To enable instruction cache and prefetch */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## 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 2 +#define MAC_ADDR1 0 +#define MAC_ADDR2 0 +#define MAC_ADDR3 0 +#define MAC_ADDR4 0 +#define MAC_ADDR5 0 + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE \ + ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE \ + ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t) 8) /* 8 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t) 4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t) 0x000000FF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t) 0x00000FFF) + +#define PHY_READ_TO ((uint32_t) 0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t) 0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t) 0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t) 0x01) /*!< 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) 0x10) /*!< PHY status register Offset */ +#define PHY_MICR \ + ((uint16_t) 0x11) /*!< MII Interrupt Control Register */ +#define PHY_MISR \ + ((uint16_t) 0x12) /*!< 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 */ + +#if 0 +#define HAL_ETH_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED + +#include "stm32f7xx.h" +#include "stm32f7xx_hal_cortex.h" #include "stm32f7xx_hal_def.h" #include "stm32f7xx_hal_rcc.h" -#define ETH_RXBUFNB 4 -#define ETH_TXBUFNB 3 +#define UID_BASE 0x1FF0F420UL +#define __HAL_FLASH_ART_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_ARTEN) +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTEN) + +#define ETH_RXBUFNB 3 +#define ETH_TXBUFNB 2 #define ETH_RX_BUF_SIZE (ipconfigNETWORK_MTU + 36) #define ETH_TX_BUF_SIZE (ipconfigNETWORK_MTU + 36) @@ -40,3 +268,38 @@ #define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ #define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ +#if !defined(HSE_VALUE) +#define HSE_VALUE \ + ((uint32_t) 8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT \ + ((uint32_t) 100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ +#if !defined(HSI_VALUE) +#define HSI_VALUE \ + ((uint32_t) 16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ +#if !defined(LSI_VALUE) +#define LSI_VALUE ((uint32_t) 32000U) /*!< LSI Typical Value in Hz*/ +#endif +#if !defined(LSE_VALUE) +#define LSE_VALUE \ + ((uint32_t) 32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT \ + ((uint32_t) 5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE \ + ((uint32_t) 12288000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ +#define VDD_VALUE ((uint32_t) 3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t) 0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch \ + */ + +#endif diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.c b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.c new file mode 100644 index 00000000..a338d071 --- /dev/null +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.c @@ -0,0 +1,505 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_cortex.c + * @author MCD Application Team + * @brief CORTEX HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the CORTEX: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + *** How to configure Interrupts using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to configure the NVIC interrupts (IRQ). + The Cortex-M4 exceptions are managed by CMSIS functions. + + (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping() + function according to the following table. + (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority(). + (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ(). + (#) please refer to programming manual for details in how to configure priority. + + -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible. + The pending IRQ priority will be managed only by the sub priority. + + -@- IRQ priority order (sorted by highest to lowest priority): + (+@) Lowest preemption priority + (+@) Lowest sub priority + (+@) Lowest hardware priority (IRQ number) + + [..] + *** How to configure Systick using CORTEX HAL driver *** + ======================================================== + [..] + Setup SysTick Timer for time base. + + (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which + is a CMSIS function that: + (++) Configures the SysTick Reload register with value passed as function parameter. + (++) Configures the SysTick IRQ priority to the lowest value (0x0F). + (++) Resets the SysTick Counter register. + (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK). + (++) Enables the SysTick Interrupt. + (++) Starts the SysTick Counter. + + (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro + __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the + HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined + inside the stm32f7xx_hal_cortex.h file. + + (+) You can change the SysTick IRQ priority by calling the + HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function + call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function. + + (+) To adjust the SysTick time base, use the following formula: + + Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s) + (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function + (++) Reload Value should not exceed 0xFFFFFF + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @defgroup CORTEX CORTEX + * @brief CORTEX HAL module driver + * @{ + */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + + +/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions allowing to configure Interrupts + Systick functionalities + +@endverbatim + * @{ + */ + + +/** + * @brief Sets the priority grouping field (preemption priority and subpriority) + * using the required unlock sequence. + * @param PriorityGroup The priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority + * 4 bits for subpriority + * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority + * 3 bits for subpriority + * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority + * 2 bits for subpriority + * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority + * 1 bits for subpriority + * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority + * 0 bits for subpriority + * @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * @retval None + */ +void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */ + NVIC_SetPriorityGrouping(PriorityGroup); +} + +/** + * @brief Sets the priority of an interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @param PreemptPriority The preemption priority for the IRQn channel. + * This parameter can be a value between 0 and 15 + * A lower priority value indicates a higher priority + * @param SubPriority the subpriority level for the IRQ channel. + * This parameter can be a value between 0 and 15 + * A lower priority value indicates a higher priority. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t prioritygroup = 0x00; + + /* Check the parameters */ + assert_param(IS_NVIC_SUB_PRIORITY(SubPriority)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + + prioritygroup = NVIC_GetPriorityGrouping(); + + NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority)); +} + +/** + * @brief Enables a device specific interrupt in the NVIC interrupt controller. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); +} + +/** + * @brief Disables a device specific interrupt in the NVIC interrupt controller. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @retval None + */ +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Disable interrupt */ + NVIC_DisableIRQ(IRQn); +} + +/** + * @brief Initiates a system reset request to reset the MCU. + * @retval None + */ +void HAL_NVIC_SystemReset(void) +{ + /* System Reset */ + NVIC_SystemReset(); +} + +/** + * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer. + * Counter is in free running mode to generate periodic interrupts. + * @param TicksNumb Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + return SysTick_Config(TicksNumb); +} +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the CORTEX + (NVIC, SYSTICK, MPU) functionalities. + + +@endverbatim + * @{ + */ + +#if (__MPU_PRESENT == 1) +/** + * @brief Disables the MPU + * @retval None + */ +void HAL_MPU_Disable(void) +{ + /* Make sure outstanding transfers are done */ + __DMB(); + + /* Disable fault exceptions */ + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; + + /* Disable the MPU and clear the control register*/ + MPU->CTRL = 0; +} + +/** + * @brief Enables the MPU + * @param MPU_Control Specifies the control mode of the MPU during hard fault, + * NMI, FAULTMASK and privileged access to the default memory + * This parameter can be one of the following values: + * @arg MPU_HFNMI_PRIVDEF_NONE + * @arg MPU_HARDFAULT_NMI + * @arg MPU_PRIVILEGED_DEFAULT + * @arg MPU_HFNMI_PRIVDEF + * @retval None + */ +void HAL_MPU_Enable(uint32_t MPU_Control) +{ + /* Enable the MPU */ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; + + /* Enable fault exceptions */ + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + /* Ensure MPU setting take effects */ + __DSB(); + __ISB(); +} + +/** + * @brief Initializes and configures the Region and the memory to be protected. + * @param MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init) +{ + /* Check the parameters */ + assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number)); + assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable)); + + /* Set the Region number */ + MPU->RNR = MPU_Init->Number; + + if ((MPU_Init->Enable) != RESET) + { + /* Check the parameters */ + assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec)); + assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission)); + assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField)); + assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable)); + assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable)); + assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable)); + assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable)); + assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size)); + + MPU->RBAR = MPU_Init->BaseAddress; + MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) | + ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) | + ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) | + ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) | + ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) | + ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) | + ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) | + ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) | + ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos); + } + else + { + MPU->RBAR = 0x00; + MPU->RASR = 0x00; + } +} +#endif /* __MPU_PRESENT */ + +/** + * @brief Gets the priority grouping field from the NVIC Interrupt Controller. + * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field) + */ +uint32_t HAL_NVIC_GetPriorityGrouping(void) +{ + /* Get the PRIGROUP[10:8] field value */ + return NVIC_GetPriorityGrouping(); +} + +/** + * @brief Gets the priority of an interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @param PriorityGroup the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority + * 4 bits for subpriority + * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority + * 3 bits for subpriority + * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority + * 2 bits for subpriority + * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority + * 1 bits for subpriority + * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority + * 0 bits for subpriority + * @param pPreemptPriority Pointer on the Preemptive priority value (starting from 0). + * @param pSubPriority Pointer on the Subpriority value (starting from 0). + * @retval None + */ +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup)); + /* Get priority for Cortex-M system or device specific interrupts */ + NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority); +} + +/** + * @brief Sets Pending bit of an external interrupt. + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @retval None + */ +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Set interrupt pending */ + NVIC_SetPendingIRQ(IRQn); +} + +/** + * @brief Gets Pending Interrupt (reads the pending register in the NVIC + * and returns the pending bit for the specified interrupt). + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Return 1 if pending else 0 */ + return NVIC_GetPendingIRQ(IRQn); +} + +/** + * @brief Clears the pending bit of an external interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @retval None + */ +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Clear pending interrupt */ + NVIC_ClearPendingIRQ(IRQn); +} + +/** + * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit). + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Return 1 if active else 0 */ + return NVIC_GetActive(IRQn); +} + +/** + * @brief Configures the SysTick clock source. + * @param CLKSource specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource)); + if (CLKSource == SYSTICK_CLKSOURCE_HCLK) + { + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + } + else + { + SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK; + } +} + +/** + * @brief This function handles SYSTICK interrupt request. + * @retval None + */ +void HAL_SYSTICK_IRQHandler(void) +{ + HAL_SYSTICK_Callback(); +} + +/** + * @brief SYSTICK callback. + * @retval None + */ +__weak void HAL_SYSTICK_Callback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SYSTICK_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CORTEX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.h b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.h new file mode 100644 index 00000000..c9162d4e --- /dev/null +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_cortex.h @@ -0,0 +1,406 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_CORTEX_H +#define __STM32F7xx_HAL_CORTEX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal_def.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @addtogroup CORTEX + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Types Cortex Exported Types + * @{ + */ + +#if (__MPU_PRESENT == 1) +/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition + * @brief MPU Region initialization structure + * @{ + */ +typedef struct +{ + uint8_t Enable; /*!< Specifies the status of the region. + This parameter can be a value of @ref CORTEX_MPU_Region_Enable */ + uint8_t Number; /*!< Specifies the number of the region to protect. + This parameter can be a value of @ref CORTEX_MPU_Region_Number */ + uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */ + uint8_t Size; /*!< Specifies the size of the region to protect. + This parameter can be a value of @ref CORTEX_MPU_Region_Size */ + uint8_t SubRegionDisable; /*!< Specifies the number of the subregion protection to disable. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + uint8_t TypeExtField; /*!< Specifies the TEX field level. + This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */ + uint8_t AccessPermission; /*!< Specifies the region access permission type. + This parameter can be a value of @ref CORTEX_MPU_Region_Permission_Attributes */ + uint8_t DisableExec; /*!< Specifies the instruction access status. + This parameter can be a value of @ref CORTEX_MPU_Instruction_Access */ + uint8_t IsShareable; /*!< Specifies the shareability status of the protected region. + This parameter can be a value of @ref CORTEX_MPU_Access_Shareable */ + uint8_t IsCacheable; /*!< Specifies the cacheable status of the region protected. + This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable */ + uint8_t IsBufferable; /*!< Specifies the bufferable status of the protected region. + This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable */ +}MPU_Region_InitTypeDef; +/** + * @} + */ +#endif /* __MPU_PRESENT */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group + * @{ + */ +#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007U) /*!< 0 bits for pre-emption priority + 4 bits for subpriority */ +#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006U) /*!< 1 bits for pre-emption priority + 3 bits for subpriority */ +#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005U) /*!< 2 bits for pre-emption priority + 2 bits for subpriority */ +#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004U) /*!< 3 bits for pre-emption priority + 1 bits for subpriority */ +#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003U) /*!< 4 bits for pre-emption priority + 0 bits for subpriority */ +/** + * @} + */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX _SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0x00000000U) +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) + +/** + * @} + */ + +#if (__MPU_PRESENT == 1) +/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control + * @{ + */ +#define MPU_HFNMI_PRIVDEF_NONE ((uint32_t)0x00000000U) +#define MPU_HARDFAULT_NMI ((uint32_t)0x00000002U) +#define MPU_PRIVILEGED_DEFAULT ((uint32_t)0x00000004U) +#define MPU_HFNMI_PRIVDEF ((uint32_t)0x00000006U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable + * @{ + */ +#define MPU_REGION_ENABLE ((uint8_t)0x01U) +#define MPU_REGION_DISABLE ((uint8_t)0x00U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access + * @{ + */ +#define MPU_INSTRUCTION_ACCESS_ENABLE ((uint8_t)0x00U) +#define MPU_INSTRUCTION_ACCESS_DISABLE ((uint8_t)0x01U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable + * @{ + */ +#define MPU_ACCESS_SHAREABLE ((uint8_t)0x01U) +#define MPU_ACCESS_NOT_SHAREABLE ((uint8_t)0x00U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable + * @{ + */ +#define MPU_ACCESS_CACHEABLE ((uint8_t)0x01U) +#define MPU_ACCESS_NOT_CACHEABLE ((uint8_t)0x00U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable + * @{ + */ +#define MPU_ACCESS_BUFFERABLE ((uint8_t)0x01U) +#define MPU_ACCESS_NOT_BUFFERABLE ((uint8_t)0x00U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_TEX_Levels MPU TEX Levels + * @{ + */ +#define MPU_TEX_LEVEL0 ((uint8_t)0x00U) +#define MPU_TEX_LEVEL1 ((uint8_t)0x01U) +#define MPU_TEX_LEVEL2 ((uint8_t)0x02U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size + * @{ + */ +#define MPU_REGION_SIZE_32B ((uint8_t)0x04U) +#define MPU_REGION_SIZE_64B ((uint8_t)0x05U) +#define MPU_REGION_SIZE_128B ((uint8_t)0x06U) +#define MPU_REGION_SIZE_256B ((uint8_t)0x07U) +#define MPU_REGION_SIZE_512B ((uint8_t)0x08U) +#define MPU_REGION_SIZE_1KB ((uint8_t)0x09U) +#define MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) +#define MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) +#define MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) +#define MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) +#define MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) +#define MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) +#define MPU_REGION_SIZE_128KB ((uint8_t)0x10U) +#define MPU_REGION_SIZE_256KB ((uint8_t)0x11U) +#define MPU_REGION_SIZE_512KB ((uint8_t)0x12U) +#define MPU_REGION_SIZE_1MB ((uint8_t)0x13U) +#define MPU_REGION_SIZE_2MB ((uint8_t)0x14U) +#define MPU_REGION_SIZE_4MB ((uint8_t)0x15U) +#define MPU_REGION_SIZE_8MB ((uint8_t)0x16U) +#define MPU_REGION_SIZE_16MB ((uint8_t)0x17U) +#define MPU_REGION_SIZE_32MB ((uint8_t)0x18U) +#define MPU_REGION_SIZE_64MB ((uint8_t)0x19U) +#define MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) +#define MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) +#define MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) +#define MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) +#define MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) +#define MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes + * @{ + */ +#define MPU_REGION_NO_ACCESS ((uint8_t)0x00U) +#define MPU_REGION_PRIV_RW ((uint8_t)0x01U) +#define MPU_REGION_PRIV_RW_URO ((uint8_t)0x02U) +#define MPU_REGION_FULL_ACCESS ((uint8_t)0x03U) +#define MPU_REGION_PRIV_RO ((uint8_t)0x05U) +#define MPU_REGION_PRIV_RO_URO ((uint8_t)0x06U) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number + * @{ + */ +#define MPU_REGION_NUMBER0 ((uint8_t)0x00U) +#define MPU_REGION_NUMBER1 ((uint8_t)0x01U) +#define MPU_REGION_NUMBER2 ((uint8_t)0x02U) +#define MPU_REGION_NUMBER3 ((uint8_t)0x03U) +#define MPU_REGION_NUMBER4 ((uint8_t)0x04U) +#define MPU_REGION_NUMBER5 ((uint8_t)0x05U) +#define MPU_REGION_NUMBER6 ((uint8_t)0x06U) +#define MPU_REGION_NUMBER7 ((uint8_t)0x07U) +/** + * @} + */ +#endif /* __MPU_PRESENT */ + +/** + * @} + */ + + +/* Exported Macros -----------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CORTEX_Exported_Functions + * @{ + */ + +/** @addtogroup CORTEX_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup); +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority); +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn); +void HAL_NVIC_SystemReset(void); +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb); +/** + * @} + */ + +/** @addtogroup CORTEX_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +#if (__MPU_PRESENT == 1) +void HAL_MPU_Enable(uint32_t MPU_Control); +void HAL_MPU_Disable(void); +void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init); +#endif /* __MPU_PRESENT */ +uint32_t HAL_NVIC_GetPriorityGrouping(void); +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority); +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn); +uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn); +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); +void HAL_SYSTICK_IRQHandler(void); +void HAL_SYSTICK_Callback(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Macros CORTEX Private Macros + * @{ + */ +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \ + ((GROUP) == NVIC_PRIORITYGROUP_1) || \ + ((GROUP) == NVIC_PRIORITYGROUP_2) || \ + ((GROUP) == NVIC_PRIORITYGROUP_3) || \ + ((GROUP) == NVIC_PRIORITYGROUP_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U) + +#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= 0x00) + +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \ + ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8)) + +#if (__MPU_PRESENT == 1) +#define IS_MPU_REGION_ENABLE(STATE) (((STATE) == MPU_REGION_ENABLE) || \ + ((STATE) == MPU_REGION_DISABLE)) + +#define IS_MPU_INSTRUCTION_ACCESS(STATE) (((STATE) == MPU_INSTRUCTION_ACCESS_ENABLE) || \ + ((STATE) == MPU_INSTRUCTION_ACCESS_DISABLE)) + +#define IS_MPU_ACCESS_SHAREABLE(STATE) (((STATE) == MPU_ACCESS_SHAREABLE) || \ + ((STATE) == MPU_ACCESS_NOT_SHAREABLE)) + +#define IS_MPU_ACCESS_CACHEABLE(STATE) (((STATE) == MPU_ACCESS_CACHEABLE) || \ + ((STATE) == MPU_ACCESS_NOT_CACHEABLE)) + +#define IS_MPU_ACCESS_BUFFERABLE(STATE) (((STATE) == MPU_ACCESS_BUFFERABLE) || \ + ((STATE) == MPU_ACCESS_NOT_BUFFERABLE)) + +#define IS_MPU_TEX_LEVEL(TYPE) (((TYPE) == MPU_TEX_LEVEL0) || \ + ((TYPE) == MPU_TEX_LEVEL1) || \ + ((TYPE) == MPU_TEX_LEVEL2)) + +#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(TYPE) (((TYPE) == MPU_REGION_NO_ACCESS) || \ + ((TYPE) == MPU_REGION_PRIV_RW) || \ + ((TYPE) == MPU_REGION_PRIV_RW_URO) || \ + ((TYPE) == MPU_REGION_FULL_ACCESS) || \ + ((TYPE) == MPU_REGION_PRIV_RO) || \ + ((TYPE) == MPU_REGION_PRIV_RO_URO)) + +#define IS_MPU_REGION_NUMBER(NUMBER) (((NUMBER) == MPU_REGION_NUMBER0) || \ + ((NUMBER) == MPU_REGION_NUMBER1) || \ + ((NUMBER) == MPU_REGION_NUMBER2) || \ + ((NUMBER) == MPU_REGION_NUMBER3) || \ + ((NUMBER) == MPU_REGION_NUMBER4) || \ + ((NUMBER) == MPU_REGION_NUMBER5) || \ + ((NUMBER) == MPU_REGION_NUMBER6) || \ + ((NUMBER) == MPU_REGION_NUMBER7)) + +#define IS_MPU_REGION_SIZE(SIZE) (((SIZE) == MPU_REGION_SIZE_32B) || \ + ((SIZE) == MPU_REGION_SIZE_64B) || \ + ((SIZE) == MPU_REGION_SIZE_128B) || \ + ((SIZE) == MPU_REGION_SIZE_256B) || \ + ((SIZE) == MPU_REGION_SIZE_512B) || \ + ((SIZE) == MPU_REGION_SIZE_1KB) || \ + ((SIZE) == MPU_REGION_SIZE_2KB) || \ + ((SIZE) == MPU_REGION_SIZE_4KB) || \ + ((SIZE) == MPU_REGION_SIZE_8KB) || \ + ((SIZE) == MPU_REGION_SIZE_16KB) || \ + ((SIZE) == MPU_REGION_SIZE_32KB) || \ + ((SIZE) == MPU_REGION_SIZE_64KB) || \ + ((SIZE) == MPU_REGION_SIZE_128KB) || \ + ((SIZE) == MPU_REGION_SIZE_256KB) || \ + ((SIZE) == MPU_REGION_SIZE_512KB) || \ + ((SIZE) == MPU_REGION_SIZE_1MB) || \ + ((SIZE) == MPU_REGION_SIZE_2MB) || \ + ((SIZE) == MPU_REGION_SIZE_4MB) || \ + ((SIZE) == MPU_REGION_SIZE_8MB) || \ + ((SIZE) == MPU_REGION_SIZE_16MB) || \ + ((SIZE) == MPU_REGION_SIZE_32MB) || \ + ((SIZE) == MPU_REGION_SIZE_64MB) || \ + ((SIZE) == MPU_REGION_SIZE_128MB) || \ + ((SIZE) == MPU_REGION_SIZE_256MB) || \ + ((SIZE) == MPU_REGION_SIZE_512MB) || \ + ((SIZE) == MPU_REGION_SIZE_1GB) || \ + ((SIZE) == MPU_REGION_SIZE_2GB) || \ + ((SIZE) == MPU_REGION_SIZE_4GB)) + +#define IS_MPU_SUB_REGION_DISABLE(SUBREGION) ((SUBREGION) < (uint16_t)0x00FFU) +#endif /* __MPU_PRESENT */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_CORTEX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.c b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.c new file mode 100644 index 00000000..c9d4c122 --- /dev/null +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.c @@ -0,0 +1,531 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_gpio.c + * @author MCD Application Team + * @brief GPIO HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the General Purpose Input/Output (GPIO) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + @verbatim + ============================================================================== + ##### GPIO Peripheral features ##### + ============================================================================== + [..] + Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each + port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software + in several modes: + (+) Input mode + (+) Analog mode + (+) Output mode + (+) Alternate function mode + (+) External interrupt/event lines + + [..] + During and just after reset, the alternate functions and external interrupt + lines are not active and the I/O ports are configured in input floating mode. + + [..] + All GPIO pins have weak internal pull-up and pull-down resistors, which can be + activated or not. + + [..] + In Output or Alternate mode, each IO can be configured on open-drain or push-pull + type and the IO speed can be selected depending on the VDD value. + + [..] + All ports have external interrupt/event capability. To use external interrupt + lines, the port must be configured in input mode. All available GPIO pins are + connected to the 16 external interrupt/event lines from EXTI0 to EXTI15. + + [..] + The external interrupt/event controller consists of up to 23 edge detectors + (16 lines are connected to GPIO) for generating event/interrupt requests (each + input line can be independently configured to select the type (interrupt or event) + and the corresponding trigger event (rising or falling or both). Each line can + also be masked independently. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE(). + + (#) Configure the GPIO pin(s) using HAL_GPIO_Init(). + (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure + (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef + structure. + (++) In case of Output or alternate function mode selection: the speed is + configured through "Speed" member from GPIO_InitTypeDef structure. + (++) In alternate mode is selection, the alternate function connected to the IO + is configured through "Alternate" member from GPIO_InitTypeDef structure. + (++) Analog mode is required when a pin is to be used as ADC channel + or DAC output. + (++) In case of external interrupt/event selection the "Mode" member from + GPIO_InitTypeDef structure select the type (interrupt or event) and + the corresponding trigger event (rising or falling or both). + + (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority + mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using + HAL_NVIC_EnableIRQ(). + + (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin(). + + (#) To set/reset the level of a pin configured in output mode use + HAL_GPIO_WritePin()/HAL_GPIO_TogglePin(). + + (#) To lock pin configuration until next reset use HAL_GPIO_LockPin(). + + + (#) During and just after reset, the alternate functions are not + active and the GPIO pins are configured in input floating mode (except JTAG + pins). + + (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose + (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has + priority over the GPIO function. + + (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as + general purpose PH0 and PH1, respectively, when the HSE oscillator is off. + The HSE has priority over the GPIO function. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIO GPIO + * @brief GPIO HAL module driver + * @{ + */ + +#ifdef HAL_GPIO_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup GPIO_Private_Constants GPIO Private Constants + * @{ + */ +#define GPIO_MODE ((uint32_t)0x00000003U) +#define EXTI_MODE ((uint32_t)0x10000000U) +#define GPIO_MODE_IT ((uint32_t)0x00010000U) +#define GPIO_MODE_EVT ((uint32_t)0x00020000U) +#define RISING_EDGE ((uint32_t)0x00100000U) +#define FALLING_EDGE ((uint32_t)0x00200000U) +#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010U) + +#define GPIO_NUMBER ((uint32_t)16U) +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Functions GPIO Exported Functions + * @{ + */ + +/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to initialize and de-initialize the GPIOs + to be ready for use. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init. + * @param GPIOx where x can be (A..K) to select the GPIO peripheral. + * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + uint32_t position = 0x00; + uint32_t ioposition = 0x00; + uint32_t iocurrent = 0x00; + uint32_t temp = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Configure the port pins */ + for(position = 0; position < GPIO_NUMBER; position++) + { + /* Get the IO position */ + ioposition = ((uint32_t)0x01) << position; + /* Get the current IO position */ + iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition; + + if(iocurrent == ioposition) + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Output or Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2)); + temp |= (GPIO_Init->Speed << (position * 2)); + GPIOx->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + temp &= ~(GPIO_OTYPER_OT_0 << position) ; + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4) << position); + GPIOx->OTYPER = temp; + } + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2)); + temp |= ((GPIO_Init->Pull) << (position * 2)); + GPIOx->PUPDR = temp; + + /* In case of Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Alternate function parameter */ + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3]; + temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4)); + GPIOx->AFR[position >> 3] = temp; + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + temp &= ~(GPIO_MODER_MODER0 << (position * 2)); + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2)); + GPIOx->MODER = temp; + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + temp = SYSCFG->EXTICR[position >> 2]; + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03))); + SYSCFG->EXTICR[position >> 2] = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->IMR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + { + temp |= iocurrent; + } + EXTI->IMR = temp; + + temp = EXTI->EMR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + { + temp |= iocurrent; + } + EXTI->EMR = temp; + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + { + temp |= iocurrent; + } + EXTI->RTSR = temp; + + temp = EXTI->FTSR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + { + temp |= iocurrent; + } + EXTI->FTSR = temp; + } + } + } +} + +/** + * @brief De-initializes the GPIOx peripheral registers to their default reset values. + * @param GPIOx where x can be (A..K) to select the GPIO peripheral. + * @param GPIO_Pin specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + uint32_t position; + uint32_t ioposition = 0x00; + uint32_t iocurrent = 0x00; + uint32_t tmp = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + + /* Configure the port pins */ + for(position = 0; position < GPIO_NUMBER; position++) + { + /* Get the IO position */ + ioposition = ((uint32_t)0x01) << position; + /* Get the current IO position */ + iocurrent = (GPIO_Pin) & ioposition; + + if(iocurrent == ioposition) + { + /*------------------------- EXTI Mode Configuration --------------------*/ + tmp = SYSCFG->EXTICR[position >> 2]; + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + if(tmp == ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03)))) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~((uint32_t)iocurrent); + EXTI->EMR &= ~((uint32_t)iocurrent); + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~((uint32_t)iocurrent); + EXTI->FTSR &= ~((uint32_t)iocurrent); + + /* Configure the External Interrupt or event for the current IO */ + tmp = ((uint32_t)0x0F) << (4 * (position & 0x03)); + SYSCFG->EXTICR[position >> 2] &= ~tmp; + } + /*------------------------- GPIO Mode Configuration --------------------*/ + /* Configure IO Direction in Input Floating Mode */ + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (position * 2)); + + /* Configure the default Alternate Function in current IO */ + GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + + /* Deactivate the Pull-up and Pull-down resistor for the current IO */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2)); + + /* Configure the default value IO Output Type */ + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position) ; + + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2)); + } + } +} + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions + * @brief GPIO Read and Write + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Reads the specified input port pin. + * @param GPIOx where x can be (A..K) to select the GPIO peripheral. + * @param GPIO_Pin specifies the port bit to read. + * This parameter can be GPIO_PIN_x where x can be (0..15). + * @retval The input port pin value. + */ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) + { + bitstatus = GPIO_PIN_SET; + } + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; +} + +/** + * @brief Sets or clears the selected data port bit. + * + * @note This function uses GPIOx_BSRR register to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * + * @param GPIOx where x can be (A..K) to select the GPIO peripheral. + * @param GPIO_Pin specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @param PinState specifies the value to be written to the selected bit. + * This parameter can be one of the GPIO_PinState enum values: + * @arg GPIO_PIN_RESET: to clear the port pin + * @arg GPIO_PIN_SET: to set the port pin + * @retval None + */ +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if(PinState != GPIO_PIN_RESET) + { + GPIOx->BSRR = GPIO_Pin; + } + else + { + GPIOx->BSRR = (uint32_t)GPIO_Pin << 16; + } +} + +/** + * @brief Toggles the specified GPIO pins. + * @param GPIOx Where x can be (A..I) to select the GPIO peripheral. + * @param GPIO_Pin Specifies the pins to be toggled. + * @retval None + */ +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint32_t odr; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* get current Output Data Register value */ + odr = GPIOx->ODR; + + /* Set selected pins that were at low level, and reset ones that were high */ + GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin); +} + +/** + * @brief Locks GPIO Pins configuration registers. + * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, + * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. + * @note The configuration of the locked GPIO pins can no longer be modified + * until the next reset. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F7 family + * @param GPIO_Pin specifies the port bit to be locked. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = GPIO_LCKR_LCKK; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + tmp |= GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Read LCKR register. This read is mandatory to complete key lock sequence */ + tmp = GPIOx->LCKR; + + /* Read again in order to confirm lock is active */ + if((GPIOx->LCKR & GPIO_LCKR_LCKK) != RESET) + { + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief This function handles EXTI interrupt request. + * @param GPIO_Pin Specifies the pins connected EXTI line + * @retval None + */ +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) +{ + /* EXTI line interrupt detected */ + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + { + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + HAL_GPIO_EXTI_Callback(GPIO_Pin); + } +} + +/** + * @brief EXTI line detection callbacks. + * @param GPIO_Pin Specifies the pins connected EXTI line + * @retval None + */ +__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(GPIO_Pin); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* HAL_GPIO_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.h b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.h new file mode 100644 index 00000000..46a64983 --- /dev/null +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio.h @@ -0,0 +1,309 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_GPIO_H +#define __STM32F7xx_HAL_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal_def.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Types GPIO Exported Types + * @{ + */ + +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_mode_define */ + + uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref GPIO_pull_define */ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_speed_define */ + + uint32_t Alternate; /*!< Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIO_Alternate_function_selection */ +}GPIO_InitTypeDef; + +/** + * @brief GPIO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + GPIO_PIN_RESET = 0, + GPIO_PIN_SET +}GPIO_PinState; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_pins_define GPIO pins define + * @{ + */ +#define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */ +#define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */ +#define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */ +#define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */ +#define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */ +#define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */ +#define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */ +#define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */ +#define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */ +#define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */ +#define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */ +#define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */ +#define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */ +#define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */ +#define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */ +#define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */ +#define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */ + +#define GPIO_PIN_MASK ((uint32_t)0x0000FFFFU) /* PIN mask for assert test */ +/** + * @} + */ + +/** @defgroup GPIO_mode_define GPIO mode define + * @brief GPIO Configuration Mode + * Elements values convention: 0xX0yz00YZ + * - X : GPIO mode or EXTI Mode + * - y : External IT or Event trigger detection + * - z : IO configuration on External IT or Event + * - Y : Output type (Push Pull or Open Drain) + * - Z : IO Direction mode (Input, Output, Alternate or Analog) + * @{ + */ +#define GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Input Floating Mode */ +#define GPIO_MODE_OUTPUT_PP ((uint32_t)0x00000001U) /*!< Output Push Pull Mode */ +#define GPIO_MODE_OUTPUT_OD ((uint32_t)0x00000011U) /*!< Output Open Drain Mode */ +#define GPIO_MODE_AF_PP ((uint32_t)0x00000002U) /*!< Alternate Function Push Pull Mode */ +#define GPIO_MODE_AF_OD ((uint32_t)0x00000012U) /*!< Alternate Function Open Drain Mode */ + +#define GPIO_MODE_ANALOG ((uint32_t)0x00000003U) /*!< Analog Mode */ + +#define GPIO_MODE_IT_RISING ((uint32_t)0x10110000U) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_FALLING ((uint32_t)0x10210000U) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define GPIO_MODE_IT_RISING_FALLING ((uint32_t)0x10310000U) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ + +#define GPIO_MODE_EVT_RISING ((uint32_t)0x10120000U) /*!< External Event Mode with Rising edge trigger detection */ +#define GPIO_MODE_EVT_FALLING ((uint32_t)0x10220000U) /*!< External Event Mode with Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING_FALLING ((uint32_t)0x10320000U) /*!< External Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @defgroup GPIO_speed_define GPIO speed define + * @brief GPIO Output Maximum frequency + * @{ + */ +#define GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Low speed */ +#define GPIO_SPEED_FREQ_MEDIUM ((uint32_t)0x00000001U) /*!< Medium speed */ +#define GPIO_SPEED_FREQ_HIGH ((uint32_t)0x00000002U) /*!< Fast speed */ +#define GPIO_SPEED_FREQ_VERY_HIGH ((uint32_t)0x00000003U) /*!< High speed */ +/** + * @} + */ + + /** @defgroup GPIO_pull_define GPIO pull define + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ +#define GPIO_NOPULL ((uint32_t)0x00000000U) /*!< No Pull-up or Pull-down activation */ +#define GPIO_PULLUP ((uint32_t)0x00000001U) /*!< Pull-up activation */ +#define GPIO_PULLDOWN ((uint32_t)0x00000002U) /*!< Pull-down activation */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @brief Checks whether the specified EXTI line flag is set or not. + * @param __EXTI_LINE__ specifies the EXTI line flag to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clears the EXTI's line pending flags. + * @param __EXTI_LINE__ specifies the EXTI lines flags to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Checks whether the specified EXTI line is asserted or not. + * @param __EXTI_LINE__ specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clears the EXTI's line pending bits. + * @param __EXTI_LINE__ specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__ specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) +/** + * @} + */ + +/* Include GPIO HAL Extension module */ +#include "stm32f7xx_hal_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPIO_Exported_Functions + * @{ + */ + +/** @addtogroup GPIO_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); +/** + * @} + */ + +/** @addtogroup GPIO_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup GPIO_Private_Constants GPIO Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET)) +#define IS_GPIO_PIN(__PIN__) ((((uint32_t)(__PIN__) & GPIO_PIN_MASK) != 0x00U)) +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) ||\ + ((MODE) == GPIO_MODE_OUTPUT_PP) ||\ + ((MODE) == GPIO_MODE_OUTPUT_OD) ||\ + ((MODE) == GPIO_MODE_AF_PP) ||\ + ((MODE) == GPIO_MODE_AF_OD) ||\ + ((MODE) == GPIO_MODE_IT_RISING) ||\ + ((MODE) == GPIO_MODE_IT_FALLING) ||\ + ((MODE) == GPIO_MODE_IT_RISING_FALLING) ||\ + ((MODE) == GPIO_MODE_EVT_RISING) ||\ + ((MODE) == GPIO_MODE_EVT_FALLING) ||\ + ((MODE) == GPIO_MODE_EVT_RISING_FALLING) ||\ + ((MODE) == GPIO_MODE_ANALOG)) +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_SPEED_LOW) || ((SPEED) == GPIO_SPEED_MEDIUM) || \ + ((SPEED) == GPIO_SPEED_FAST) || ((SPEED) == GPIO_SPEED_HIGH)) +#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || \ + ((PULL) == GPIO_PULLDOWN)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup GPIO_Private_Functions GPIO Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_GPIO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio_ex.h b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio_ex.h new file mode 100644 index 00000000..f93badbd --- /dev/null +++ b/examples/stm32-freertos-tcp/HAL/stm32f7xx_hal_gpio_ex.h @@ -0,0 +1,658 @@ +/** + ****************************************************************************** + * @file stm32f7xx_hal_gpio_ex.h + * @author MCD Application Team + * @brief Header file of GPIO HAL Extension module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_HAL_GPIO_EX_H +#define __STM32F7xx_HAL_GPIO_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal_def.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIOEx GPIOEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_Alternate_function_selection GPIO Alternate Function Selection + * @{ + */ +/*--------------- STM32F74xxx/STM32F75xxx/STM32F76xxx/STM32F77xxx -------------*/ +#if defined (STM32F745xx) || defined (STM32F746xx) || defined (STM32F756xx) || defined (STM32F765xx) || defined (STM32F767xx) ||\ + defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) || defined (STM32F750xx) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00U) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00U) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00U) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01U) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01U) /* TIM2 Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF1_UART5 ((uint8_t)0x01U) /* UART5 Alternate Function mapping */ +#define GPIO_AF1_I2C4 ((uint8_t)0x01U) /* I2C4 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02U) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02U) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02U) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03U) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03U) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03U) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03U) /* TIM11 Alternate Function mapping */ +#define GPIO_AF3_LPTIM1 ((uint8_t)0x03U) /* LPTIM1 Alternate Function mapping */ +#define GPIO_AF3_CEC ((uint8_t)0x03U) /* CEC Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF3_DFSDM1 ((uint8_t)0x03U) /* DFSDM1 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04U) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04U) /* I2C3 Alternate Function mapping */ +#define GPIO_AF4_I2C4 ((uint8_t)0x04U) /* I2C4 Alternate Function mapping */ +#define GPIO_AF4_CEC ((uint8_t)0x04U) /* CEC Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF4_USART1 ((uint8_t)0x04) /* USART1 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05U) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05U) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05U) /* SPI4 Alternate Function mapping */ +#define GPIO_AF5_SPI5 ((uint8_t)0x05U) /* SPI5 Alternate Function mapping */ +#define GPIO_AF5_SPI6 ((uint8_t)0x05U) /* SPI6 Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06U) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_SAI1 ((uint8_t)0x06U) /* SAI1 Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF6_UART4 ((uint8_t)0x06U) /* UART4 Alternate Function mapping */ +#define GPIO_AF6_DFSDM1 ((uint8_t)0x06U) /* DFSDM1 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07U) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07U) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07U) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_UART5 ((uint8_t)0x07U) /* UART5 Alternate Function mapping */ +#define GPIO_AF7_SPDIFRX ((uint8_t)0x07U) /* SPDIF-RX Alternate Function mapping */ +#define GPIO_AF7_SPI2 ((uint8_t)0x07U) /* SPI2 Alternate Function mapping */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07U) /* SPI3 Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF7_SPI6 ((uint8_t)0x07U) /* SPI6 Alternate Function mapping */ +#define GPIO_AF7_DFSDM1 ((uint8_t)0x07U) /* DFSDM1 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08U) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08U) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08U) /* USART6 Alternate Function mapping */ +#define GPIO_AF8_UART7 ((uint8_t)0x08U) /* UART7 Alternate Function mapping */ +#define GPIO_AF8_UART8 ((uint8_t)0x08U) /* UART8 Alternate Function mapping */ +#define GPIO_AF8_SPDIFRX ((uint8_t)0x08U) /* SPIDIF-RX Alternate Function mapping */ +#define GPIO_AF8_SAI2 ((uint8_t)0x08U) /* SAI2 Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF8_SPI6 ((uint8_t)0x08U) /* SPI6 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09U) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_CAN2 ((uint8_t)0x09U) /* CAN2 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09U) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09U) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09U) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_QUADSPI ((uint8_t)0x09U) /* QUADSPI Alternate Function mapping */ +#if defined(STM32F746xx) || defined(STM32F756xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F750xx) +#define GPIO_AF9_LTDC ((uint8_t)0x09U) /* LCD-TFT Alternate Function mapping */ +#endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */ +#if defined(STM32F746xx) || defined(STM32F756xx) || defined(STM32F765xx) || defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F750xx) +#define GPIO_AF9_FMC ((uint8_t)0x09U) /* FMC Alternate Function mapping */ +#endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */ +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xAU) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xAU) /* OTG_HS Alternate Function mapping */ +#define GPIO_AF10_QUADSPI ((uint8_t)0xAU) /* QUADSPI Alternate Function mapping */ +#define GPIO_AF10_SAI2 ((uint8_t)0xAU) /* SAI2 Alternate Function mapping */ +#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) +#define GPIO_AF10_DFSDM1 ((uint8_t)0x0AU) /* DFSDM1 Alternate Function mapping */ +#define GPIO_AF10_SDMMC2 ((uint8_t)0x0AU) /* SDMMC2 Alternate Function mapping */ +#define GPIO_AF10_LTDC ((uint8_t)0x0AU) /* LCD-TFT Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_ETH ((uint8_t)0x0BU) /* ETHERNET Alternate Function mapping */ +#if defined(STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) +#define GPIO_AF11_CAN3 ((uint8_t)0x0BU) /* CAN3 Alternate Function mapping */ +#define GPIO_AF11_SDMMC2 ((uint8_t)0x0BU) /* SDMMC2 Alternate Function mapping */ +#define GPIO_AF11_I2C4 ((uint8_t)0x0BU) /* I2C4 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FMC ((uint8_t)0xCU) /* FMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xCU) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDMMC1 ((uint8_t)0xCU) /* SDMMC1 Alternate Function mapping */ +#if defined(STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) +#define GPIO_AF12_MDIOS ((uint8_t)0xCU) /* SDMMC1 Alternate Function mapping */ +#define GPIO_AF12_UART7 ((uint8_t)0xCU) /* UART7 Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_DCMI ((uint8_t)0x0DU) /* DCMI Alternate Function mapping */ +#if defined (STM32F769xx) || defined (STM32F779xx) +#define GPIO_AF13_DSI ((uint8_t)0x0DU) /* DSI Alternate Function mapping */ +#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ +#if defined(STM32F746xx) || defined(STM32F756xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F750xx) +#define GPIO_AF13_LTDC ((uint8_t)0x0DU) /* LTDC Alternate Function mapping */ + +/** + * @brief AF 14 selection + */ +#define GPIO_AF14_LTDC ((uint8_t)0x0EU) /* LCD-TFT Alternate Function mapping */ +#endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */ +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0FU) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F745xx || STM32F746xx || STM32F756xx || STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ +/*----------------------------------------------------------------------------*/ + +/*---------------------------- STM32F72xxx/STM32F73xxx -----------------------*/ +#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F732xx) || defined(STM32F733xx) || defined(STM32F730xx) + /** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00U) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00U) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00U) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01U) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01U) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02U) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02U) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02U) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03U) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03U) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03U) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03U) /* TIM11 Alternate Function mapping */ +#define GPIO_AF3_LPTIM1 ((uint8_t)0x03U) /* LPTIM1 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04U) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04U) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05U) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05U) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05U) /* SPI4 Alternate Function mapping */ +#define GPIO_AF5_SPI5 ((uint8_t)0x05U) /* SPI5 Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06U) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_SAI1 ((uint8_t)0x06U) /* SAI1 Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07U) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07U) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07U) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_UART5 ((uint8_t)0x07U) /* UART5 Alternate Function mapping */ +#define GPIO_AF7_SPI2 ((uint8_t)0x07U) /* SPI2 Alternate Function mapping */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07U) /* SPI3 Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08U) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08U) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08U) /* USART6 Alternate Function mapping */ +#define GPIO_AF8_UART7 ((uint8_t)0x08U) /* UART7 Alternate Function mapping */ +#define GPIO_AF8_UART8 ((uint8_t)0x08U) /* UART8 Alternate Function mapping */ +#define GPIO_AF8_SAI2 ((uint8_t)0x08U) /* SAI2 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09U) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09U) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09U) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09U) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_QUADSPI ((uint8_t)0x09U) /* QUADSPI Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xAU) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xAU) /* OTG_HS Alternate Function mapping */ +#define GPIO_AF10_QUADSPI ((uint8_t)0xAU) /* QUADSPI Alternate Function mapping */ +#define GPIO_AF10_SAI2 ((uint8_t)0xAU) /* SAI2 Alternate Function mapping */ +#define GPIO_AF10_SDMMC2 ((uint8_t)0x0AU) /* SDMMC2 Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_SDMMC2 ((uint8_t)0x0BU) /* SDMMC2 Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FMC ((uint8_t)0xCU) /* FMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xCU) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDMMC1 ((uint8_t)0xCU) /* SDMMC1 Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_RNG ((uint8_t)0x0DU) /* RNG Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0FU) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */ +/*----------------------------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Macros GPIO Exported Macros + * @{ + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Functions GPIO Exported Functions + * @{ + */ +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup GPIOEx_Private_Constants GPIO Private Constants + * @{ + */ + +/** + * @brief GPIO pin available on the platform + */ +/* Defines the available pins per GPIOs */ +#define GPIOA_PIN_AVAILABLE GPIO_PIN_All +#define GPIOB_PIN_AVAILABLE GPIO_PIN_All +#define GPIOC_PIN_AVAILABLE GPIO_PIN_All +#define GPIOD_PIN_AVAILABLE GPIO_PIN_All +#define GPIOE_PIN_AVAILABLE GPIO_PIN_All +#define GPIOF_PIN_AVAILABLE GPIO_PIN_All +#define GPIOG_PIN_AVAILABLE GPIO_PIN_All +#define GPIOI_PIN_AVAILABLE GPIO_PIN_All +#define GPIOJ_PIN_AVAILABLE GPIO_PIN_All +#define GPIOH_PIN_AVAILABLE GPIO_PIN_All +#define GPIOK_PIN_AVAILABLE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | \ + GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Private_Macros GPIO Private Macros + * @{ + */ +/** @defgroup GPIOEx_Get_Port_Index GPIO Get Port Index + * @{ + */ +#if defined (STM32F745xx) || defined (STM32F746xx) || defined (STM32F756xx) || defined (STM32F765xx) ||\ + defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) ||\ + defined (STM32F750xx) +#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U :\ + ((__GPIOx__) == (GPIOF))? 5U :\ + ((__GPIOx__) == (GPIOG))? 6U :\ + ((__GPIOx__) == (GPIOH))? 7U :\ + ((__GPIOx__) == (GPIOI))? 8U :\ + ((__GPIOx__) == (GPIOJ))? 9U : 10U) +#endif /* STM32F745xx || STM32F746xx || STM32F756xx || STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */ + +#if defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx) +#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U :\ + ((__GPIOx__) == (GPIOF))? 5U :\ + ((__GPIOx__) == (GPIOG))? 6U :\ + ((__GPIOx__) == (GPIOH))? 7U : 8U) +#endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */ +/** + * @} + */ + +#define IS_GPIO_PIN_AVAILABLE(__INSTANCE__,__PIN__) \ + ((((__INSTANCE__) == GPIOA) && (((__PIN__) & (GPIOA_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOA_PIN_AVAILABLE)) == (GPIOA_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOB) && (((__PIN__) & (GPIOB_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOB_PIN_AVAILABLE)) == (GPIOB_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOC) && (((__PIN__) & (GPIOC_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOC_PIN_AVAILABLE)) == (GPIOC_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOD) && (((__PIN__) & (GPIOD_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOD_PIN_AVAILABLE)) == (GPIOD_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOE) && (((__PIN__) & (GPIOE_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOE_PIN_AVAILABLE)) == (GPIOE_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOF) && (((__PIN__) & (GPIOF_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOF_PIN_AVAILABLE)) == (GPIOF_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOG) && (((__PIN__) & (GPIOG_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOG_PIN_AVAILABLE)) == (GPIOG_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOI) && (((__PIN__) & (GPIOI_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOI_PIN_AVAILABLE)) == (GPIOI_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOJ) && (((__PIN__) & (GPIOJ_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOJ_PIN_AVAILABLE)) == (GPIOJ_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOK) && (((__PIN__) & (GPIOK_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOK_PIN_AVAILABLE)) == (GPIOK_PIN_AVAILABLE))) || \ + (((__INSTANCE__) == GPIOH) && (((__PIN__) & (GPIOH_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOH_PIN_AVAILABLE)) == (GPIOH_PIN_AVAILABLE)))) +/** @defgroup GPIOEx_IS_Alternat_function_selection GPIO Check Alternate Function + * @{ + */ +#if defined(STM32F756xx) || defined(STM32F746xx) || defined(STM32F750xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \ + ((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \ + ((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \ + ((AF) == GPIO_AF9_LTDC) || ((AF) == GPIO_AF10_OTG_FS) || \ + ((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \ + ((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \ + ((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDMMC1) || \ + ((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF15_EVENTOUT) || \ + ((AF) == GPIO_AF13_DCMI) || ((AF) == GPIO_AF14_LTDC)) +#elif defined(STM32F745xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \ + ((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \ + ((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \ + ((AF) == GPIO_AF13_DCMI) || ((AF) == GPIO_AF10_OTG_FS) || \ + ((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \ + ((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \ + ((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDMMC1) || \ + ((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF15_EVENTOUT)) +#elif defined(STM32F767xx) || defined(STM32F777xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \ + ((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \ + ((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \ + ((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF9_LTDC) || \ + ((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \ + ((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \ + ((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \ + ((AF) == GPIO_AF11_CAN3) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDMMC1) || ((AF) == GPIO_AF12_FMC) || \ + ((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF14_LTDC)) +#elif defined(STM32F769xx) || defined(STM32F779xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \ + ((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \ + ((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \ + ((AF) == GPIO_AF9_LTDC) || ((AF) == GPIO_AF10_OTG_FS) || \ + ((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \ + ((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \ + ((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \ + ((AF) == GPIO_AF11_CAN3) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDMMC1) || ((AF) == GPIO_AF12_FMC) || \ + ((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF14_LTDC) || ((AF) == GPIO_AF13_DSI)) +#elif defined(STM32F765xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \ + ((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \ + ((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \ + ((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \ + ((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \ + ((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \ + ((AF) == GPIO_AF11_CAN3) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDMMC1) || ((AF) == GPIO_AF12_FMC) || \ + ((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF10_OTG_FS)) +#elif defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \ + ((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \ + ((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF5_SPI3) || \ + ((AF) == GPIO_AF5_SPI4) || ((AF) == GPIO_AF5_SPI5) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF9_QUADSPI) || ((AF) == GPIO_AF10_OTG_HS) || \ + ((AF) == GPIO_AF10_SAI2) || ((AF) == GPIO_AF10_QUADSPI) || \ + ((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \ + ((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDMMC1) || \ + ((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF15_EVENTOUT) || \ + ((AF) == GPIO_AF10_OTG_FS)) +#endif /* STM32F756xx || STM32F746xx || STM32F750xx */ +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup GPIOEx_Private_Functions GPIO Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_HAL_GPIO_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/examples/stm32-freertos-tcp/Makefile b/examples/stm32-freertos-tcp/Makefile index 6509bd03..47dc14f0 100644 --- a/examples/stm32-freertos-tcp/Makefile +++ b/examples/stm32-freertos-tcp/Makefile @@ -1,22 +1,56 @@ # FreeRTOS/{FreeRTOS-Kernel V10.4.3,FreeRTOS-Plus-TCP V2.3.2} PROG = firmware ARCH = stm32f7 -ROOT = $(realpath $(CURDIR)/../..) -DOCKER ?= docker run -it --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/armgcc -MONGOOSE_OPTS = -DMG_ARCH=MG_ARCH_FREERTOS_TCP -DMG_ENABLE_FS=0 -DMG_ENABLE_LINES=1 -MCU = -mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard -INCS = -I. -I$(ROOT) -I$(ARCH) -I$(ROOT)/test/freertos-kernel/include -I$(ROOT)/test/freertos-tcp/include -I$(ROOT)/test/freertos-tcp/portable/Compiler/GCC -I$(ROOT)/test/freertos-tcp/portable/NetworkInterface/include -IHAL -NETFLAGS = -DSEMIHOSTING -DSTM32F7xx -DSTM32F746xx -Wno-sign-compare -Wno-unused-function -Wno-cpp -CFLAGS = -W -Wall -Werror -Wno-format -Wno-address-of-packed-member -Os -g $(MCU) -fdata-sections -ffunction-sections $(INCS) $(MONGOOSE_OPTS) $(NETFLAGS) $(EXTRA) -#LFLAGS = $(MCU) --static -Wl,-Map=$(TARGET).map -Wl,--gc-sections -lc -lgcc -T$(ARCH)/link.ld #-nostartfiles -lgcc #-Wl,-Map=obj/$(PROG).map,--cref -Wl,--gc-sections -LFLAGS = $(MCU) --static -Wl,-Map=$(TARGET).map -Wl,--gc-sections -specs rdimon.specs -lrdimon -lc -lgcc -T$(ARCH)/link.ld #-nostartfiles -lgcc #-Wl,-Map=obj/$(PROG).map,--cref -Wl,--gc-sections -SRCS = main.c $(wildcard $(ROOT)/test/freertos-kernel/*.c) $(wildcard $(ROOT)/test/freertos-tcp/*.c) -SRCS += $(ROOT)/test/freertos-kernel/portable/MemMang/heap_4.c $(ARCH)/port.c -SRCS += $(ROOT)/test/freertos-tcp/portable/BufferManagement/BufferAllocation_2.c -SRCS += $(wildcard $(ROOT)/test/freertos-tcp/portable/NetworkInterface/STM32Fxx/*.c) -SRCS += $(wildcard $(ROOT)/test/freertos-tcp/portable/NetworkInterface/Common/*.c) -SRCS += $(wildcard HAL/*.c) -OBJS = obj/boot.o $(SRCS:%.c=obj/%.o) obj/mongoose.o # ORDER MATTERS - boot (vector table) first! +PROJECT_ROOT_PATH = $(realpath $(CURDIR)/../..) +DOCKER ?= docker run -it --rm -v $(PROJECT_ROOT_PATH):$(PROJECT_ROOT_PATH) -w $(CURDIR) mdashnet/armgcc +FREERTOS_KERNEL_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-kernel +FREERTOS_PLUS_TCP_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-tcp + +MONGOOSE_FLAGS = -DMG_ARCH=MG_ARCH_FREERTOS_TCP -DMG_ENABLE_FS=0 +MCU_FLAGS = -mcpu=cortex-m7 -mthumb -mfloat-abi=softfp -mfpu=vfpv4 +#-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard + +INCLUDES = -I$(PROJECT_ROOT_PATH) -I$(ARCH) -I$(FREERTOS_KERNEL_PATH)/include -I$(FREERTOS_PLUS_TCP_PATH)/include +INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/tools/tcp_utilities/include +INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/../Utilities/include +#INCLUDES += -IH2 +#INCLUDES += -I/Users/lsm/src/htibosch/plus/stm32F7/ST_Library/include +INCLUDES += -IHAL +INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/portable/Compiler/GCC +INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx +INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/include +NETFLAGS = -DSTM32F7xx -DSTM32F746xx -Wno-sign-compare -Wno-unused-function #-Wno-cpp + +CFLAGS = -g3 -O0 -W -Wall $(MCU_FLAGS) +CFLAGS += $(INCLUDES) $(MONGOOSE_FLAGS) $(NETFLAGS) $(EXTRA) + +LINKFLAGS = -T$(ARCH)/link.ld -mcpu=cortex-m7 -mthumb -nostartfiles --specs rdimon.specs -Wl,--gc-sections + +SOURCES = main.c $(PROJECT_ROOT_PATH)/mongoose.c +SOURCES += $(wildcard HAL/*.c) +#SOURCES += -I$(realpath $(FREERTOS_KERNEL_PATH)/../../stm32F7/ST_Library/sources)/ + +# FreeRTOS kernel sources +SOURCES += $(wildcard $(FREERTOS_KERNEL_PATH)/*.c) +SOURCES += $(FREERTOS_KERNEL_PATH)/portable/MemMang/heap_5.c +SOURCES += $(FREERTOS_KERNEL_PATH)/portable/GCC/ARM_CM7/r0p1/port.c + +# FreeRTOS TCP stack sources +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_ARP.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_DHCP.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_DNS.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_IP.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_Sockets.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_Stream_Buffer.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_TCP_IP.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_TCP_WIN.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_UDP_IP.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/Common/phyHandling.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/BufferManagement/BufferAllocation_1.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx/NetworkInterface.c +SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c + +OBJECTS = obj/boot.o $(SOURCES:%.c=obj/%.o) all: $(PROG).hex @@ -26,19 +60,17 @@ $(PROG).bin: $(PROG).elf $(PROG).hex: $(PROG).bin $(DOCKER) arm-none-eabi-objcopy -I binary -O ihex --change-address 0x8000000 $< $@ -$(PROG).elf: $(OBJS) - $(DOCKER) arm-none-eabi-gcc $(OBJS) $(LFLAGS) -o $@ +$(PROG).elf: $(OBJECTS) Makefile + $(DOCKER) arm-none-eabi-gcc $(OBJECTS) $(LINKFLAGS) -o $@ + $(DOCKER) arm-none-eabi-size -A $@ obj/%.o: %.c @mkdir -p $(dir $@) $(DOCKER) arm-none-eabi-gcc $(CFLAGS) -c $< -o $@ -obj/boot.o: +obj/boot.o: $(ARCH)/boot.s @mkdir -p $(dir $@) - $(DOCKER) arm-none-eabi-as --warn --fatal-warnings $(MCU) $(ARCH)/boot.s -o $@ - -obj/mongoose.o: - $(DOCKER) arm-none-eabi-gcc $(CFLAGS) -c ../../mongoose.c -o $@ + $(DOCKER) arm-none-eabi-as -g3 --warn --fatal-warnings $(MCU_FLAGS) $< -o $@ flash: $(PROG).bin st-flash --reset write $< 0x8000000 @@ -46,7 +78,8 @@ flash: $(PROG).bin openocd: openocd -f openocd.cfg -gdb: $(PROG).elf +ELF ?= $(PROG).elf +gdb: #$(PROG).elf arm-none-eabi-gdb \ -ex 'set confirm off' \ -ex 'target extended-remote :3333' \ @@ -54,8 +87,9 @@ gdb: $(PROG).elf -ex 'monitor reset halt' \ -ex 'load' \ -ex 'monitor reset init' \ + -ex '$(GDBCMD)' \ -ex 'r' \ - $< + $(ELF) clean: @rm -rf *.{bin,elf,map,lst,tgz,zip,hex} obj diff --git a/examples/stm32-freertos-tcp/main.c b/examples/stm32-freertos-tcp/main.c index e1100f3a..5d5dba63 100644 --- a/examples/stm32-freertos-tcp/main.c +++ b/examples/stm32-freertos-tcp/main.c @@ -4,7 +4,7 @@ #include "device.h" #include "mongoose.h" -static const char *s_debug_level = "2"; +static const char *s_debug_level = "4"; static const char *s_listening_address = "http://0.0.0.0:80"; // Event handler for the listening connection. @@ -20,6 +20,7 @@ static void server(void *args) { struct mg_mgr mgr; mg_log_set(s_debug_level); mg_mgr_init(&mgr); + LOG(LL_INFO, ("Starting Mongoose v%s", MG_VERSION)); // Tell the world mg_http_listen(&mgr, s_listening_address, cb, &mgr); // Web listener while (args == NULL) mg_mgr_poll(&mgr, 1000); // Infinite event loop mg_mgr_free(&mgr); // Unreachable @@ -27,23 +28,47 @@ static void server(void *args) { static void blinker(void *args) { uint16_t pin = ((char *) args)[0] == '1' ? LED2 : LED3; - int ms = pin == LED2 ? 750 : 1130; + int ms = pin == LED2 ? 3750 : 5130; for (;;) { gpio_toggle(pin); vTaskDelay(pdMS_TO_TICKS(ms)); - LOG(LL_INFO, ("blink %s", (char *) args)); + LOG(LL_INFO, ("blink %s, RAM: %u", (char *) args, xPortGetFreeHeapSize())); + // printf("blink %s, RAM: %u\n", (char *) args, xPortGetFreeHeapSize()); } } +// Start Mongoose server when network is ready +void vApplicationIPNetworkEventHook(eIPCallbackEvent_t ev) { + static bool mongoose_started = false; + LOG(LL_INFO, ("FreeRTOS net event %d, up: %d", ev, eNetworkUp)); + if (ev == eNetworkUp && mongoose_started == false) { + xTaskCreate(server, "server", 8192, NULL, configMAX_PRIORITIES - 1, NULL); + mongoose_started = true; + } +} + +static void init_heap(void) { + extern uint32_t _end, _estack; + uint8_t *ptr = (uint8_t *) ((((uint32_t) &_end) + 7) & ~7U); + uint32_t len = (uint32_t)((char *) &_estack - (char *) &_end); + HeapRegion_t regions[] = {{ptr, len}, {NULL, 0}}; + vPortDefineHeapRegions(regions); +} + int main(void) { init_hardware(); -#ifdef SEMIHOSTING - extern void initialise_monitor_handles(void); - initialise_monitor_handles(); -#endif - xTaskCreate(server, "server", 4096, NULL, configMAX_PRIORITIES - 1, NULL); - xTaskCreate(blinker, "blinker", 256, "1", configMAX_PRIORITIES - 1, NULL); - xTaskCreate(blinker, "blinker", 256, "2", configMAX_PRIORITIES - 1, NULL); + init_heap(); + + // Initialise networking task. Can be done before scheduler is started + static const uint8_t macaddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; + static const uint8_t ipaddr[4] = {192, 168, 0, 77}; + static const uint8_t netmask[4] = {255, 255, 255, 0}; + static const uint8_t dnsaddr[4] = {8, 8, 8, 8}; + static const uint8_t gwaddr[4] = {192, 168, 0, 1}; + FreeRTOS_IPInit(ipaddr, netmask, gwaddr, dnsaddr, macaddr); + + xTaskCreate(blinker, "blinker", 512, "1", configMAX_PRIORITIES - 1, NULL); + xTaskCreate(blinker, "blinker", 512, "2", configMAX_PRIORITIES - 1, NULL); vTaskStartScheduler(); // This blocks return 0; // Unreachable } @@ -53,14 +78,64 @@ uint32_t ulApplicationGetNextSequenceNumber(uint32_t a, uint16_t b, uint32_t c, uint16_t d) { return a ^ b ^ c ^ d; } + BaseType_t xApplicationGetRandomNumber(uint32_t *p) { *p = 0; return 1; } + uint32_t SystemCoreClock = 216000000; -uint32_t HAL_GetTick(void) { - return 250; -} uint32_t HAL_RCC_GetHCLKFreq(void) { return SystemCoreClock; } +// void assert_failed(void) { +//} + +uint32_t HAL_GetTick(void) { + return configTICK_RATE_HZ; +} + +#include "stm32f7xx_hal_conf.h" +#include "stm32fxx_hal_eth.h" +void HAL_ETH_MspInit( ETH_HandleTypeDef* heth ) { + GPIO_InitTypeDef GPIO_InitStructure; + if (heth->Instance == ETH) { + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + + GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Alternate = GPIO_AF11_ETH; + GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; + HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; + HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); + + HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); + HAL_NVIC_EnableIRQ(ETH_IRQn); + + __HAL_RCC_ETH_CLK_ENABLE(); + HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 ); + } +} + +int vLoggingPrintf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + char buf[100]; + int n = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + write(1, buf, n); + return n; +} + +void *_sbrk(ptrdiff_t incr) { + (void) incr; + return NULL; +} \ No newline at end of file diff --git a/examples/stm32-freertos-tcp/stm32f7/FreeRTOSConfig.h b/examples/stm32-freertos-tcp/stm32f7/FreeRTOSConfig.h index 0c0cfd51..a10cce63 100644 --- a/examples/stm32-freertos-tcp/stm32f7/FreeRTOSConfig.h +++ b/examples/stm32-freertos-tcp/stm32f7/FreeRTOSConfig.h @@ -1,31 +1,23 @@ #pragma once #define configUSE_PREEMPTION 1 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_TICKLESS_IDLE 0 -#define configCPU_CLOCK_HZ ((unsigned long) 72000000) +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configCPU_CLOCK_HZ ((unsigned long) 216000000) #define configSYSTICK_CLOCK_HZ (configCPU_CLOCK_HZ / 8) #define configTICK_RATE_HZ 250 #define configMAX_PRIORITIES 5 -#define configMINIMAL_STACK_SIZE 128 +#define configMINIMAL_STACK_SIZE 512 #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_TASK_NOTIFICATIONS 1 -#define configUSE_MUTEXES 0 -#define configUSE_RECURSIVE_MUTEXES 0 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 10 -#define configUSE_QUEUE_SETS 1 -#define configUSE_TIME_SLICING 0 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 0 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configQUEUE_REGISTRY_SIZE 8 #define configSUPPORT_STATIC_ALLOCATION 0 #define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configTOTAL_HEAP_SIZE ((size_t)(8 * 1024)) -#define configAPPLICATION_ALLOCATED_HEAP 0 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 @@ -40,8 +32,8 @@ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 1 -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY 3 +#define configUSE_TIMERS 0 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE @@ -51,7 +43,7 @@ #define configPRIO_BITS 4 #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 -#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 4 #define configKERNEL_INTERRUPT_PRIORITY \ (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) #define configMAX_SYSCALL_INTERRUPT_PRIORITY \ @@ -59,24 +51,18 @@ #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_xResumeFromISR 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetIdleTaskHandle 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xEventGroupSetBitFromISR 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 1 -#define INCLUDE_xTaskGetHandle 1 -#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTimerPendFunctionCall 0 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTaskGetSchedulerState 1 -#define vPortSVCHandler SVC_handler -#define xPortPendSVHandler pending_SV_handler -#define xPortSysTickHandler SysTick_handler +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler diff --git a/examples/stm32-freertos-tcp/stm32f7/FreeRTOSIPConfig.h b/examples/stm32-freertos-tcp/stm32f7/FreeRTOSIPConfig.h new file mode 100644 index 00000000..b2eff778 --- /dev/null +++ b/examples/stm32-freertos-tcp/stm32f7/FreeRTOSIPConfig.h @@ -0,0 +1,45 @@ +#pragma once +#define FREERTOS_IP_CONFIG_H + +#ifndef ipconfigHAS_DEBUG_PRINTF +#define ipconfigHAS_DEBUG_PRINTF 1 +#endif +#if (ipconfigHAS_DEBUG_PRINTF == 1) +#define FreeRTOS_debug_printf(X) vLoggingPrintf X +#endif +#ifndef ipconfigHAS_PRINTF +#define ipconfigHAS_PRINTF 1 +#endif +#if (ipconfigHAS_PRINTF == 1) +#define FreeRTOS_printf(X) vLoggingPrintf X +#endif + +#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN +#define ipconfigREPLY_TO_INCOMING_PINGS 1 +#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM (1) +#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM (1) +#define ipconfigZERO_COPY_RX_DRIVER (1) +#define ipconfigZERO_COPY_TX_DRIVER (1) +#define ipconfigIP_TASK_PRIORITY 4 +#define niEMAC_HANDLER_TASK_PRIORITY 5 +#define ipconfigIPERF_PRIORITY_IPERF_TASK 6 +#define ipconfigIP_TASK_STACK_SIZE_WORDS (configMINIMAL_STACK_SIZE * 5) +extern UBaseType_t uxRand(); +#define ipconfigRAND32() uxRand() +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 +#define ipconfigUSE_DHCP 0 +#define ipconfigDHCP_REGISTER_HOSTNAME 0 +#define ipconfigDHCP_USES_UNICAST 1 +#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD (pdMS_TO_TICKS(30000)) +#define ipconfigARP_CACHE_ENTRIES 6 +#define ipconfigMAX_ARP_RETRANSMISSIONS (5) +#define ipconfigMAX_ARP_AGE 150 +#define ipconfigINCLUDE_FULL_INET_ADDR 0 +#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 20 +#define ipconfigEVENT_QUEUE_LENGTH (ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5) +#define ipconfigUDP_TIME_TO_LIVE 128 +#define ipconfigTCP_TIME_TO_LIVE 128 +#define ipconfigUSE_TCP 1 +#define ipconfigSUPPORT_SELECT_FUNCTION 1 +#define ipconfigUSE_TCP_WIN 0 +#define ipconfigNETWORK_MTU 1500 \ No newline at end of file diff --git a/examples/stm32-freertos-tcp/stm32f7/boot.s b/examples/stm32-freertos-tcp/stm32f7/boot.s index 2b5df65d..a76cdb63 100644 --- a/examples/stm32-freertos-tcp/stm32f7/boot.s +++ b/examples/stm32-freertos-tcp/stm32f7/boot.s @@ -1,6 +1,10 @@ .cpu cortex-m7 +.fpu softvfp +.syntax unified .thumb +.section .vectortab,"a",%progbits + // Cortex-M7 interrupt handlers .word _estack // 0 Stack top address .word _reset // 1 Reset .word pass // 2 NMI @@ -8,29 +12,33 @@ .word halt // 4 MM Fault .word halt // 5 Bus Fault .word halt // 6 Usage Fault -.word halt // 7 RESERVED -.word halt // 8 RESERVED -.word halt // 9 RESERVED -.word halt // 10 RESERVED -.word SVC_handler // 11 SV call +.word 0 // 7 RESERVED +.word 0 // 8 RESERVED +.word 0 // 9 RESERVED +.word 0 // 10 RESERVED +.word SVC_Handler // 11 SV call .word halt // 12 Debug reserved -.word halt // 13 RESERVED -.word pending_SV_handler // 14 PendSV -.word SysTick_handler // 15 SysTick -.word pass // 16 IRQ0 -.word halt // 17 IRQ1 - // On to IRQ67 +.word 0 // 13 RESERVED +.word PendSV_Handler // 14 PendSV +.word SysTick_Handler // 15 SysTick + // 98 STM32 handlers .word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt .word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt .word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt .word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt .word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt +.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt +.word halt,ETH_IRQHandler,halt,halt,halt,halt,halt,halt,halt,halt +.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt +.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt +.word halt,halt,halt,halt,halt,halt,halt,halt -halt: b halt -pass: BX lr - -.thumb_func +.section .text .global _reset _reset: - bl main - b . + ldr sp, =_estack + bl main + b . + +halt: b . +pass: bx lr diff --git a/examples/stm32-freertos-tcp/stm32f7/device.h b/examples/stm32-freertos-tcp/stm32f7/device.h index 83ef939f..69eae197 100644 --- a/examples/stm32-freertos-tcp/stm32f7/device.h +++ b/examples/stm32-freertos-tcp/stm32f7/device.h @@ -4,6 +4,7 @@ // Memory map: 2.2.2 #include "stm32f746xx.h" +//#include "stm32f7xx_hal.h" #include "string.h" #define BIT(x) ((uint32_t) 1 << (x)) @@ -24,22 +25,14 @@ static inline void gpio_off(uint16_t pin) { static inline void gpio_toggle(uint16_t pin) { gpio_bank(pin)->ODR ^= BIT(pin & 255); } -enum { GPIO_MODE_IN, GPIO_MODE_OUT, GPIO_MODE_AF, GPIO_MODE_ANALOG }; -enum { GPIO_TYPE_PP, GPIO_TYPE_OD }; +enum { GPIO_IN, GPIO_OUT, GPIO_AF, GPIO_ANALOG }; +enum { GPIO_PP, GPIO_OD }; enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH, GPIO_SPEED_INSANE }; enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN }; -enum { - OUTPUT = GPIO_MODE_OUT | (GPIO_TYPE_PP << 2) | (GPIO_SPEED_MEDIUM << 3) | - (GPIO_PULL_NONE << 5), - INPUT = GPIO_MODE_IN | (GPIO_TYPE_PP << 2) | (GPIO_SPEED_MEDIUM << 3) | - (GPIO_PULL_NONE << 5), - INPUT_PULLUP = GPIO_MODE_IN | (GPIO_TYPE_PP << 2) | (GPIO_SPEED_MEDIUM << 3) | - (GPIO_PULL_UP << 5), -}; -static inline void gpio_init(uint16_t pin, uint8_t state) { +static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type, + uint8_t speed, uint8_t pull, uint8_t af) { GPIO_TypeDef *gpio = gpio_bank(pin); - uint8_t n = pin & 255, mode = state & 3, type = (state >> 2) & 1, - speed = (state >> 3) & 3, pupdr = (state >> 5) & 3; + uint8_t n = pin & 255; gpio->MODER &= ~(3 << (n * 2)); gpio->MODER |= (mode << (n * 2)); gpio->OTYPER &= ~(1 << n); @@ -47,15 +40,14 @@ static inline void gpio_init(uint16_t pin, uint8_t state) { gpio->OSPEEDR &= ~(3 << (n * 2)); gpio->OSPEEDR |= (speed << (n * 2)); gpio->PUPDR &= ~(3 << (n * 2)); - gpio->PUPDR |= (pupdr << (n * 2)); -} - -static inline void init_ram(void) { - extern uint32_t __bss_start__, __bss_end__; - extern uint32_t _data_start, _data_end, _data_flash_start; - memset(&__bss_start__, 0, ((char *) &__bss_end__ - (char *) &__bss_start__)); - memcpy(&_data_start, &_data_flash_start, - ((char *) &_data_end - (char *) &_data_start)); + gpio->PUPDR |= (pull << (n * 2)); + if (n < 8) { + gpio->AFR[0] &= 15 << (n * 4); + gpio->AFR[0] |= af << (n * 4); + } else { + gpio->AFR[1] &= 15 << (n * 4); + gpio->AFR[1] |= af << (n * 4); + } } static inline void init_clock(void) { @@ -83,6 +75,11 @@ static inline void init_clock(void) { RCC->CFGR &= ~RCC_CFGR_SW; // Select the main PLL RCC->CFGR |= RCC_CFGR_SW_PLL; // as system clock source while ((RCC->CFGR & RCC_CFGR_SWS) == 0) (void) 0; + + // Ethernet clock + RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN; + RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACTXEN; + RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACRXEN; } #define delay(ms) vTaskDelay(pdMS_TO_TICKS(ms)) @@ -95,11 +92,44 @@ static inline void led_toggle(void) { gpio_toggle(LED2); } +static inline void init_ram(void) { + extern uint32_t _sbss, _ebss; + extern uint32_t _sdata, _edata, _sidata; + memset(&_sbss, 0, ((char *) &_ebss - (char *) &_sbss)); + memcpy(&_sdata, &_sidata, ((char *) &_edata - (char *) &_sdata)); +} + static inline void init_hardware(void) { init_ram(); init_clock(); - RCC->AHB1ENR |= BIT(0) | BIT(1) | BIT(2); // Init GPIO banks A,B,C - gpio_init(LED1, OUTPUT); - gpio_init(LED2, OUTPUT); - gpio_init(LED3, OUTPUT); + RCC->AHB1ENR |= BIT(0) | BIT(1) | BIT(2) | BIT(6); // Init GPIO banks A,B,C,G + gpio_init(LED1, GPIO_OUT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, 0); + gpio_init(LED2, GPIO_OUT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, 0); + gpio_init(LED3, GPIO_OUT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, 0); + gpio_on(LED2); +#if 0 + uint16_t a1 = PIN('A', 1), a2 = PIN('A', 2), a7 = PIN('A', 7); + gpio_init(a1, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(a2, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(a7, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + + uint16_t b13 = PIN('B', 13); + gpio_init(b13, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + + uint16_t c1 = PIN('C', 1), c4 = PIN('C', 4), c5 = PIN('C', 5); + gpio_init(c1, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(c4, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(c5, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + + uint16_t g2 = PIN('G', 2), g11 = PIN('G', 11), g13 = PIN('G', 13), + g14 = PIN('G', 14); + gpio_init(g2, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(g11, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(g13, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + gpio_init(g14, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11); + + HAL_Init(); + HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); + HAL_NVIC_EnableIRQ(ETH_IRQn); +#endif } diff --git a/examples/stm32-freertos-tcp/stm32f7/link.ld b/examples/stm32-freertos-tcp/stm32f7/link.ld index 36672c67..f12e98a7 100644 --- a/examples/stm32-freertos-tcp/stm32f7/link.ld +++ b/examples/stm32-freertos-tcp/stm32f7/link.ld @@ -1,25 +1,32 @@ ENTRY(_reset); MEMORY { - ram(rwx) : ORIGIN = 0x20000000, LENGTH = 320k + ram(rwx) : ORIGIN = 0x20000000, LENGTH = 307k rom(rx) : ORIGIN = 0x08000000, LENGTH = 1024k } -_estack = 0x20000000 + 320k; +_estack = ORIGIN(ram) + LENGTH(ram); /* boot.s and init_heap() */ SECTIONS { - .text : { *(.text*) } > rom - .rodata : { *(.rodata*) } > rom - - .bss : { - __bss_start__ = .; - *(.bss SORT(.bss.*) COMMON) - __bss_end__ = .; - } > ram + .vectortab : { KEEP(*(.vectortab)) } > rom + .text : { *(.text*) } > rom + .rodata : { *(.rodata*) } > rom .data : { - _data_start = .; + _sdata = .; /* for init_ram() */ + *(.first_data) *(.data SORT(.data.*)) - _data_end = .; + _edata = .; /* for init_ram() */ } > ram AT > rom - _data_flash_start = LOADADDR(.data); + _sidata = LOADADDR(.data); + + .bss : { + _sbss = .; /* for init_ram() */ + __bss_start__ = _sbss; /* for libc */ + *(.bss SORT(.bss.*) COMMON) + _ebss = .; /* for init_ram() */ + __bss_end__ = _ebss; /* for libc */ + } > ram + + . = ALIGN(8); + end = .; /* for syscalls.c */ + _end = .; /* for cmsis_gcc.h and init_ram() */ + __end__ = .; /* for libc */ } -__end__ = _data_end; -end = _data_end; diff --git a/examples/stm32-freertos-tcp/stm32f7/port.c b/examples/stm32-freertos-tcp/stm32f7/port.c deleted file mode 100644 index e30e0767..00000000 --- a/examples/stm32-freertos-tcp/stm32f7/port.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/*----------------------------------------------------------- -* Implementation of functions defined in portable.h for the ARM CM7 port. -*----------------------------------------------------------*/ - -/* Scheduler includes. */ -#include "FreeRTOS.h" -#include "task.h" - -#ifndef __VFP_FP__ - #error This port can only be used when the project options are configured to enable hardware floating point support. -#endif - -#ifndef configSYSTICK_CLOCK_HZ - #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ - /* Ensure the SysTick is clocked at the same frequency as the core. */ - #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) -#else - -/* The way the SysTick is clocked is not modified in case it is not the same - * as the core. */ - #define portNVIC_SYSTICK_CLK_BIT ( 0 ) -#endif - -/* Constants required to manipulate the core. Registers first... */ -#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) -#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) -#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) -#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) -/* ...then bits in the registers. */ -#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) -#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) -#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) -#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) -#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) - -#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) -#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) - -/* Constants required to check the validity of an interrupt priority. */ -#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) -#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) -#define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) -#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) -#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) -#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) -#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) -#define portPRIGROUP_SHIFT ( 8UL ) - -/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ -#define portVECTACTIVE_MASK ( 0xFFUL ) - -/* Constants required to manipulate the VFP. */ -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ -#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) - -/* Constants required to set up the initial stack. */ -#define portINITIAL_XPSR ( 0x01000000 ) -#define portINITIAL_EXC_RETURN ( 0xfffffffd ) - -/* The systick is a 24-bit counter. */ -#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) - -/* For strict compliance with the Cortex-M spec the task start address should - * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ -#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) - -/* A fiddle factor to estimate the number of SysTick counts that would have - * occurred while the SysTick counter is stopped during tickless idle - * calculations. */ -#define portMISSED_COUNTS_FACTOR ( 45UL ) - -/* Let the user override the pre-loading of the initial LR with the address of - * prvTaskExitError() in case it messes up unwinding of the stack in the - * debugger. */ -#ifdef configTASK_RETURN_ADDRESS - #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS -#else - #define portTASK_RETURN_ADDRESS prvTaskExitError -#endif - -/* - * Setup the timer to generate the tick interrupts. The implementation in this - * file is weak to allow application writers to change the timer used to - * generate the tick interrupt. - */ -void vPortSetupTimerInterrupt( void ); - -/* - * Exception handlers. - */ -void xPortPendSVHandler( void ) __attribute__( ( naked ) ); -void xPortSysTickHandler( void ); -void vPortSVCHandler( void ) __attribute__( ( naked ) ); - -/* - * Start first task is a separate function so it can be tested in isolation. - */ -static void prvPortStartFirstTask( void ) __attribute__( ( naked ) ); - -/* - * Function to enable the VFP. - */ -static void vPortEnableVFP( void ) __attribute__( ( naked ) ); - -/* - * Used to catch tasks that attempt to return from their implementing function. - */ -static void prvTaskExitError( void ); - -/*-----------------------------------------------------------*/ - -/* Each task maintains its own interrupt status in the critical nesting - * variable. */ -static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; - -/* - * The number of SysTick increments that make up one tick period. - */ -#if ( configUSE_TICKLESS_IDLE == 1 ) - static uint32_t ulTimerCountsForOneTick = 0; -#endif /* configUSE_TICKLESS_IDLE */ - -/* - * The maximum number of tick periods that can be suppressed is limited by the - * 24 bit resolution of the SysTick timer. - */ -#if ( configUSE_TICKLESS_IDLE == 1 ) - static uint32_t xMaximumPossibleSuppressedTicks = 0; -#endif /* configUSE_TICKLESS_IDLE */ - -/* - * Compensate for the CPU cycles that pass while the SysTick is stopped (low - * power functionality only. - */ -#if ( configUSE_TICKLESS_IDLE == 1 ) - static uint32_t ulStoppedTimerCompensation = 0; -#endif /* configUSE_TICKLESS_IDLE */ - -/* - * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure - * FreeRTOS API functions are not called from interrupts that have been assigned - * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. - */ -#if ( configASSERT_DEFINED == 1 ) - static uint8_t ucMaxSysCallPriority = 0; - static uint32_t ulMaxPRIGROUPValue = 0; - static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; -#endif /* configASSERT_DEFINED */ - -/*-----------------------------------------------------------*/ - -/* - * See header file for description. - */ -StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters ) -{ - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - - /* Offset added to account for the way the MCU uses the stack on entry/exit - * of interrupts, and to ensure alignment. */ - pxTopOfStack--; - - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - - /* Save code space by skipping register initialisation. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - - /* A save method is being used that requires each task to maintain its - * own exec return value. */ - pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; - - pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ - - return pxTopOfStack; -} -/*-----------------------------------------------------------*/ - -static void prvTaskExitError( void ) -{ - volatile uint32_t ulDummy = 0; - - /* A function that implements a task must not exit or attempt to return to - * its caller as there is nothing to return to. If a task wants to exit it - * should instead call vTaskDelete( NULL ). - * - * Artificially force an assert() to be triggered if configASSERT() is - * defined, then stop here so application writers can catch the error. */ - configASSERT( uxCriticalNesting == ~0UL ); - portDISABLE_INTERRUPTS(); - - while( ulDummy == 0 ) - { - /* This file calls prvTaskExitError() after the scheduler has been - * started to remove a compiler warning about the function being defined - * but never called. ulDummy is used purely to quieten other warnings - * about code appearing after this function is called - making ulDummy - * volatile makes the compiler think the function could return and - * therefore not output an 'unreachable code' warning for code that appears - * after it. */ - } -} -/*-----------------------------------------------------------*/ - -void vPortSVCHandler( void ) -{ - __asm volatile ( - " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ - " ldr r1, [r3] \n"/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ - " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */ - " ldmia r0!, {r4-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ - " msr psp, r0 \n"/* Restore the task stack pointer. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n" - " bx r14 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - ); -} -/*-----------------------------------------------------------*/ - -static void prvPortStartFirstTask( void ) -{ - /* Start the first task. This also clears the bit that indicates the FPU is - * in use in case the FPU was used before the scheduler was started - which - * would otherwise result in the unnecessary leaving of space in the SVC stack - * for lazy saving of FPU registers. */ - __asm volatile ( - " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ - " ldr r0, [r0] \n" - " ldr r0, [r0] \n" - " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ - " mov r0, #0 \n"/* Clear the bit that indicates the FPU is in use, see comment above. */ - " msr control, r0 \n" - " cpsie i \n"/* Globally enable interrupts. */ - " cpsie f \n" - " dsb \n" - " isb \n" - " svc 0 \n"/* System call to start first task. */ - " nop \n" - " .ltorg \n" - ); -} -/*-----------------------------------------------------------*/ - -/* - * See header file for description. - */ -BaseType_t xPortStartScheduler( void ) -{ - /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. - * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ - configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); - - #if ( configASSERT_DEFINED == 1 ) - { - volatile uint32_t ulOriginalPriority; - volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); - volatile uint8_t ucMaxPriorityValue; - - /* Determine the maximum priority from which ISR safe FreeRTOS API - * functions can be called. ISR safe functions are those that end in - * "FromISR". FreeRTOS maintains separate thread and ISR API functions to - * ensure interrupt entry is as fast and simple as possible. - * - * Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; - - /* Determine the number of priority bits available. First write to all - * possible bits. */ - *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; - - /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = *pucFirstUserPriorityRegister; - - /* Use the same mask on the maximum system call priority. */ - ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; - - /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; - - while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) - { - ulMaxPRIGROUPValue--; - ucMaxPriorityValue <<= ( uint8_t ) 0x01; - } - - #ifdef __NVIC_PRIO_BITS - { - /* Check the CMSIS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* Check the FreeRTOS configuration that defines the number of - * priority bits matches the number of priority bits actually queried - * from the hardware. */ - configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); - } - #endif - - /* Shift the priority group value back to its position within the AIRCR - * register. */ - ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; - ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; - - /* Restore the clobbered interrupt priority register to its original - * value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; - } - #endif /* conifgASSERT_DEFINED */ - - /* Make PendSV and SysTick the lowest priority interrupts. */ - portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; - portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - - /* Start the timer that generates the tick ISR. Interrupts are disabled - * here already. */ - vPortSetupTimerInterrupt(); - - /* Initialise the critical nesting count ready for the first task. */ - uxCriticalNesting = 0; - - /* Ensure the VFP is enabled - it should be anyway. */ - vPortEnableVFP(); - - /* Lazy save always. */ - *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; - - /* Start the first task. */ - prvPortStartFirstTask(); - - /* Should never get here as the tasks will now be executing! Call the task - * exit error function to prevent compiler warnings about a static function - * not being called in the case that the application writer overrides this - * functionality by defining configTASK_RETURN_ADDRESS. Call - * vTaskSwitchContext() so link time optimisation does not remove the - * symbol. */ - vTaskSwitchContext(); - prvTaskExitError(); - - /* Should not get here! */ - return 0; -} -/*-----------------------------------------------------------*/ - -void vPortEndScheduler( void ) -{ - /* Not implemented in ports where there is nothing to return to. - * Artificially force an assert. */ - configASSERT( uxCriticalNesting == 1000UL ); -} -/*-----------------------------------------------------------*/ - -void vPortEnterCritical( void ) -{ - portDISABLE_INTERRUPTS(); - uxCriticalNesting++; - - /* This is not the interrupt safe version of the enter critical function so - * assert() if it is being called from an interrupt context. Only API - * functions that end in "FromISR" can be used in an interrupt. Only assert if - * the critical nesting count is 1 to protect against recursive calls if the - * assert function also uses a critical section. */ - if( uxCriticalNesting == 1 ) - { - configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); - } -} -/*-----------------------------------------------------------*/ - -void vPortExitCritical( void ) -{ - configASSERT( uxCriticalNesting ); - uxCriticalNesting--; - - if( uxCriticalNesting == 0 ) - { - portENABLE_INTERRUPTS(); - } -} -/*-----------------------------------------------------------*/ - -void xPortPendSVHandler( void ) -{ - /* This is a naked function. */ - - __asm volatile - ( - " mrs r0, psp \n" - " isb \n" - " \n" - " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ - " ldr r2, [r3] \n" - " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" - " \n" - " stmdb r0!, {r4-r11, r14} \n"/* Save the core registers. */ - " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ - " \n" - " stmdb sp!, {r0, r3} \n" - " mov r0, %0 \n" - " cpsid i \n"/* Errata workaround. */ - " msr basepri, r0 \n" - " dsb \n" - " isb \n" - " cpsie i \n"/* Errata workaround. */ - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" - " msr basepri, r0 \n" - " ldmia sp!, {r0, r3} \n" - " \n" - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */ - " ldr r0, [r1] \n" - " \n" - " ldmia r0!, {r4-r11, r14} \n"/* Pop the core registers. */ - " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" - " \n" - " msr psp, r0 \n" - " isb \n" - " \n" - #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ - #if WORKAROUND_PMU_CM001 == 1 - " push { r14 } \n" - " pop { pc } \n" - #endif - #endif - " \n" - " bx r14 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) - ); -} -/*-----------------------------------------------------------*/ - -void xPortSysTickHandler( void ) -{ - /* The SysTick runs at the lowest interrupt priority, so when this interrupt - * executes all interrupts must be unmasked. There is therefore no need to - * save and then restore the interrupt mask value as its value is already - * known. */ - portDISABLE_INTERRUPTS(); - { - /* Increment the RTOS tick. */ - if( xTaskIncrementTick() != pdFALSE ) - { - /* A context switch is required. Context switching is performed in - * the PendSV interrupt. Pend the PendSV interrupt. */ - portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; - } - } - portENABLE_INTERRUPTS(); -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_TICKLESS_IDLE == 1 ) - - __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) - { - uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements; - TickType_t xModifiableIdleTime; - - /* Make sure the SysTick reload value does not overflow the counter. */ - if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) - { - xExpectedIdleTime = xMaximumPossibleSuppressedTicks; - } - - /* Stop the SysTick momentarily. The time the SysTick is stopped for - * is accounted for as best it can be, but using the tickless mode will - * inevitably result in some tiny drift of the time maintained by the - * kernel with respect to calendar time. */ - portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; - - /* Calculate the reload value required to wait xExpectedIdleTime - * tick periods. -1 is used because this code will execute part way - * through one of the tick periods. */ - ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); - - if( ulReloadValue > ulStoppedTimerCompensation ) - { - ulReloadValue -= ulStoppedTimerCompensation; - } - - /* Enter a critical section but don't use the taskENTER_CRITICAL() - * method as that will mask interrupts that should exit sleep mode. */ - __asm volatile ( "cpsid i" ::: "memory" ); - __asm volatile ( "dsb" ); - __asm volatile ( "isb" ); - - /* If a context switch is pending or a task is waiting for the scheduler - * to be unsuspended then abandon the low power entry. */ - if( eTaskConfirmSleepModeStatus() == eAbortSleep ) - { - /* Restart from whatever is left in the count register to complete - * this tick period. */ - portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; - - /* Restart SysTick. */ - portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; - - /* Reset the reload register to the value required for normal tick - * periods. */ - portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; - - /* Re-enable interrupts - see comments above the cpsid instruction() - * above. */ - __asm volatile ( "cpsie i" ::: "memory" ); - } - else - { - /* Set the new reload value. */ - portNVIC_SYSTICK_LOAD_REG = ulReloadValue; - - /* Clear the SysTick count flag and set the count value back to - * zero. */ - portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; - - /* Restart SysTick. */ - portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; - - /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can - * set its parameter to 0 to indicate that its implementation contains - * its own wait for interrupt or wait for event instruction, and so wfi - * should not be executed again. However, the original expected idle - * time variable must remain unmodified, so a copy is taken. */ - xModifiableIdleTime = xExpectedIdleTime; - configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); - - if( xModifiableIdleTime > 0 ) - { - __asm volatile ( "dsb" ::: "memory" ); - __asm volatile ( "wfi" ); - __asm volatile ( "isb" ); - } - - configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); - - /* Re-enable interrupts to allow the interrupt that brought the MCU - * out of sleep mode to execute immediately. see comments above - * __disable_interrupt() call above. */ - __asm volatile ( "cpsie i" ::: "memory" ); - __asm volatile ( "dsb" ); - __asm volatile ( "isb" ); - - /* Disable interrupts again because the clock is about to be stopped - * and interrupts that execute while the clock is stopped will increase - * any slippage between the time maintained by the RTOS and calendar - * time. */ - __asm volatile ( "cpsid i" ::: "memory" ); - __asm volatile ( "dsb" ); - __asm volatile ( "isb" ); - - /* Disable the SysTick clock without reading the - * portNVIC_SYSTICK_CTRL_REG register to ensure the - * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, - * the time the SysTick is stopped for is accounted for as best it can - * be, but using the tickless mode will inevitably result in some tiny - * drift of the time maintained by the kernel with respect to calendar - * time*/ - portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); - - /* Determine if the SysTick clock has already counted to zero and - * been set back to the current reload value (the reload back being - * correct for the entire expected idle time) or if the SysTick is yet - * to count to zero (in which case an interrupt other than the SysTick - * must have brought the system out of sleep mode). */ - if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) - { - uint32_t ulCalculatedLoadValue; - - /* The tick interrupt is already pending, and the SysTick count - * reloaded with ulReloadValue. Reset the - * portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick - * period. */ - ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); - - /* Don't allow a tiny value, or values that have somehow - * underflowed because the post sleep hook did something - * that took too long. */ - if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) - { - ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); - } - - portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; - - /* As the pending tick will be processed as soon as this - * function exits, the tick value maintained by the tick is stepped - * forward by one less than the time spent waiting. */ - ulCompleteTickPeriods = xExpectedIdleTime - 1UL; - } - else - { - /* Something other than the tick interrupt ended the sleep. - * Work out how long the sleep lasted rounded to complete tick - * periods (not the ulReload value which accounted for part - * ticks). */ - ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; - - /* How many complete tick periods passed while the processor - * was waiting? */ - ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; - - /* The reload value is set to whatever fraction of a single tick - * period remains. */ - portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; - } - - /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG - * again, then set portNVIC_SYSTICK_LOAD_REG back to its standard - * value. */ - portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; - portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; - vTaskStepTick( ulCompleteTickPeriods ); - portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; - - /* Exit with interrupts enabled. */ - __asm volatile ( "cpsie i" ::: "memory" ); - } - } - -#endif /* #if configUSE_TICKLESS_IDLE */ -/*-----------------------------------------------------------*/ - -/* - * Setup the systick timer to generate the tick interrupts at the required - * frequency. - */ -__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) -{ - /* Calculate the constants required to configure the tick interrupt. */ - #if ( configUSE_TICKLESS_IDLE == 1 ) - { - ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); - xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; - ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); - } - #endif /* configUSE_TICKLESS_IDLE */ - - /* Stop and clear the SysTick. */ - portNVIC_SYSTICK_CTRL_REG = 0UL; - portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; - - /* Configure SysTick to interrupt at the requested rate. */ - portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; - portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); -} -/*-----------------------------------------------------------*/ - -/* This is a naked function. */ -static void vPortEnableVFP( void ) -{ - __asm volatile - ( - " ldr.w r0, =0xE000ED88 \n"/* The FPU enable bits are in the CPACR. */ - " ldr r1, [r0] \n" - " \n" - " orr r1, r1, #( 0xf << 20 ) \n"/* Enable CP10 and CP11 coprocessors, then save back. */ - " str r1, [r0] \n" - " bx r14 \n" - " .ltorg \n" - ); -} -/*-----------------------------------------------------------*/ - -#if ( configASSERT_DEFINED == 1 ) - - void vPortValidateInterruptPriority( void ) - { - uint32_t ulCurrentInterrupt; - uint8_t ucCurrentPriority; - - /* Obtain the number of the currently executing interrupt. */ - __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); - - /* Is the interrupt number a user defined interrupt? */ - if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) - { - /* Look up the interrupt's priority. */ - ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; - - /* The following assertion will fail if a service routine (ISR) for - * an interrupt that has been assigned a priority above - * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API - * function. ISR safe FreeRTOS API functions must *only* be called - * from interrupts that have been assigned a priority at or below - * configMAX_SYSCALL_INTERRUPT_PRIORITY. - * - * Numerically low interrupt priority numbers represent logically high - * interrupt priorities, therefore the priority of the interrupt must - * be set to a value equal to or numerically *higher* than - * configMAX_SYSCALL_INTERRUPT_PRIORITY. - * - * Interrupts that use the FreeRTOS API must not be left at their - * default priority of zero as that is the highest possible priority, - * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, - * and therefore also guaranteed to be invalid. - * - * FreeRTOS maintains separate thread and ISR API functions to ensure - * interrupt entry is as fast and simple as possible. - * - * The following links provide detailed information: - * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ - configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); - } - - /* Priority grouping: The interrupt controller (NVIC) allows the bits - * that define each interrupt's priority to be split between bits that - * define the interrupt's pre-emption priority bits and bits that define - * the interrupt's sub-priority. For simplicity all bits must be defined - * to be pre-emption priority bits. The following assertion will fail if - * this is not the case (if some bits represent a sub-priority). - * - * If the application only uses CMSIS libraries for interrupt - * configuration then the correct setting can be achieved on all Cortex-M - * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the - * scheduler. Note however that some vendor specific peripheral libraries - * assume a non-zero priority group setting, in which cases using a value - * of zero will result in unpredictable behaviour. */ - configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); - } - -#endif /* configASSERT_DEFINED */ diff --git a/mongoose.c b/mongoose.c index 9fd63f90..5263efcc 100644 --- a/mongoose.c +++ b/mongoose.c @@ -22,17 +22,6 @@ #endif void mg_connect_resolved(struct mg_connection *); -#if MG_ARCH == MG_ARCH_FREERTOS_TCP -static inline void *mg_calloc(int cnt, size_t size) { - void *p = pvPortMalloc(cnt * size); - if (p != NULL) memset(p, 0, size); - return p; -} -#define calloc(a, b) mg_calloc((a), (b)) -#define malloc(a) pvPortMalloc(a) -#define free(a) vPortFree(a) -#endif - #ifdef MG_ENABLE_LINES #line 1 "src/base64.c" #endif @@ -1065,7 +1054,7 @@ DIR *opendir(const char *name) { if (name == NULL) { SetLastError(ERROR_BAD_ARGUMENTS); - } else if ((d = (DIR *) malloc(sizeof(*d))) == NULL) { + } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0])); @@ -1510,9 +1499,9 @@ int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { io->buf = NULL; io->len = io->size = 0; } else if (new_size != io->size) { - // NOTE(lsm): do not use realloc here. Use malloc/free only, to ease the + // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the // porting to some obscure platforms like FreeRTOS - void *p = malloc(new_size); + void *p = calloc(1, new_size); if (p != NULL) { size_t len = new_size < io->len ? new_size : io->len; if (len > 0) memcpy(p, io->buf, len); @@ -1630,207 +1619,6 @@ void mg_log_set_callback(void (*fn)(const void *, int, void *), void *param) { #endif #endif -#ifdef MG_ENABLE_LINES -#line 1 "src/lwip.c" -#endif - - - - - - - -#if MG_ENABLE_LWIP -#include -#include - -static void tcp_error_cb(void *arg, err_t err) { - struct mg_connection *c = (struct mg_connection *) arg; - mg_error(c, "%p err %ld", c->fd, err); -} - -static err_t connect_cb(void *arg, struct tcp_pcb *pcb, err_t err) { - struct mg_connection *c = (struct mg_connection *) arg; - LOG(LL_DEBUG, ("err %ld, arg %p, pcb %p", err, arg, pcb)); - c->is_connecting = 0; - if (err != ERR_OK) mg_error(c, "%p err %d", c->fd, err); - return err; -} - -static err_t tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, - err_t err) { - struct mg_connection *c = (struct mg_connection *) arg; - LOG(LL_DEBUG, - ("err %ld, pbuf %p/%d, io.len %d, io.size %d", err, p, - p == NULL ? 0 : (int) p->len, (int) c->recv.len, (int) c->recv.size)); - if (err == ERR_OK && p != NULL) { -#if 0 - if (s->io.size < s->io.len + p->len) { - char *buf = realloc(s->io.buf, s->io.len + p->len); - if (buf != NULL) { - s->io.buf = buf; - s->io.size = s->io.len + p->len; - } else { - return ERR_MEM; - } - } - // MLOG(LL_DEBUG, " --> cpy, %p %p", s->io.buf, p->payload); - memcpy(s->io.buf + s->io.len, p->payload, p->len); - s->io.len += p->len; -#endif - tcp_recved(pcb, p->len); - pbuf_free(p); - return err; - } else { - // rmsock(s); - return ERR_ABRT; - } -} - -static void udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, uint16_t port) { - LOG(LL_DEBUG, - ("%p %p pbuf %p/%d port %hu", arg, pcb, p, p == NULL ? 0 : p->len, port)); -} - -static err_t tcp_sent_cb(void *arg, struct tcp_pcb *pcb, uint16_t len) { - LOG(LL_DEBUG, ("%p %d", pcb, (int) len)); - return ERR_OK; -} - -#if 0 -static int ll_write(struct mg_connection *c, const void *buf, int len, - int *fail) { - int n = c->is_tls ? mg_tls_send(c, buf, len, fail) - : mg_sock_send(c, buf, len, fail); - LOG(*fail ? LL_ERROR : LL_VERBOSE_DEBUG, - ("%p %c%c%c %d/%d %d", c->fd, c->is_tls ? 'T' : 't', - c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len, - MG_SOCK_ERRNO)); - if (n > 0 && c->is_hexdumping) mg_hexdump(c, "->", buf, n); - return n; -} -#endif - -int mg_send(struct mg_connection *c, const void *buf, size_t len) { - if (c->is_udp) { - struct udp_pcb *pcb = (struct udp_pcb *) c->fd; - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (p != NULL) { - // p->payload = (void *) buf; - memcpy(p->payload, buf, len); - err_t err = udp_send(pcb, p); - pbuf_free(p); - LOG(LL_DEBUG, - ("%lu UDP %d bytes -> %x:%hu, err %ld", c->id, (int) len, - (unsigned) *(uint32_t *) &pcb->remote_ip, pcb->remote_port, err)); - if (err != ERR_OK) mg_error(c, "%p err %d", c->fd, err); - } else { - mg_error(c, "%p pbuf OOM", c->fd); - } - } else if (c->is_connecting) { - mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE); - } else { - } -#if 0 - int fail, n = c->is_udp - ? ll_write(c, buf, (SOCKET) len, &fail) - : mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE); - return n; -#endif - return 0; -} - -static struct mg_connection *mg_mkconn(const char *url) { - struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c)); - typedef void *(*new_t)(void); - int is_udp = strncmp(url, "udp:", 4) == 0; - if (c == NULL) { - LOG(LL_ERROR, ("%s %s", url, "OOM")); - } else if ((c->fd = (is_udp ? (new_t) udp_new : (new_t) tcp_new)()) == NULL) { - LOG(LL_ERROR, ("%s new", url)); - free(c); - c = NULL; - } else { - c->is_udp = is_udp; - } - return c; -} - -struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, - mg_event_handler_t fn, void *fn_data) { - struct mg_connection *c = mg_mkconn(url); - struct mg_str host = mg_url_host(url); - if (c == NULL) return c; - c->next = mgr->conns; - mgr->conns = c; - // mg_set_non_blocking_mode((SOCKET) c->fd); - c->is_client = 1; - c->peer.port = mg_htons(mg_url_port(url)); - c->fn = fn; - c->fn_data = fn_data; - c->is_hexdumping = 1; - if (c->is_udp) { - udp_bind(c->fd, IP_ADDR_ANY, 0); - udp_recv(c->fd, udp_recv_cb, c); - } else { - tcp_arg(c->fd, c); - tcp_err(c->fd, tcp_error_cb); - tcp_sent(c->fd, tcp_sent_cb); - tcp_recv(c->fd, tcp_recv_cb); - tcp_bind(c->fd, IP_ADDR_ANY, 0); - tcp_nagle_disable((struct tcp_pcb *) c->fd); - } - LOG(LL_DEBUG, ("%lu -> %s %s", c->id, url, c->is_udp ? "UDP" : "TCP")); - mg_resolve(mgr, c, &host, mgr->dnstimeout); - return c; -} - -void mg_connect_resolved(struct mg_connection *c) { - char buf[40]; - ip_addr_t ipaddr; - memcpy(&ipaddr, &c->peer.ip, sizeof(ipaddr)); - mg_call(c, MG_EV_RESOLVE, NULL); - LOG(LL_DEBUG, ("%lu resolved to %s", c->id, mg_straddr(c, buf, sizeof(buf)))); - err_t err = c->is_udp ? udp_connect((struct udp_pcb *) c->fd, &ipaddr, - mg_ntohs(c->peer.port)) - : tcp_connect((struct tcp_pcb *) c->fd, &ipaddr, - mg_ntohs(c->peer.port), connect_cb); - if (c->is_udp) c->is_connecting = 0; - if (err != ERR_OK) mg_error(c, "%p failed, err %d", c->fd, err); -} - -static err_t accept_cb(void *arg, struct tcp_pcb *pcb, err_t e) { - LOG(LL_DEBUG, ("%p err %ld, pcb %p", arg, e, pcb)); - return ERR_OK; -} - -struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, - mg_event_handler_t fn, void *fn_data) { - struct mg_connection *c = mg_mkconn(url); - struct mg_str host = mg_url_host(url); - uint16_t port = mg_url_port(url); - uint32_t ipaddr; - err_t err; - if (c == NULL) return c; - mg_aton(host.ptr, &ipaddr); - if (!mg_vcasecmp(&host, "localhost")) ipaddr = mg_htonl(0x7f000001); - if ((err = tcp_bind(c->fd, (ip_addr_t *) &ipaddr, port)) != ERR_OK) { - mg_error(c, "%p tcp_bind(%x:%hu) -> %ld", c->fd, ipaddr, port, err); - } else { - tcp_listen(c->fd); - tcp_accept(c->fd, accept_cb); - } - return c; -} - -void mg_mgr_poll(struct mg_mgr *mgr, int ms) { - LOG(LL_DEBUG, ("%p %d", mgr, ms)); - mg_usleep(200 * 1000); - mg_timer_poll(mg_millis()); -} -#endif - #ifdef MG_ENABLE_LINES #line 1 "src/md5.c" #endif @@ -2433,7 +2221,7 @@ void mg_mgr_free(struct mg_mgr *mgr) { struct mg_connection *c; for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; mg_mgr_poll(mgr, 0); -#if MG_ARCH == MG_ARCH_FREERTOS +#if MG_ARCH == MG_ARCH_FREERTOS_TCP FreeRTOS_DeleteSocketSet(mgr->ss); #endif LOG(LL_INFO, ("All connections closed")); @@ -3031,11 +2819,13 @@ SOCKET mg_open_listener(const char *url) { (type == SOCK_DGRAM || listen(fd, 128) == 0)) { mg_set_non_blocking_mode(fd); } else if (fd != INVALID_SOCKET) { - LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO)); closesocket(fd); fd = INVALID_SOCKET; } } + if (fd == INVALID_SOCKET) { + LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO)); + } return fd; } @@ -3522,7 +3312,7 @@ int mg_vcasecmp(const struct mg_str *str1, const char *str2) { struct mg_str mg_strdup(const struct mg_str s) { struct mg_str r = {NULL, 0}; if (s.len > 0 && s.ptr != NULL) { - char *sc = (char *) malloc(s.len + 1); + char *sc = (char *) calloc(1, s.len + 1); if (sc != NULL) { memcpy(sc, s.ptr, s.len); sc[s.len] = '\0'; @@ -4136,7 +3926,7 @@ char *mg_file_read(const char *path, size_t *sizep) { char *data = NULL; size_t size = (size_t) mg_file_size(path); if ((fp = mg_fopen(path, "rb")) != NULL) { - data = (char *) malloc(size + 1); + data = (char *) calloc(1, size + 1); if (data != NULL) { if (fread(data, 1, size, fp) != size) { free(data); @@ -4253,7 +4043,7 @@ uint16_t mg_ntohs(uint16_t net) { char *mg_hexdump(const void *buf, size_t len) { const unsigned char *p = (const unsigned char *) buf; size_t i, idx, n = 0, ofs = 0, dlen = len * 5 + 100; - char ascii[17] = "", *dst = (char *) malloc(dlen); + char ascii[17] = "", *dst = (char *) calloc(1, dlen); if (dst == NULL) return dst; for (i = 0; i < len; i++) { idx = i % 16; @@ -4324,7 +4114,7 @@ int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) { free(*buf); if (size == 0) size = 5; size *= 2; - if ((*buf = (char *) malloc(size)) == NULL) { + if ((*buf = (char *) calloc(1, size)) == NULL) { len = -1; break; } @@ -4338,7 +4128,7 @@ int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) { // LCOV_EXCL_STOP } else if (len >= (int) size) { /// Standard-compliant code path. Allocate a buffer that is large enough - if ((*buf = (char *) malloc(len + 1)) == NULL) { + if ((*buf = (char *) calloc(1, len + 1)) == NULL) { len = -1; // LCOV_EXCL_LINE } else { // LCOV_EXCL_LINE va_copy(ap_copy, ap); diff --git a/mongoose.h b/mongoose.h index cf0eff82..72c0d38a 100644 --- a/mongoose.h +++ b/mongoose.h @@ -34,6 +34,8 @@ #define MG_ARCH MG_ARCH_ESP8266 #elif defined(ESP_PLATFORM) #define MG_ARCH MG_ARCH_ESP32 +#elif defined(FREERTOS_IP_H) +#define MG_ARCH MG_ARCH_FREERTOS_TCP #endif #if !defined(MG_ARCH) @@ -143,6 +145,8 @@ #define MG_INT64_FMT "%lld" #define MG_DIRSEP '/' +// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing +// with FreeRTOS_ prefix, is beyond me #define IPPROTO_TCP FREERTOS_IPPROTO_TCP #define IPPROTO_UDP FREERTOS_IPPROTO_UDP #define AF_INET FREERTOS_AF_INET @@ -168,6 +172,17 @@ #define closesocket(x) FreeRTOS_closesocket(x) #define gethostbyname(x) FreeRTOS_gethostbyname(x) +// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib +static inline void *mg_calloc(int cnt, size_t size) { + void *p = pvPortMalloc(cnt * size); + if (p != NULL) memset(p, 0, size); + return p; +} +#define calloc(a, b) mg_calloc((a), (b)) +#define free(a) vPortFree(a) +#define malloc(a) pvPortMalloc(a) + +// Again, why not a clean retarget, but instead this.. #ifdef MG_ENABLE_FF #include diff --git a/src/arch.h b/src/arch.h index ecbb9741..774bc484 100644 --- a/src/arch.h +++ b/src/arch.h @@ -16,6 +16,8 @@ #define MG_ARCH MG_ARCH_ESP8266 #elif defined(ESP_PLATFORM) #define MG_ARCH MG_ARCH_ESP32 +#elif defined(FREERTOS_IP_H) +#define MG_ARCH MG_ARCH_FREERTOS_TCP #endif #if !defined(MG_ARCH) diff --git a/src/arch_freertos_tcp.h b/src/arch_freertos_tcp.h index 6a4cc155..12f1fd3e 100644 --- a/src/arch_freertos_tcp.h +++ b/src/arch_freertos_tcp.h @@ -26,6 +26,8 @@ #define MG_INT64_FMT "%lld" #define MG_DIRSEP '/' +// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing +// with FreeRTOS_ prefix, is beyond me #define IPPROTO_TCP FREERTOS_IPPROTO_TCP #define IPPROTO_UDP FREERTOS_IPPROTO_UDP #define AF_INET FREERTOS_AF_INET @@ -51,6 +53,17 @@ #define closesocket(x) FreeRTOS_closesocket(x) #define gethostbyname(x) FreeRTOS_gethostbyname(x) +// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib +static inline void *mg_calloc(int cnt, size_t size) { + void *p = pvPortMalloc(cnt * size); + if (p != NULL) memset(p, 0, size); + return p; +} +#define calloc(a, b) mg_calloc((a), (b)) +#define free(a) vPortFree(a) +#define malloc(a) pvPortMalloc(a) + +// Again, why not a clean retarget, but instead this.. #ifdef MG_ENABLE_FF #include diff --git a/src/http.c b/src/http.c index 6949c361..903631e5 100644 --- a/src/http.c +++ b/src/http.c @@ -643,7 +643,7 @@ DIR *opendir(const char *name) { if (name == NULL) { SetLastError(ERROR_BAD_ARGUMENTS); - } else if ((d = (DIR *) malloc(sizeof(*d))) == NULL) { + } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0])); diff --git a/src/iobuf.c b/src/iobuf.c index 979bc8b5..0d0826a3 100644 --- a/src/iobuf.c +++ b/src/iobuf.c @@ -19,9 +19,9 @@ int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { io->buf = NULL; io->len = io->size = 0; } else if (new_size != io->size) { - // NOTE(lsm): do not use realloc here. Use malloc/free only, to ease the + // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the // porting to some obscure platforms like FreeRTOS - void *p = malloc(new_size); + void *p = calloc(1, new_size); if (p != NULL) { size_t len = new_size < io->len ? new_size : io->len; if (len > 0) memcpy(p, io->buf, len); diff --git a/src/net.c b/src/net.c index d3821f69..d967aade 100644 --- a/src/net.c +++ b/src/net.c @@ -115,7 +115,7 @@ void mg_mgr_free(struct mg_mgr *mgr) { struct mg_connection *c; for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; mg_mgr_poll(mgr, 0); -#if MG_ARCH == MG_ARCH_FREERTOS +#if MG_ARCH == MG_ARCH_FREERTOS_TCP FreeRTOS_DeleteSocketSet(mgr->ss); #endif LOG(LL_INFO, ("All connections closed")); diff --git a/src/private.h b/src/private.h index 4af3ac94..eeb40939 100644 --- a/src/private.h +++ b/src/private.h @@ -1,12 +1 @@ void mg_connect_resolved(struct mg_connection *); - -#if MG_ARCH == MG_ARCH_FREERTOS_TCP -static inline void *mg_calloc(int cnt, size_t size) { - void *p = pvPortMalloc(cnt * size); - if (p != NULL) memset(p, 0, size); - return p; -} -#define calloc(a, b) mg_calloc((a), (b)) -#define malloc(a) pvPortMalloc(a) -#define free(a) vPortFree(a) -#endif diff --git a/src/sock.c b/src/sock.c index 4c6d4ba0..5491b728 100644 --- a/src/sock.c +++ b/src/sock.c @@ -235,11 +235,13 @@ SOCKET mg_open_listener(const char *url) { (type == SOCK_DGRAM || listen(fd, 128) == 0)) { mg_set_non_blocking_mode(fd); } else if (fd != INVALID_SOCKET) { - LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO)); closesocket(fd); fd = INVALID_SOCKET; } } + if (fd == INVALID_SOCKET) { + LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO)); + } return fd; } diff --git a/src/str.c b/src/str.c index 27f3786f..eb84cfdf 100644 --- a/src/str.c +++ b/src/str.c @@ -44,7 +44,7 @@ int mg_vcasecmp(const struct mg_str *str1, const char *str2) { struct mg_str mg_strdup(const struct mg_str s) { struct mg_str r = {NULL, 0}; if (s.len > 0 && s.ptr != NULL) { - char *sc = (char *) malloc(s.len + 1); + char *sc = (char *) calloc(1, s.len + 1); if (sc != NULL) { memcpy(sc, s.ptr, s.len); sc[s.len] = '\0'; diff --git a/src/util.c b/src/util.c index 02a3306b..3b7ac8a8 100644 --- a/src/util.c +++ b/src/util.c @@ -39,7 +39,7 @@ char *mg_file_read(const char *path, size_t *sizep) { char *data = NULL; size_t size = (size_t) mg_file_size(path); if ((fp = mg_fopen(path, "rb")) != NULL) { - data = (char *) malloc(size + 1); + data = (char *) calloc(1, size + 1); if (data != NULL) { if (fread(data, 1, size, fp) != size) { free(data); @@ -156,7 +156,7 @@ uint16_t mg_ntohs(uint16_t net) { char *mg_hexdump(const void *buf, size_t len) { const unsigned char *p = (const unsigned char *) buf; size_t i, idx, n = 0, ofs = 0, dlen = len * 5 + 100; - char ascii[17] = "", *dst = (char *) malloc(dlen); + char ascii[17] = "", *dst = (char *) calloc(1, dlen); if (dst == NULL) return dst; for (i = 0; i < len; i++) { idx = i % 16; @@ -227,7 +227,7 @@ int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) { free(*buf); if (size == 0) size = 5; size *= 2; - if ((*buf = (char *) malloc(size)) == NULL) { + if ((*buf = (char *) calloc(1, size)) == NULL) { len = -1; break; } @@ -241,7 +241,7 @@ int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) { // LCOV_EXCL_STOP } else if (len >= (int) size) { /// Standard-compliant code path. Allocate a buffer that is large enough - if ((*buf = (char *) malloc(len + 1)) == NULL) { + if ((*buf = (char *) calloc(1, len + 1)) == NULL) { len = -1; // LCOV_EXCL_LINE } else { // LCOV_EXCL_LINE va_copy(ap_copy, ap); diff --git a/test/freertos-tcp/FreeRTOS_IP.c b/test/freertos-tcp/FreeRTOS_IP.c index 9b57525c..616aa7c9 100644 --- a/test/freertos-tcp/FreeRTOS_IP.c +++ b/test/freertos-tcp/FreeRTOS_IP.c @@ -411,6 +411,7 @@ static void prvIPTask( void * pvParameters ) /* Wait until there is something to do. If the following call exits * due to a time out rather than a message being received, set a * 'NoEvent' value. */ + // printf("foo %x %x\n", xNetworkEventQueue, xNextIPSleep); if( xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep ) == pdFALSE ) { xReceivedEvent.eEventType = eNoEvent;