//--------------------------------------------------------------
// File : stm32_ub_ee_flash.c
// Datum : 05.09.2013
// Version : 1.0
// Autor : UB
// EMail : mc-4u(@)t-online.de
// Web : www.mikrocontroller-4u.de
// CPU : STM32F4
// IDE : CooCox CoIDE 1.7.4
// GCC : 4.7 2012q4
// Module : FLASH
// Funktion : virtuelles EEprom (per internem Flash)
//
// Hinweise :
//
// 1. es werden zwei 16k Flash-Bl鯿ke zum speichern
// der EEprom-Daten benutzt
// 2. der schreib/lese zugriff wird von zwei Funktionen verwaltet
// 3. die VCC der CPU muss zwischen 2.7 und 3,3V liegen !!
// 4. zur Funktionsweise siehe : Application note AN3969
//
//--------------------------------------------------------------
//--------------------------------------------------------------
// Includes
//--------------------------------------------------------------
#include "stm32_ub_ee_flash.h"
//--------------------------------------------------------------
// interne Funktionen
//--------------------------------------------------------------
FLASH_Status EE_Format(void);
uint16_t EE_FindValidPage(uint8_t Operation);
uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
//--------------------------------------------------------------
// init vom virtuellen EEprom
// Return_wert :
// -> ERROR , wenn Fehler beim Init
// -> SUCCESS , wenn Init vom virtuellen EEProm ok
//--------------------------------------------------------------
ErrorStatus UB_EE_FLASH_Init(void)
{
uint16_t PageStatus0, PageStatus1;
uint16_t VarIdx;
uint16_t status_wert;
int16_t x = -1;
int32_t read_wert;
uint16_t data_wert;
FLASH_Unlock();
PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
switch (PageStatus0)
{
case EE_ERASED :
if (PageStatus1 == EE_VALID_PAGE) {
status_wert = FLASH_EraseSector(PAGE0_ID,VOLTAGE_RANGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
else if (PageStatus1 == EE_RECEIVE_DATA) {
status_wert = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
status_wert = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, EE_VALID_PAGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
else {
status_wert = EE_Format();
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
break;
case EE_RECEIVE_DATA :
if (PageStatus1 == EE_VALID_PAGE) {
x=-1;
for (VarIdx = 0; VarIdx < EE_FLASH_MAX_ADR; VarIdx++)
{
if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VarIdx) {
x = VarIdx;
}
if (VarIdx != x) {
read_wert = UB_EE_FLASH_Read(VarIdx);
if (read_wert >= 0) {
data_wert=(uint16_t)(read_wert);
status_wert = EE_VerifyPageFullWriteVariable(VarIdx, data_wert);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
}
}
status_wert = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, EE_VALID_PAGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
status_wert = FLASH_EraseSector(PAGE1_ID, VOLTAGE_RANGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
else if (PageStatus1 == EE_ERASED)
{
status_wert = FLASH_EraseSector(PAGE1_ID, VOLTAGE_RANGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
status_wert = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, EE_VALID_PAGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
else {
status_wert = EE_Format();
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
break;
case EE_VALID_PAGE :
if (PageStatus1 == EE_VALID_PAGE) {
status_wert = EE_Format();
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
else if (PageStatus1 == EE_ERASED) {
status_wert = FLASH_EraseSector(PAGE1_ID, VOLTAGE_RANGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
else {
x=-1;
for (VarIdx = 0; VarIdx < EE_FLASH_MAX_ADR; VarIdx++) {
if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VarIdx) {
x = VarIdx;
}
if (VarIdx != x) {
read_wert = UB_EE_FLASH_Read(VarIdx);
if (read_wert >= 0) {
data_wert=(uint16_t)(read_wert);
status_wert = EE_VerifyPageFullWriteVariable(VarIdx, data_wert);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
}
}
status_wert = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, EE_VALID_PAGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
status_wert = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE);
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
}
break;
default :
status_wert = EE_Format();
if (status_wert != FLASH_COMPLETE) {
return ERROR;
}
break;
}
return SUCCESS;
}
//--------------------------------------------------------------
// Daten aus virtuellem EEprom lesen
// VirtAddress : [0...EE_FLASH_MAX_ADR-1]
// Return_wert :
// [0...65535] : wenn Inhalt von Adresse ausgelesen wurde
// [-1] : Adresse nicht g黮tig
// [-2] : Flash noch nicht initialisiert
// [-3] : Adresse wurde im Flash nicht gefunden
//--------------------------------------------------------------
int32_t UB_EE_FLASH_Read(uint16_t VirtAddress)
{
int32_t ret_wert=-3;
uint16_t wert;
uint16_t ValidPage;
uint16_t AddressValue;
uint32_t Address, PageStartAddress;
if(VirtAddress>=EE_FLASH_MAX_ADR) {
return -1;
}
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
if(ValidPage==EE_PAGE0) {
PageStartAddress = (uint32_t)(PAGE0_BASE_ADDRESS);
Address = (uint32_t)(PAGE0_END_ADDRESS-1);
}
else if(ValidPage==EE_PAGE1) {
PageStartAddress = (uint32_t)(PAGE1_BASE_ADDRESS);
Address = (uint32_t)(PAGE1_END_ADDRESS-1);
}
else {
return -2;
}
ret_wert=-3;
while (Address > (PageStartAddress + 2)) {
AddressValue = (*(__IO uint16_t*)Address);
if (AddressValue == VirtAddress) {
wert = (*(__IO uint16_t*)(Address - 2));
ret_wert=0;
break;
}
else {
Address = Address - 4;
}
}
if(ret_wert==0) {
// ausgelesenen Datenwert zur點kgeben
ret_wert=(int32_t)(wert);
}
return ret_wert;
}
//--------------------------------------------------------------
// Daten in virtuelles EEprom speichern
// VirtAddress : [0...EE_FLASH_MAX_ADR-1]
// Data : [0...65535]
// Return_wert :
// [0] : schreiben OK
// [-1] : Adresse nicht g黮tig
// [-2] : sonstiger Fehler
//--------------------------------------------------------------
int32_t UB_EE_FLASH_Write(uint16_t VirtAddress, uint16_t Data)
{
uint16_t Status = EE_NO_ERROR;
if(VirtAddress>=EE_FLASH_MAX_ADR) {
return -1;
}
Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
if (Status == EE_PAGE_FULL) {
Status = EE_PageTransfer(VirtAddress, Data);
}
if(Status != FLASH_COMPLETE) {
return -2;
}
return 0;
}
//-------------------------------------------------------------