577 lines
17 KiB
C
577 lines
17 KiB
C
/**
|
|
******************************************************************************
|
|
* @file LwIP/LwIP_HTTP_Server_Netconn_RTOS/Src/main.c
|
|
* @author MCD Application Team
|
|
* @brief This sample code implements a http server application based on
|
|
* Netconn API of LwIP stack and FreeRTOS. This application uses
|
|
* STM32H7xx the ETH HAL API to transmit and receive data.
|
|
* The communication is done with a web browser of a remote PC.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* This software component is licensed by ST under Ultimate Liberty license
|
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at:
|
|
* www.st.com/SLA0044
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "main.h"
|
|
#include "cmsis_os.h"
|
|
#include "ethernetif.h"
|
|
#include "lwip/netif.h"
|
|
#include "lwip/tcpip.h"
|
|
#include "app_ethernet.h"
|
|
|
|
#include "retarget.h"
|
|
#include "tasks/user_tasks.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "stm32h7xx_hal.h"
|
|
|
|
#include "stm32h7xx_hal_tim.h"
|
|
#include "stm32h7xx_hal_tim_ex.h"
|
|
|
|
#include "cli.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include "flexptp/ptp_defs.h"
|
|
|
|
#include "persistent_storage.h"
|
|
|
|
#include "flexptp/ptp_core.h"
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
|
#define OSC_XTAL (1)
|
|
#define OSC_EXT (2)
|
|
|
|
#if HSE_VALUE == 16000000UL
|
|
#define OSC_TYPE (OSC_XTAL)
|
|
#else
|
|
#define OSC_TYPE (OSC_EXT)
|
|
#endif
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
struct netif gnetif; /* network interface structure */
|
|
|
|
// Devices handles
|
|
static UART_HandleTypeDef shUART3;
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
static void SystemClock_Config(void);
|
|
static void BSP_Config(void);
|
|
static void StartThread(void const *argument);
|
|
static void Netif_Config(void);
|
|
static void MPU_Config(void);
|
|
static void CPU_CACHE_Enable(void);
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
|
static TaskHandle_t shBoardTask;
|
|
static void task_board(void const *argument);
|
|
|
|
static void reg_board_task() {
|
|
BaseType_t result = xTaskCreate(task_board, "board", 64, NULL, 1, &shBoardTask);
|
|
if (result != pdPASS) { // taszk létrehozása
|
|
MSG("Failed to create task! (errcode: %ld)\n", result);
|
|
}
|
|
}
|
|
|
|
static void BSP_Config(void) {
|
|
BSP_LED_Init(LED2);
|
|
BSP_LED_Init(LED3);
|
|
BSP_LED_Init(LED1);
|
|
}
|
|
|
|
static bool sPing = false;
|
|
static int CB_ping(const CliToken_Type *ppArgs, uint8_t argc) {
|
|
if (argc >= 1) {
|
|
sPing = (ONOFF(ppArgs[0]) > 0);
|
|
} else {
|
|
sPing = !sPing;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static char sTaskPrintBuf[512];
|
|
|
|
static int CB_listTasks(const CliToken_Type *ppArgs, uint8_t argc) {
|
|
osThreadList(sTaskPrintBuf);
|
|
printf("\nName\t\tState\tPrio\tStk\t#\n\n");
|
|
printf("%s\n\n", sTaskPrintBuf);
|
|
printf("B : Blocked, R : Ready, D : Deleted, S : Suspended\n\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int CB_config(const CliToken_Type *ppArgs, uint8_t argc) {
|
|
if (!strcmp(ppArgs[0], "save")) {
|
|
MSG("Saving to persistent storage...");
|
|
|
|
// clear storage
|
|
ps_clear();
|
|
|
|
// save PTP-config
|
|
PtpConfig config;
|
|
ptp_store_config(&config);
|
|
ps_store(CONFIG_PTP, &config);
|
|
|
|
MSG("done!\n");
|
|
|
|
return 0;
|
|
} else if (!strcmp(ppArgs[0], "load")) {
|
|
MSG("Loading from persistent storage...");
|
|
|
|
// load PTP-config
|
|
ptp_load_config_from_dump(ps_load(CONFIG_PTP));
|
|
|
|
MSG("done!\n");
|
|
|
|
return 0;
|
|
} else if (!strcmp(ppArgs[0], "clear")) {
|
|
MSG("Clearing persistent storage...");
|
|
ps_clear();
|
|
MSG("done!\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
//static int CB_start_stop_ptp(const CliToken_Type *ppArgs, uint8_t argc) {
|
|
// if (!strcmp(ppArgs[0], "start")) {
|
|
// MSG("Starting PTP!\n");
|
|
// reg_task_ptp();
|
|
// } else if (!strcmp(ppArgs[0], "stop")) {
|
|
// unreg_task_ptp();
|
|
// MSG("PTP stopped!\n");
|
|
// } else {
|
|
// return -1;
|
|
// }
|
|
// return 0;
|
|
//}
|
|
|
|
static void task_board(void const *argument) {
|
|
sPing = false;
|
|
|
|
// register cli commands
|
|
cli_register_command("ping [on|off] \t\t\tTurn on/off ping led blinking", 1, 0, CB_ping);
|
|
cli_register_command("tasks \t\t\tPrint list or registered tasks", 1, 0, CB_listTasks);
|
|
cli_register_command("config {save|load|clear} \t\t\tSave/load/clear config to/from persistent storage", 1, 1, CB_config);
|
|
// cli_register_command("ptp {start|stop} \t\t\tStart PTP", 1, 1, CB_start_stop_ptp);
|
|
|
|
// construct config table
|
|
ps_add_entry(sizeof(PtpConfig), CONFIG_PTP);
|
|
|
|
while (true) {
|
|
if (sPing || BSP_LED_GetState(LED1)) {
|
|
BSP_LED_Toggle(LED1);
|
|
}
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
if (BSP_PB_GetState(BUTTON_USER)) {
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
|
|
/**
|
|
* @brief Prepare USART3 to function as a debug printing interface
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void retarget_printf() {
|
|
// Enable peripheral clocks
|
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
|
__HAL_RCC_USART3_CLK_ENABLE();
|
|
__HAL_RCC_USART3_FORCE_RESET();
|
|
__HAL_RCC_USART3_RELEASE_RESET();
|
|
|
|
// Initialize pins as USART3 Tx and Rx
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
|
// TX
|
|
GPIO_InitStructure.Pin = GPIO_PIN_8;
|
|
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStructure.Alternate = GPIO_AF7_USART3;
|
|
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
|
|
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
|
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
|
|
|
// RX
|
|
GPIO_InitStructure.Pin = GPIO_PIN_9;
|
|
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
|
|
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
|
|
|
// Initialize USART3
|
|
shUART3.Instance = USART3;
|
|
shUART3.Init.BaudRate = 115200; //
|
|
shUART3.Init.Mode = UART_MODE_TX_RX;
|
|
shUART3.Init.Parity = UART_PARITY_NONE;
|
|
shUART3.Init.WordLength = UART_WORDLENGTH_8B;
|
|
shUART3.Init.StopBits = UART_STOPBITS_1;
|
|
shUART3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
|
shUART3.Init.OverSampling = UART_OVERSAMPLING_16;
|
|
shUART3.Init.ClockPrescaler = UART_PRESCALER_DIV16;
|
|
//huart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
|
HAL_UART_Init(&shUART3);
|
|
|
|
USART3->CR3 |= USART_CR3_OVRDIS;
|
|
|
|
// Initialize retargeting
|
|
RetargetInit(&shUART3);
|
|
|
|
// set fallback output device
|
|
RetargetSetFallbackOutput(output_usart);
|
|
|
|
// enable DMA interrupts
|
|
//HAL_NVIC_SetPriority(USART3_IRQn, 10, 10);
|
|
//HAL_NVIC_EnableIRQ(USART3_IRQn);
|
|
}
|
|
|
|
// hardware initialization
|
|
void hw_init() {
|
|
retarget_printf(); // retarget printf to USART3
|
|
}
|
|
|
|
/**
|
|
* @brief Main program
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
int main(void) {
|
|
/* Turn off MPU */
|
|
HAL_MPU_Disable();
|
|
|
|
/* STM32H7xx HAL library initialization:
|
|
- Configure the TIM6 to generate an interrupt each 1 msec
|
|
- Set NVIC Group Priority to 4
|
|
- Low Level Initialization
|
|
*/
|
|
HAL_Init();
|
|
|
|
/* Configure the system clock to 400 MHz */
|
|
SystemClock_Config();
|
|
|
|
/* Configure the MPU attributes as Device memory for ETH DMA descriptors */
|
|
MPU_Config();
|
|
|
|
/* Further hardware initialization */
|
|
hw_init();
|
|
|
|
/* Enable the MPU */
|
|
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
|
|
|
|
/* Enable the CPU Cache */
|
|
CPU_CACHE_Enable();
|
|
|
|
/* FIXME Configure the LEDs ...*/
|
|
BSP_Config();
|
|
|
|
/* Init thread */
|
|
osThreadDef(Start, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 4);
|
|
osThreadCreate(osThread(Start), NULL);
|
|
|
|
MSG("\033[2J\033[H");
|
|
MSG("Starting scheduler!\r\n");
|
|
MSG("CPU freq. = %u Hz\n", HAL_RCC_GetSysClockFreq());
|
|
|
|
/* Start scheduler */
|
|
osKernelStart();
|
|
|
|
/* We should never get here as control is now taken by the scheduler */
|
|
for (;;)
|
|
;
|
|
}
|
|
|
|
static void BoardThread(void const *argument);
|
|
|
|
#include "timersync/timersync.h"
|
|
|
|
/**
|
|
* @brief Start Thread
|
|
* @param argument not used
|
|
* @retval None
|
|
*/
|
|
static void StartThread(void const *argument) {
|
|
//pm_init();
|
|
|
|
/* Create tcp_ip stack thread */
|
|
tcpip_init(NULL, NULL);
|
|
|
|
/* Initialize the LwIP stack */
|
|
Netif_Config();
|
|
|
|
/* register CLI task*/
|
|
reg_task_cli();
|
|
|
|
/* register board thread */
|
|
reg_board_task();
|
|
|
|
/* register task for PTP management */
|
|
reg_task_eth();
|
|
|
|
/* initialize timer synchronization */
|
|
timersync_init();
|
|
|
|
for (;;) {
|
|
/* Delete the Init Thread */
|
|
osThreadTerminate(NULL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Initializes the lwIP stack
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
static void Netif_Config(void) {
|
|
ip_addr_t ipaddr;
|
|
ip_addr_t netmask;
|
|
ip_addr_t gw;
|
|
|
|
#if LWIP_DHCP
|
|
ip_addr_set_zero_ip4(&ipaddr);
|
|
ip_addr_set_zero_ip4(&netmask);
|
|
ip_addr_set_zero_ip4(&gw);
|
|
#else
|
|
IP_ADDR4(&ipaddr,IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3);
|
|
IP_ADDR4(&netmask,NETMASK_ADDR0,NETMASK_ADDR1,NETMASK_ADDR2,NETMASK_ADDR3);
|
|
IP_ADDR4(&gw,GW_ADDR0,GW_ADDR1,GW_ADDR2,GW_ADDR3);
|
|
#endif /* LWIP_DHCP */
|
|
|
|
/* add the network interface */
|
|
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
|
|
|
|
/* Registers the default network interface. */
|
|
netif_set_default(&gnetif);
|
|
|
|
ethernet_link_status_updated(&gnetif);
|
|
|
|
#if LWIP_NETIF_LINK_CALLBACK
|
|
netif_set_link_callback(&gnetif, ethernet_link_status_updated);
|
|
|
|
osThreadDef(EthLink, ethernet_link_thread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE *2);
|
|
osThreadCreate(osThread(EthLink), &gnetif);
|
|
#endif
|
|
|
|
#if LWIP_DHCP
|
|
/* Start DHCPClient */
|
|
osThreadDef(DHCP, DHCP_Thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 2);
|
|
osThreadCreate(osThread(DHCP), &gnetif);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief System Clock Configuration
|
|
* The system Clock is configured as follow :
|
|
* System Clock source = PLL1 (HSE BYPASS)
|
|
* SYSCLK(Hz) = 400000000 (CPU Clock)
|
|
* HCLK(Hz) = 200000000 (AXI and AHBs Clock)
|
|
* AHB Prescaler = 2
|
|
* D1 APB3 Prescaler = 2 (APB3 Clock 100MHz)
|
|
* D2 APB1 Prescaler = 2 (APB1 Clock 100MHz)
|
|
* D2 APB2 Prescaler = 2 (APB2 Clock 100MHz)
|
|
* D3 APB4 Prescaler = 2 (APB4 Clock 100MHz)
|
|
* HSE Frequency(Hz) = 16000000
|
|
* PLL_M = 8
|
|
* PLL_N = 400
|
|
* PLL_P = 2
|
|
* PLL_Q = 4
|
|
* PLL_R = 2
|
|
* VDD(V) = 3.3
|
|
* Flash Latency(WS) = 4
|
|
*
|
|
* PLL2 is used for SAI 98.304MHz generation
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
|
|
static void SystemClock_Config(void) {
|
|
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
|
HAL_StatusTypeDef ret = HAL_OK;
|
|
|
|
/*!< Supply configuration update enable */
|
|
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
|
|
|
|
/* The voltage scaling allows optimizing the power consumption when the device is
|
|
clocked below the maximum system frequency, to update the voltage scaling value
|
|
regarding system frequency refer to product datasheet. */
|
|
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
|
|
|
|
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
|
|
}
|
|
|
|
/* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/
|
|
__HAL_RCC_D2SRAM3_CLK_ENABLE();
|
|
|
|
/* Enable HSE Oscillator and activate PLL with HSE as source */
|
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
|
|
|
#if OSC_TYPE == OSC_XTAL
|
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON; // HSE ON
|
|
#elif OSC_TYPE == OSC_EXT
|
|
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // HSE BYPASS ON
|
|
#endif
|
|
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
|
|
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
|
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
|
|
|
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE / 2000000; // 16/10MHz -> 2MHz
|
|
RCC_OscInitStruct.PLL.PLLN = 400;
|
|
RCC_OscInitStruct.PLL.PLLFRACN = 0;
|
|
RCC_OscInitStruct.PLL.PLLP = 2;
|
|
RCC_OscInitStruct.PLL.PLLR = 2;
|
|
RCC_OscInitStruct.PLL.PLLQ = 4;
|
|
|
|
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
|
|
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
|
|
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
|
if (ret != HAL_OK) {
|
|
while (1)
|
|
;
|
|
}
|
|
|
|
/* Select PLL as system clock source and configure bus clocks dividers */
|
|
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 |
|
|
RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
|
|
|
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
|
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
|
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
|
|
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
|
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
|
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
|
|
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
|
|
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
|
|
if (ret != HAL_OK) {
|
|
while (1)
|
|
;
|
|
}
|
|
|
|
/*activate CSI clock mandatory for I/O Compensation Cell*/
|
|
__HAL_RCC_CSI_ENABLE();
|
|
|
|
/* Enable SYSCFG clock mandatory for I/O Compensation Cell */
|
|
__HAL_RCC_SYSCFG_CLK_ENABLE()
|
|
;
|
|
|
|
/* Enables the I/O Compensation Cell */
|
|
HAL_EnableCompensationCell();
|
|
|
|
// get existing settings
|
|
RCC_PeriphCLKInitTypeDef perClkInit;
|
|
HAL_RCCEx_GetPeriphCLKConfig(&perClkInit);
|
|
|
|
/* Initialize PLL2 */
|
|
perClkInit.PLL2.PLL2M = HSE_VALUE / 2000000; // 16/10MHz -> 2MHz
|
|
perClkInit.PLL2.PLL2N = 98; // 2MHz -> 196.608MHz
|
|
perClkInit.PLL2.PLL2FRACN = 2490; // ...
|
|
perClkInit.PLL2.PLL2P = 2; // 196.608MHz -> 98.304MHz
|
|
|
|
// don't need these outputs, but don't leave them zero
|
|
perClkInit.PLL2.PLL2Q = 10;
|
|
perClkInit.PLL2.PLL2R = 10;
|
|
|
|
perClkInit.PLL2.PLL2RGE = RCC_PLL1VCIRANGE_1; // Frequency range 1
|
|
perClkInit.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM; // Medium-range PLL
|
|
|
|
/* Set SAI clock source pll2_p_ck */
|
|
perClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2; // modify value for SAI1
|
|
HAL_RCCEx_PeriphCLKConfig(&perClkInit); // save settings
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the MPU attributes
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
static void MPU_Config(void) {
|
|
MPU_Region_InitTypeDef MPU_InitStruct;
|
|
|
|
/* Configure the MPU attributes as Device not cacheable
|
|
for ETH DMA descriptors */
|
|
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
|
|
MPU_InitStruct.BaseAddress = 0x30040000;
|
|
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
|
|
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
|
|
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
|
|
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
|
|
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
|
|
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
|
|
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
|
|
MPU_InitStruct.SubRegionDisable = 0x00;
|
|
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
|
|
|
|
HAL_MPU_ConfigRegion(&MPU_InitStruct);
|
|
|
|
/* Configure the MPU attributes as Normal Non Cacheable
|
|
for LwIP RAM heap which contains the Tx buffers */
|
|
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
|
|
MPU_InitStruct.BaseAddress = 0x30044000;
|
|
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
|
|
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
|
|
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
|
|
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
|
|
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
|
|
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
|
|
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
|
|
MPU_InitStruct.SubRegionDisable = 0x00;
|
|
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
|
|
|
|
HAL_MPU_ConfigRegion(&MPU_InitStruct);
|
|
|
|
SCB_InvalidateDCache();
|
|
}
|
|
|
|
/**
|
|
* @brief CPU L1-Cache enable.
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
static void CPU_CACHE_Enable(void) {
|
|
/* Enable I-Cache */
|
|
SCB_EnableICache();
|
|
|
|
/* Enable D-Cache */
|
|
//SCB_EnableDCache();
|
|
}
|
|
|
|
#ifdef USE_FULL_ASSERT
|
|
|
|
/**
|
|
* @brief Reports the name of the source file and the source line number
|
|
* where the assert_param error has occurred.
|
|
* @param file: pointer to the source file name
|
|
* @param line: assert_param error line source number
|
|
* @retval None
|
|
*/
|
|
void assert_failed(uint8_t* file, uint32_t line)
|
|
{
|
|
/* User can add his own implementation to report the file name and line number,
|
|
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
|
|
|
/* Infinite loop */
|
|
while (1)
|
|
{
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|