Добавлены команды чтения/записи Flash памяти.
This commit is contained in:
277
Core/Src/FLASH_SECTOR_F4.c
Normal file
277
Core/Src/FLASH_SECTOR_F4.c
Normal file
@@ -0,0 +1,277 @@
|
||||
|
||||
/**
|
||||
***************************************************************************************************************
|
||||
***************************************************************************************************************
|
||||
***************************************************************************************************************
|
||||
File: FLASH_SECTOR_F4.c
|
||||
Modifier: ControllersTech.com
|
||||
Updated: 27th MAY 2021
|
||||
***************************************************************************************************************
|
||||
Copyright (C) 2017 ControllersTech.com
|
||||
This is a free software under the GNU license, you can redistribute it and/or modify it under the terms
|
||||
of the GNU General Public License version 3 as published by the Free Software Foundation.
|
||||
This software library is shared with public for educational purposes, without WARRANTY and Author is not liable for any damages caused directly
|
||||
or indirectly by this software, read more about this on the GNU General Public License.
|
||||
***************************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "FLASH_SECTOR_F4.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* DEFINE the SECTORS according to your reference manual
|
||||
* STM32F446RE have:-
|
||||
* Sector 0 to Sector 3 each 16KB
|
||||
* Sector 4 as 64KB
|
||||
* Sector 5 to Sector 7 each 128KB
|
||||
*/
|
||||
|
||||
static uint32_t GetSector(uint32_t Address)
|
||||
{
|
||||
uint32_t sector = 0;
|
||||
|
||||
if((Address < 0x08003FFF) && (Address >= 0x08000000))
|
||||
{
|
||||
sector = FLASH_SECTOR_0;
|
||||
}
|
||||
else if((Address < 0x08007FFF) && (Address >= 0x08004000))
|
||||
{
|
||||
sector = FLASH_SECTOR_1;
|
||||
}
|
||||
else if((Address < 0x0800BFFF) && (Address >= 0x08008000))
|
||||
{
|
||||
sector = FLASH_SECTOR_2;
|
||||
}
|
||||
else if((Address < 0x0800FFFF) && (Address >= 0x0800C000))
|
||||
{
|
||||
sector = FLASH_SECTOR_3;
|
||||
}
|
||||
else if((Address < 0x0801FFFF) && (Address >= 0x08010000))
|
||||
{
|
||||
sector = FLASH_SECTOR_4;
|
||||
}
|
||||
else if((Address < 0x0803FFFF) && (Address >= 0x08020000))
|
||||
{
|
||||
sector = FLASH_SECTOR_5;
|
||||
}
|
||||
else if((Address < 0x0805FFFF) && (Address >= 0x08040000))
|
||||
{
|
||||
sector = FLASH_SECTOR_6;
|
||||
}
|
||||
else if((Address < 0x0807FFFF) && (Address >= 0x08060000))
|
||||
{
|
||||
sector = FLASH_SECTOR_7;
|
||||
}
|
||||
/* else if((Address < 0x0809FFFF) && (Address >= 0x08080000))
|
||||
{
|
||||
sector = FLASH_SECTOR_8;
|
||||
}
|
||||
else if((Address < 0x080BFFFF) && (Address >= 0x080A0000))
|
||||
{
|
||||
sector = FLASH_SECTOR_9;
|
||||
}
|
||||
else if((Address < 0x080DFFFF) && (Address >= 0x080C0000))
|
||||
{
|
||||
sector = FLASH_SECTOR_10;
|
||||
}
|
||||
else if((Address < 0x080FFFFF) && (Address >= 0x080E0000))
|
||||
{
|
||||
sector = FLASH_SECTOR_11;
|
||||
}
|
||||
else if((Address < 0x08103FFF) && (Address >= 0x08100000))
|
||||
{
|
||||
sector = FLASH_SECTOR_12;
|
||||
}
|
||||
else if((Address < 0x08107FFF) && (Address >= 0x08104000))
|
||||
{
|
||||
sector = FLASH_SECTOR_13;
|
||||
}
|
||||
else if((Address < 0x0810BFFF) && (Address >= 0x08108000))
|
||||
{
|
||||
sector = FLASH_SECTOR_14;
|
||||
}
|
||||
else if((Address < 0x0810FFFF) && (Address >= 0x0810C000))
|
||||
{
|
||||
sector = FLASH_SECTOR_15;
|
||||
}
|
||||
else if((Address < 0x0811FFFF) && (Address >= 0x08110000))
|
||||
{
|
||||
sector = FLASH_SECTOR_16;
|
||||
}
|
||||
else if((Address < 0x0813FFFF) && (Address >= 0x08120000))
|
||||
{
|
||||
sector = FLASH_SECTOR_17;
|
||||
}
|
||||
else if((Address < 0x0815FFFF) && (Address >= 0x08140000))
|
||||
{
|
||||
sector = FLASH_SECTOR_18;
|
||||
}
|
||||
else if((Address < 0x0817FFFF) && (Address >= 0x08160000))
|
||||
{
|
||||
sector = FLASH_SECTOR_19;
|
||||
}
|
||||
else if((Address < 0x0819FFFF) && (Address >= 0x08180000))
|
||||
{
|
||||
sector = FLASH_SECTOR_20;
|
||||
}
|
||||
else if((Address < 0x081BFFFF) && (Address >= 0x081A0000))
|
||||
{
|
||||
sector = FLASH_SECTOR_21;
|
||||
}
|
||||
else if((Address < 0x081DFFFF) && (Address >= 0x081C0000))
|
||||
{
|
||||
sector = FLASH_SECTOR_22;
|
||||
}
|
||||
else if (Address < 0x081FFFFF) && (Address >= 0x081E0000)
|
||||
{
|
||||
sector = FLASH_SECTOR_23;
|
||||
}*/
|
||||
return sector;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t bytes_temp[4];
|
||||
|
||||
|
||||
void float2Bytes(uint8_t * ftoa_bytes_temp,float float_variable)
|
||||
{
|
||||
union {
|
||||
float a;
|
||||
uint8_t bytes[4];
|
||||
} thing;
|
||||
|
||||
thing.a = float_variable;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
ftoa_bytes_temp[i] = thing.bytes[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float Bytes2float(uint8_t * ftoa_bytes_temp)
|
||||
{
|
||||
union {
|
||||
float a;
|
||||
uint8_t bytes[4];
|
||||
} thing;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
thing.bytes[i] = ftoa_bytes_temp[i];
|
||||
}
|
||||
|
||||
float float_variable = thing.a;
|
||||
return float_variable;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Flash_Write_Data (uint32_t StartSectorAddress, uint32_t *Data, uint16_t numberofwords)
|
||||
{
|
||||
|
||||
static FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
uint32_t SECTORError;
|
||||
int sofar=0;
|
||||
|
||||
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
/* Erase the user Flash area */
|
||||
|
||||
/* Get the number of sector to erase from 1st sector */
|
||||
|
||||
uint32_t StartSector = GetSector(StartSectorAddress);
|
||||
uint32_t EndSectorAddress = StartSectorAddress + numberofwords*4;
|
||||
uint32_t EndSector = GetSector(EndSectorAddress);
|
||||
|
||||
/* Fill EraseInit structure*/
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
||||
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
||||
EraseInitStruct.Sector = StartSector;
|
||||
EraseInitStruct.NbSectors = (EndSector - StartSector) + 1;
|
||||
|
||||
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
|
||||
you have to make sure that these data are rewritten before they are accessed during code
|
||||
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
|
||||
DCRST and ICRST bits in the FLASH_CR register. */
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
|
||||
{
|
||||
return HAL_FLASH_GetError ();
|
||||
}
|
||||
|
||||
/* Program the user Flash area word by word
|
||||
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
||||
|
||||
while (sofar<numberofwords)
|
||||
{
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, StartSectorAddress, Data[sofar]) == HAL_OK)
|
||||
{
|
||||
StartSectorAddress += 4; // use StartPageAddress += 2 for half word and 8 for double word
|
||||
sofar++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error occurred while writing data in Flash memory*/
|
||||
return HAL_FLASH_GetError ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the Flash to disable the flash control register access (recommended
|
||||
to protect the FLASH memory against possible unwanted operation) *********/
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Flash_Read_Data (uint32_t StartSectorAddress, uint32_t *RxBuf, uint16_t numberofwords)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
||||
*RxBuf = *(__IO uint32_t *)StartSectorAddress;
|
||||
StartSectorAddress += 4;
|
||||
RxBuf++;
|
||||
if (!(numberofwords--)) break;
|
||||
}
|
||||
}
|
||||
|
||||
void Convert_To_Str (uint32_t *Data, char *Buf)
|
||||
{
|
||||
int numberofbytes = ((strlen((char *)Data)/4) + ((strlen((char *)Data) % 4) != 0)) *4;
|
||||
|
||||
for (int i=0; i<numberofbytes; i++)
|
||||
{
|
||||
Buf[i] = Data[i/4]>>(8*(i%4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Flash_Write_NUM (uint32_t StartSectorAddress, float Num)
|
||||
{
|
||||
|
||||
float2Bytes(bytes_temp, Num);
|
||||
|
||||
Flash_Write_Data (StartSectorAddress, (uint32_t *)bytes_temp, 1);
|
||||
}
|
||||
|
||||
|
||||
float Flash_Read_NUM (uint32_t StartSectorAddress)
|
||||
{
|
||||
uint8_t buffer[4];
|
||||
float value;
|
||||
|
||||
Flash_Read_Data(StartSectorAddress, (uint32_t *)buffer, 1);
|
||||
value = Bytes2float(buffer);
|
||||
return value;
|
||||
}
|
||||
@@ -25,6 +25,8 @@
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "pribors.h"
|
||||
#include <FLASH_SECTOR_F4.h>
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -103,6 +105,7 @@ int main(void)
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
HAL_Delay(100);
|
||||
MX_LWIP_Init();
|
||||
MX_FMC_Init();
|
||||
MX_TIM3_Init();
|
||||
@@ -141,12 +144,12 @@ int main(void)
|
||||
br_counter = 0;
|
||||
}
|
||||
|
||||
|
||||
if (rx_msg.con_timeout > 1999)
|
||||
{
|
||||
rx_msg.clnt_con = 0;
|
||||
}
|
||||
//HAL_Delay(100);
|
||||
//read_isa(0x4);
|
||||
|
||||
}
|
||||
/* USER CODE END WHILE */
|
||||
}
|
||||
@@ -277,14 +280,14 @@ static void MX_FMC_Init(void)
|
||||
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
|
||||
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
|
||||
/* Timing */
|
||||
Timing.AddressSetupTime = 15;
|
||||
Timing.AddressHoldTime = 15;
|
||||
Timing.DataSetupTime = 255;
|
||||
Timing.BusTurnAroundDuration = 15;
|
||||
Timing.CLKDivision = 16;
|
||||
Timing.DataLatency = 17;
|
||||
Timing.AddressSetupTime = 10;
|
||||
Timing.AddressHoldTime = 10;
|
||||
Timing.DataSetupTime = 15;
|
||||
Timing.BusTurnAroundDuration = 10;
|
||||
Timing.CLKDivision = 10;
|
||||
Timing.DataLatency = 10;
|
||||
Timing.AccessMode = FMC_ACCESS_MODE_A;
|
||||
/* ExtTiming */
|
||||
|
||||
|
||||
if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
|
||||
{
|
||||
@@ -413,6 +416,7 @@ void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
void rcv_command(void)
|
||||
{
|
||||
uint16_t ports_amount = 0;
|
||||
uint16_t bytes_amount = 0;
|
||||
uint16_t i = 0;
|
||||
rx_msg.cmd_num = rx_msg.rx_buf[2] | (rx_msg.rx_buf[3] << 8);
|
||||
rx_msg.cmd_code = rx_msg.rx_buf[6];
|
||||
@@ -510,6 +514,76 @@ void rcv_command(void)
|
||||
tx_msg.cmd_len = (ports_amount << 2) + 3;
|
||||
}
|
||||
break;
|
||||
case 55:
|
||||
//-----------------------------------------------------------
|
||||
// КОМАНДА №55
|
||||
// ЗАПИСЬ МАССИВА В FLASH
|
||||
//-----------------------------------------------------------
|
||||
|
||||
cmd_buf[0] = rx_msg.cmd_code; // - код команды
|
||||
bytes_amount = rx_msg.rx_buf[9] + (rx_msg.rx_buf[10] << 8);
|
||||
|
||||
// Проверка размера принятого буфера
|
||||
if( rx_msg.length < (10 + bytes_amount))
|
||||
{
|
||||
// Размер принятого пакета меньше чем долно быть
|
||||
// Установить ошибку
|
||||
// КОД = 2
|
||||
cmd_buf[1] = ERR_SIZE;
|
||||
|
||||
// Установить размер буфера = 2
|
||||
tx_msg.cmd_len = 2;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Установить ВЫПОЛНЕНО
|
||||
cmd_buf[1] = NO_ERROR;
|
||||
|
||||
uint16_t flash_addr = rx_msg.rx_buf[7] + (rx_msg.rx_buf[8] << 8);
|
||||
uint16_t numofwords = (bytes_amount/4)+((bytes_amount%4)!=0);
|
||||
Flash_Write_Data(FLASH_BASE_WR + flash_addr, (uint32_t *)&rx_msg.rx_buf[11], numofwords);
|
||||
// Установить размер буфера
|
||||
tx_msg.cmd_len = 2;
|
||||
}
|
||||
break;
|
||||
case 51:
|
||||
//-----------------------------------------------------------
|
||||
// КОМАНДА №51
|
||||
// ЧТЕНИЕ МАССИВА ИЗ FLASH
|
||||
//-----------------------------------------------------------
|
||||
|
||||
cmd_buf[0] = rx_msg.cmd_code; // - код команды
|
||||
bytes_amount = rx_msg.rx_buf[9] + (rx_msg.rx_buf[10] << 8);
|
||||
|
||||
// Проверка размера принятого буфера
|
||||
if( rx_msg.length < (8))
|
||||
{
|
||||
// Размер принятого пакета меньше чем долно быть
|
||||
// Установить ошибку
|
||||
// КОД = 2
|
||||
cmd_buf[1] = ERR_SIZE;
|
||||
|
||||
// Установить размер буфера = 2
|
||||
tx_msg.cmd_len = 2;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Установить ВЫПОЛНЕНО
|
||||
cmd_buf[1] = NO_ERROR;
|
||||
// Колличество записаных байт
|
||||
cmd_buf[2] = rx_msg.rx_buf[7];
|
||||
cmd_buf[3] = rx_msg.rx_buf[8] << 8;
|
||||
cmd_buf[4] = rx_msg.rx_buf[9];
|
||||
cmd_buf[5] = rx_msg.rx_buf[10] << 8;
|
||||
uint16_t flash_addr = rx_msg.rx_buf[7] + (rx_msg.rx_buf[8] << 8);
|
||||
uint16_t numofwords = (bytes_amount/4)+((bytes_amount%4)!=0);
|
||||
Flash_Read_Data(FLASH_BASE_WR + flash_addr, (uint32_t *)&cmd_buf[6], numofwords);
|
||||
// Установить размер буфера
|
||||
tx_msg.cmd_len = 6 + bytes_amount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
need_send_private = 1;
|
||||
@@ -525,6 +599,8 @@ void write_isa(uint16_t addr, uint16_t data)
|
||||
{
|
||||
*(uint16_t*)(ISA_BASE_WR + (addr << 1)) = data;
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user