2015-01-13 01:27 AM
Hello
I am try write a configuration in a microcontroller STM32F I am using stsw-stm32010 code base example. The example work properly. But when I make my code don't work. I want write my config data from a memory address and after I want read then. I don't have problems with read. But i can't over write the memory position. It is like i write all the data in the same memory position. And i don't understand it.bool EscribeDatosEnFlash(char *Datos, uint32_t offset)
{
u32 i;
u32 tamanho = IndexArrayFin; //strlen(Datos);
uint16_t estado;
// uint16_t VarValue = 0;
// ***********************************************************
// * Success or error status:
// * - FLASH_COMPLETE: on success
// * - PAGE_FULL: if valid page is full
// * - NO_VALID_PAGE: if no valid page was found
// * - Flash error code: on write Flash error
// ************************************************************
FLASH_Unlock();//unlock flash writing
EE_Init();
for (i = 0; i < tamanho; i++)
{
estado = EE_EscribeVariable((EEPROM_START_ADDRESS+i), Datos[i]);
}
FLASH_Lock();//lock the flash for writing
if (estado == FLASH_COMPLETE) return true;
if (estado == PAGE_FULL) return false;
if (estado == NO_VALID_PAGE) return false;
else return true;
}
/**
* @brief Writes/upadtes variable data in EEPROM.
* @param Direcion: Variable address
* @param Dato: 16 bit data to be written
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/
uint16_t EE_EscribeVariable(uint32_t Direcion, uint16_t Dato)
{
uint16_t Status = 0;
// Write the variable virtual address and value in the EEPROM
Status = EE_VerificaYEscribeVariable(Direcion, Dato);
// In case the EEPROM active page is full
if (Status == PAGE_FULL)
{
// Perform Page transfer
Status = EE_PageTransfer(Direcion, Dato);
}
// Return last operation status
return Status;
}
/**
* @brief Verifica si la pagina y Escribe en la EEPROM.
* @param Direcion: Variable address
* @param Dato: 16 bit data to be written as variable value
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/
uint16_t EE_VerificaYEscribeVariable(uint32_t DirecionIn, uint16_t Dato)
{
FLASH_Status FlashStatus = FLASH_COMPLETE;
uint16_t ValidPage = PAGE0;
uint32_t Address = DirecionIn;
/* Get valid Page for write operation */
ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE)
{
return NO_VALID_PAGE;
}
/* Get the valid Page start Address */
Address = (uint32_t)(DirecionIn + (uint32_t)(ValidPage * PAGE_SIZE));
FlashStatus = FLASH_ProgramHalfWord(Address, Dato);
return FlashStatus;
}
/**
* @brief Verify if active page is full and Writes variable in EEPROM.
* @param VirtAddress: 16 bit virtual address of the variable
* @param Data: 16 bit data to be written as variable value
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - PAGE_FULL: if valid page is full
* - NO_VALID_PAGE: if no valid page was found
* - Flash error code: on write Flash error
*/
static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
{
FLASH_Status FlashStatus = FLASH_COMPLETE;
uint16_t ValidPage = PAGE0;
uint32_t Address = 0x08010000, PageEndAddress = 0x080107FF;
/* Get valid Page for write operation */
ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE)
{
return NO_VALID_PAGE;
}
/* Get the valid Page start Address */
Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
/* Get the valid Page end Address */
PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
/* Check each active page address starting from begining */
while (Address < PageEndAddress)
{
/* Verify if Address and Address+2 contents are 0xFFFFFFFF */
if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF)
{
/* Set variable data */
FlashStatus = FLASH_ProgramHalfWord(Address, Data);
/* If program operation was failed, a Flash error code is returned */
if (FlashStatus != FLASH_COMPLETE)
{
return FlashStatus;
}
/* Set variable virtual address */
FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress);
/* Return program operation status */
return FlashStatus;
}
else
{
/* Next address location */
Address = Address + 4;
}
}
/* Return PAGE_FULL in case the valid page is full */
return PAGE_FULL;
}
Some One can help me???
Best Regards
#stm32f #stm32f105 #rewrite #flash #eeprom
2015-01-13 08:00 AM
Hello
I have solved the problem. I read the solution in linkedin https://www.linkedin.com/groups/Flash-erase-write-on-stm32f103-4240S.108244546 Thanks to Johnson C. EEPROM_LnkIn.h/******EEPROM .h*****/
#ifndef FLASH_EEPROM_LNK_IN_H
#define FLASH_EEPROM_LNK_IN_H
#define FL_EERPOM_StartAddr ((uint32_t) 0x08010000) // start from address after 94kbyte flash size //0x080107000
#define FL_EEPROM_EndAddr ((uint32_t) 0x08010800) // 2K data size //0x08017800
#define FL_EEPROM_PageSize ((uint16_t) 0x400) // 1K
/* Page status definitions */
#define ERASED ((uint16_t)0xFFFF) /* PAGE is empty */
#define RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */
#define VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
#include ''stdint.h''
#include ''stm32f10x.h''
#include ''stm32f10x_flash.h''
#include ''b_types.h''
typedef enum
{
Data_8Bit =1,
Data_16Bit,
Data_32Bit
} Data_typeDef;
#define PASSED true
uint16_t Flash_EEPROM_Write_Data( uint32_t Start_Address, uint16_t *data, uint16_t No_of_Data, uint8_t Data_format);
uint16_t Flash_EEPROM_ErasePage( uint32_t Start_Address, uint16_t No_of_Size);
uint16_t Flash_EEPROM_Read_Data( uint32_t Start_Address, uint16_t *dest_data, uint16_t No_of_Data, uint8_t Data_format);
uint16_t Flash_EEPROM_Format( uint32_t Start_Address, uint32_t End_Address);
#endif /*FLASH_EEPROM_LNK_IN_H */
EEPROM_LnkIn.C
/*
https://www.linkedin.com/groups/Flash-erase-write-on-stm32f103-4240S.108244546
Johnson C.
Founder/Director of Engineering at Dreampro Technology Ltd.
Actually, STM32F do not have internal EEPROM(beside STM32L series), ST website had use Internal Flash emulate the EEPROM function. It need consider the Flash start address and end address.
1. The start address do not cover your program code section. Otherwise, it will overwrite your program and your STM32 will hanging. You need the start address outside our total complied code size. ( e.g. your total flash size=64K, the start address >64K address)
2. Flash memory need erase the whole flash page (1Kbyte) data when you want to rewrite the same address. So, It will also erase other data in same page. It need read and backup the data in RAM first before erase the flash page.
3. The end address do you excess the physic memory of STM32 (e.g STM32F103RBT6 is max 128Kflash memory)
It is my example code for write EEPROM
It is my example code for Read/erase EEPROM
*/
/*****Flash eeprom.c*****/
/// user define function
#include ''EEPROM_LnkIn.h''
FLASH_Status FLASHStatus;
uint16_t FLASH_EEPROM_ProgramStatus;
uint32_t Flash_EEPROM_Addr;
uint32_t Flash_EEPROM_Nb_Of_Page;
uint32_t EraseCounter;
/**** Function : Write the internal Flash data****/
uint16_t Flash_EEPROM_Write_Data( uint32_t Start_Address, uint16_t *data, uint16_t No_of_Data, uint8_t Data_format)
{
// uint32_t Write_Addr_Cnt=Start_Address;
uint32_t End_Of_Address=0;
FLASHStatus=FLASH_COMPLETE;
FLASH_EEPROM_ProgramStatus= PASSED;
FLASH_Unlock();
/*Start EEPROM*/
Flash_EEPROM_Addr= Start_Address;
End_Of_Address= Start_Address +(No_of_Data * Data_format) ;
/* Write page data*/
while((Flash_EEPROM_Addr<End_Of_Address) )
{
/* Verify if Address and Address+2 contents are 0xFFFFFFFF */
// if ((*( vuint32_t *)Flash_EEPROM_Addr) == 0xFFFFFFFF)
// {
switch(Data_format)
{
case Data_8Bit :
break;
case Data_16Bit :
FLASHStatus = FLASH_ProgramHalfWord(Flash_EEPROM_Addr, *data);
if (FLASHStatus != FLASH_COMPLETE)
{
return FLASHStatus;
}
Flash_EEPROM_Addr +=2; // point to next 2byte address
data++;
break;
case Data_32Bit :
FLASHStatus = FLASH_ProgramWord(Flash_EEPROM_Addr, *data);
if (FLASHStatus != FLASH_COMPLETE)
{
return FLASHStatus;
}
Flash_EEPROM_Addr +=4; // point to next 4byte address
data++;
break;
}
/*
}
else
{
Flash_EEPROM_Addr +=4; // point to next 4byte address
}
*/
}
FLASH_Lock();
return FLASHStatus;
}
/*
Function : Erase the internal Flash data
Input :- start address
- Number of page
Output: return the FLASH status
*/
uint16_t Flash_EEPROM_ErasePage( uint32_t Start_Address, uint16_t No_of_Size)
{
FLASH_Unlock();
FLASHStatus=FLASH_COMPLETE;
FLASH_EEPROM_ProgramStatus= PASSED;
Flash_EEPROM_Nb_Of_Page= No_of_Size; //
/*Clear all the flash */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_OPTERR);
/*erase the page*/
for(EraseCounter=0; EraseCounter<Flash_EEPROM_Nb_Of_Page; EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(Start_Address +(FL_EEPROM_PageSize* EraseCounter));
if (FLASHStatus != FLASH_COMPLETE)
{
return FLASHStatus;
}
}
FLASH_Lock();
return FLASHStatus;
}
uint16_t Flash_EEPROM_Read_Data( uint32_t Start_Address, uint16_t *dest_data, uint16_t No_of_Data, uint8_t Data_format)
{
uint32_t End_Of_Address=0;
/*
uint32_t *EEPROM_32Bit_p = (uint32_t *)Start_Address; // pointer point to address after 72kbyte flash size
uint16_t *EEPROM_16Bit_p = (uint32_t *)Start_Address;
uint8_t *EEPROM_8Bit_p = (uint32_t *)Start_Address;
*/
FLASHStatus=FLASH_COMPLETE;
FLASH_EEPROM_ProgramStatus= PASSED;
// FLASH_Unlock();
/*Start EEPROM*/
Flash_EEPROM_Addr= Start_Address;
End_Of_Address= Start_Address +(No_of_Data * Data_format) ;
while((Flash_EEPROM_Addr<End_Of_Address))
{
switch(Data_format)
{
case Data_8Bit : *dest_data = *(uint8_t *)Flash_EEPROM_Addr ; //
dest_data++ ;
Flash_EEPROM_Addr+=1;
break;
case Data_16Bit : *dest_data = *(uint16_t *)Flash_EEPROM_Addr ;
dest_data++;
Flash_EEPROM_Addr+=2;
break;
case Data_32Bit : *dest_data = *(uint32_t *)Flash_EEPROM_Addr ;
dest_data++;
Flash_EEPROM_Addr+=4;
break;
default: break;
}
}
FLASH_Lock();
return FLASHStatus;
}
/*
Function : format the internal Flash data
Input :- start address
- Number of page
Output: return FLASHStatus;
*/
uint16_t Flash_EEPROM_Format( uint32_t Start_Address, uint32_t End_Address)
{
FLASH_Unlock();
FLASHStatus=FLASH_COMPLETE;
FLASH_EEPROM_ProgramStatus= PASSED;
Flash_EEPROM_Nb_Of_Page= (End_Address- Start_Address)/FL_EEPROM_PageSize; //
if (Flash_EEPROM_Nb_Of_Page< 1)
{
Flash_EEPROM_Nb_Of_Page=1;
}
/*Clear all the flash */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_OPTERR);
/*erase the page*/
for(EraseCounter=0; EraseCounter<Flash_EEPROM_Nb_Of_Page; EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(Start_Address +(FL_EEPROM_PageSize* EraseCounter));
if (FLASHStatus != FLASH_COMPLETE)
{
return FLASHStatus;
}
}
FLASH_Lock();
return FLASHStatus;
}
Code
bool EscribeDatosEnFlash(char *Datos, uint32_t offset)
{
u32 i;
u32 tamanho = IndexArrayFin; //strlen(Datos);
uint16_t estado;
// uint16_t VarValue = 0;
uint16_t Datos_16[IndexArrayFin];
// ***********************************************************
// * Success or error status:
// * - FLASH_COMPLETE: on success
// * - PAGE_FULL: if valid page is full
// * - NO_VALID_PAGE: if no valid page was found
// * - Flash error code: on write Flash error
// ************************************************************
FLASH_Unlock();//unlock flash writing
EE_Init();
Flash_EEPROM_Format(FL_EERPOM_StartAddr, FL_EEPROM_EndAddr);
FLASH_Lock();//lock the flash for writing
EE_Init();
for (i = 0; i < tamanho; i++)
{
Datos_16[i] = (Datos[i] & 0x00FF);
}
estado = Flash_EEPROM_Write_Data(EEPROM_START_ADDRESS, Datos_16, tamanho, Data_16Bit);
FLASH_Lock();//lock the flash for writing
return true;
}
//////////////////////////
void LeerConfiguracionEeprom(Datos_Via_USB_S *Datos_Out)
{
int i = 0;
char Datos[TamanhoUsadoEnLaConfiguracion];
uint16_t Datos_16[IndexArrayFin];
Flash_EEPROM_Read_Data( EEPROM_START_ADDRESS, Datos_16, IndexArrayFin, Data_16Bit);
for (i = 0; i < IndexArrayFin; i++)
{
Datos[i] = (char)(Datos_16[i] & 0x00FF);
}
Extraer_Datos_Leidos_Eeprom(Datos, Datos_Out);
}
Best regards