Added plausibility check for pressure values
In case of I2C communication problems at startup the dc jumped into dive mode with depth up to 300m. As no CRC is applied a bit flip may also occure during normal operation without detection => added a plausibility check if last measured value fits to the last measurements
line source
/**+ −
******************************************************************************+ −
* @copyright heinrichs weikamp+ −
* @file externLogbookFlash.c+ −
* @author heinrichs weikamp gmbh+ −
* @date 07-Aug-2014+ −
* @version V0.0.4+ −
* @since 29-Sept-2015+ −
* @brief Main File to access the new 1.8 Volt Spansion S25FS256S 256 Mbit (32 Mbyte)+ −
* @bug+ −
* @warning+ −
*+ −
@verbatim+ −
==============================================================================+ −
##### Logbook Header (TOC) #####+ −
==============================================================================+ −
[..] Memory useage:+ −
NEW: Spansion S25FS-S256S+ −
+ −
only 8x 4KB and 1x 32KB, remaining is 64KB or 256KB+ −
Sector Size (kbyte) Sector Count Sector Range Address Range (Byte Address) Notes+ −
4 8 SA00 00000000h-00000FFFh + −
: :+ −
SA07 00007000h-00007FFFh+ −
+ −
32 1 SA08 00008000h-0000FFFFh+ −
+ −
64 511 SA09 00010000h-0001FFFFh+ −
: :+ −
SA519 01FF0000h-01FFFFFFh + −
OLD:+ −
1kB each header+ −
with predive header at beginning+ −
and postdive header with 0x400 HEADER2OFFSET+ −
4kB (one erase) has two dives with 4 headers total+ −
total of 512 kB (with 256 header ids (8 bit))+ −
Size is 280 Byte (as of 25.Nov. 2014)+ −
+ −
[..] Output to PC / UART is postdive header+ −
+ −
[..] Block Protection Lock-Down is to erase logbook only+ −
+ −
[..] Timing (see page 137 of LOGBOOK_V3_S25FS-S_00-271247.pdf+ −
bulk erase is 2 minutes typ., 6 minutes max.+ −
+ −
==============================================================================+ −
##### DEMOMODE #####+ −
==============================================================================+ −
151215: ext_flash_write_settings() is DISABLED!+ −
+ −
==============================================================================+ −
##### bug fixes #####+ −
==============================================================================+ −
150917: end in header and length of sample was one byte too long + −
as stated by Jef Driesen email 15.09.2015+ −
+ −
@endverbatim+ −
******************************************************************************+ −
* @attention+ −
*+ −
* <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>+ −
*+ −
******************************************************************************+ −
*/+ −
+ −
/* Includes ------------------------------------------------------------------*/+ −
#include "stm32f4xx_hal.h"+ −
#include "externLogbookFlash.h"+ −
#include "ostc.h"+ −
#include "settings.h"+ −
#include "gfx_engine.h"+ −
+ −
#ifndef BOOTLOADER_STANDALONE+ −
#include "logbook.h"+ −
#endif+ −
+ −
/* Private types -------------------------------------------------------------*/+ −
#define FLASHSTART 0x000000+ −
//#define FLASHSTOP 0x01FFFFFF all 32 MB with 4byte addressing+ −
#define FLASHSTOP 0x00FFFFFF + −
//#define FLASHSTOP 0x3FFFFF+ −
#define RELEASE 1+ −
#define HOLDCS 0+ −
+ −
#define HEADER2OFFSET 0x400+ −
+ −
typedef enum{+ −
EF_HEADER,+ −
EF_SAMPLE,+ −
EF_DEVICEDATA,+ −
EF_VPMDATA,+ −
EF_SETTINGS,+ −
EF_FIRMWARE,+ −
EF_FIRMWARE2,+ −
}which_ring_enum;+ −
+ −
+ −
typedef struct{+ −
uint8_t IsBusy:1;+ −
uint8_t IsWriteEnabled:1;+ −
uint8_t BlockProtect0:1;+ −
uint8_t BlockProtect1:1;+ −
uint8_t BlockProtect2:1;+ −
uint8_t BlockProtect3:1;+ −
uint8_t IsAutoAddressIncMode:1;+ −
uint8_t BlockProtectL:1;+ −
} extFlashStatusUbit8_t;+ −
+ −
typedef union{+ −
extFlashStatusUbit8_t ub;+ −
uint8_t uw;+ −
} extFlashStatusBit8_Type;+ −
+ −
+ −
/* Exported variables --------------------------------------------------------*/+ −
+ −
/* Private variables ---------------------------------------------------------*/+ −
static uint32_t actualAddress = 0;+ −
static uint32_t entryPoint = 0;+ −
+ −
static uint32_t actualPointerHeader = 0;+ −
static uint32_t actualPointerSample = 0;+ −
static uint32_t LengthLeftSampleRead = 0;+ −
static uint32_t actualPointerDevicedata = 0;+ −
static uint32_t actualPointerVPM = 0;+ −
static uint32_t actualPointerSettings = 0;+ −
static uint32_t actualPointerFirmware = 0;+ −
static uint32_t actualPointerFirmware2 = 0;+ −
+ −
/* Private function prototypes -----------------------------------------------*/+ −
static void chip_unselect(void);+ −
static void chip_select(void);+ −
static void error_led_on(void);+ −
static void error_led_off(void);+ −
+ −
static void write_spi(uint8_t data, uint8_t unselect_CS_afterwards);+ −
static uint8_t read_spi(uint8_t unselect_CS_afterwards);+ −
static void write_address(uint8_t unselect_CS_afterwards);+ −
static void Error_Handler_extflash(void);+ −
static void wait_chip_not_busy(void);+ −
static void ext_flash_incf_address(uint8_t type);+ −
//void ext_flash_incf_address_ring(void);+ −
static void ext_flash_decf_address_ring(uint8_t type);+ −
+ −
static void ext_flash_erase4kB(void);+ −
static void ext_flash_erase32kB(void);+ −
static void ext_flash_erase64kB(void);+ −
static uint8_t ext_flash_erase_if_on_page_start(void);+ −
+ −
static void ef_write_block(uint8_t * sendByte, uint32_t length, uint8_t type, uint8_t do_not_erase);+ −
+ −
static void ext_flash_read_block(uint8_t *getByte, uint8_t type);+ −
static void ext_flash_read_block_multi(void *getByte, uint32_t size, uint8_t type);+ −
static void ext_flash_read_block_stop(void);+ −
+ −
static void ef_hw_rough_delay_us(uint32_t delayUs);+ −
static void ef_erase_64K(uint32_t blocks);+ −
+ −
static void ext_flash_overwrite_sample_without_erase(uint8_t *pSample, uint16_t length);+ −
+ −
static void ext_flash_disable_protection(void);+ −
+ −
static _Bool ext_flash_test_remaining_space_of_page_empty(uint32_t pointer, uint16_t length);+ −
static void ext_flash_set_to_begin_of_next_page(uint32_t *pointer, uint8_t type);+ −
static void ext_flash_find_start(void);+ −
+ −
+ −
/* Exported functions --------------------------------------------------------*/+ −
+ −
void ext_flash_write_firmware(uint8_t *pSample1, uint32_t length1)//, uint8_t *pSample2, uint32_t length2)+ −
{+ −
general32to8_Type lengthTransform;+ −
+ −
lengthTransform.u32 = length1;+ −
+ −
actualPointerFirmware = FWSTART;+ −
ef_write_block(lengthTransform.u8,4, EF_FIRMWARE, 1);+ −
ef_write_block(pSample1,length1, EF_FIRMWARE, 1);+ −
+ −
// if(length2)+ −
// ef_write_block(pSample2,length2, EF_FIRMWARE, 1);+ −
}+ −
+ −
uint8_t ext_flash_read_firmware_version(char *text)+ −
{+ −
uint32_t backup = actualAddress;+ −
uint8_t buffer[4];+ −
+ −
// + 4 for length data, see ext_flash_write_firmware+ −
actualAddress = FWSTART + 4 + 0x10000;+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&buffer[0], EF_FIRMWARE);+ −
ext_flash_read_block(&buffer[1], EF_FIRMWARE);+ −
ext_flash_read_block(&buffer[2], EF_FIRMWARE);+ −
ext_flash_read_block(&buffer[3], EF_FIRMWARE);+ −
+ −
ext_flash_read_block_stop();+ −
actualAddress = backup;+ −
+ −
uint8_t ptr = 0;+ −
text[ptr++] = 'V';+ −
ptr += gfx_number_to_string(2,0,&text[ptr],buffer[0] & 0x3F);+ −
text[ptr++] = '.';+ −
ptr += gfx_number_to_string(2,0,&text[ptr],buffer[1] & 0x3F);+ −
text[ptr++] = '.';+ −
ptr += gfx_number_to_string(2,0,&text[ptr],buffer[2] & 0x3F);+ −
text[ptr++] = ' ';+ −
if(buffer[3])+ −
{+ −
text[ptr++] = 'b';+ −
text[ptr++] = 'e';+ −
text[ptr++] = 't';+ −
text[ptr++] = 'a';+ −
text[ptr++] = ' ';+ −
}+ −
return ptr;+ −
}+ −
+ −
+ −
uint32_t ext_flash_read_firmware(uint8_t *pSample1, uint32_t max_length, uint8_t *magicByte)+ −
{+ −
uint32_t backup = actualAddress;+ −
general32to8_Type lengthTransform;+ −
+ −
actualAddress = FWSTART;+ −
ext_flash_read_block_start();+ −
+ −
ext_flash_read_block(&lengthTransform.u8[0], EF_FIRMWARE);+ −
ext_flash_read_block(&lengthTransform.u8[1], EF_FIRMWARE);+ −
ext_flash_read_block(&lengthTransform.u8[2], EF_FIRMWARE);+ −
ext_flash_read_block(&lengthTransform.u8[3], EF_FIRMWARE);+ −
+ −
+ −
if(lengthTransform.u32 == 0xFFFFFFFF)+ −
{+ −
lengthTransform.u32 = 0xFFFFFFFF;+ −
}+ −
else+ −
if(lengthTransform.u32 > max_length)+ −
{+ −
lengthTransform.u32 = 0xFF000000;+ −
}+ −
else+ −
{+ −
for(uint32_t i = 0; i<lengthTransform.u32; i++)+ −
{+ −
ext_flash_read_block(&pSample1[i], EF_FIRMWARE);+ −
}+ −
+ −
}+ −
+ −
ext_flash_read_block_stop();+ −
+ −
if(magicByte)+ −
{+ −
*magicByte = pSample1[0x10000 + 0x3E]; // 0x3E == 62 + −
}+ −
+ −
actualAddress = backup;+ −
return lengthTransform.u32;+ −
}+ −
+ −
+ −
void ext_flash_write_firmware2(uint32_t offset, uint8_t *pSample1, uint32_t length1, uint8_t *pSample2, uint32_t length2)+ −
{+ −
general32to8_Type lengthTransform, offsetTransform;+ −
+ −
lengthTransform.u32 = length1 + length2;+ −
offsetTransform.u32 = offset;+ −
+ −
actualPointerFirmware2 = FWSTART2;+ −
ef_write_block(lengthTransform.u8,4, EF_FIRMWARE2, 1);+ −
ef_write_block(offsetTransform.u8,4, EF_FIRMWARE2, 1);+ −
ef_write_block(pSample1,length1, EF_FIRMWARE2, 1);+ −
if(length2)+ −
ef_write_block(pSample2,length2, EF_FIRMWARE2, 1);+ −
}+ −
+ −
+ −
uint32_t ext_flash_read_firmware2(uint32_t *offset, uint8_t *pSample1, uint32_t max_length1, uint8_t *pSample2, uint32_t max_length2)+ −
{+ −
uint32_t backup = actualAddress;+ −
uint32_t length1, length2;+ −
general32to8_Type lengthTransform, offsetTransform;+ −
+ −
actualAddress = FWSTART2;+ −
ext_flash_read_block_start();+ −
+ −
ext_flash_read_block(&lengthTransform.u8[0], EF_FIRMWARE2);+ −
ext_flash_read_block(&lengthTransform.u8[1], EF_FIRMWARE2);+ −
ext_flash_read_block(&lengthTransform.u8[2], EF_FIRMWARE2);+ −
ext_flash_read_block(&lengthTransform.u8[3], EF_FIRMWARE2);+ −
+ −
ext_flash_read_block(&offsetTransform.u8[0], EF_FIRMWARE2);+ −
ext_flash_read_block(&offsetTransform.u8[1], EF_FIRMWARE2);+ −
ext_flash_read_block(&offsetTransform.u8[2], EF_FIRMWARE2);+ −
ext_flash_read_block(&offsetTransform.u8[3], EF_FIRMWARE2);+ −
+ −
*offset = offsetTransform.u32;+ −
+ −
if(lengthTransform.u32 == 0xFFFFFFFF)+ −
{+ −
lengthTransform.u32 = 0xFFFFFFFF;+ −
}+ −
else+ −
if(lengthTransform.u32 > max_length1 + max_length2)+ −
{+ −
lengthTransform.u32 = 0xFF000000;+ −
}+ −
else+ −
{+ −
if(lengthTransform.u32 < max_length1)+ −
{+ −
length1 = lengthTransform.u32;+ −
length2 = 0;+ −
}+ −
else+ −
{+ −
length1 = max_length1;+ −
length2 = lengthTransform.u32 - max_length1;+ −
}+ −
+ −
if(pSample1)+ −
{+ −
for(uint32_t i = 0; i<length1; i++)+ −
{+ −
ext_flash_read_block(&pSample1[i], EF_FIRMWARE2);+ −
}+ −
if(pSample2)+ −
{+ −
for(uint32_t i = 0; i<length2; i++)+ −
{+ −
ext_flash_read_block(&pSample2[i], EF_FIRMWARE2);+ −
}+ −
}+ −
}+ −
else if(pSample2)+ −
{+ −
actualAddress += length1;+ −
for(uint32_t i = 0; i<length2; i++)+ −
{+ −
ext_flash_read_block(&pSample2[i], EF_FIRMWARE2);+ −
}+ −
}+ −
}+ −
ext_flash_read_block_stop();+ −
actualAddress = backup;+ −
return lengthTransform.u32;+ −
}+ −
+ −
+ −
void ext_flash_read_fixed_16_devicedata_blocks_formated_128byte_total(uint8_t *buffer)+ −
{+ −
SDeviceLine data[16];+ −
uint8_t tempLengthIngnore;+ −
uint16_t count;+ −
uint8_t transfer;+ −
+ −
RTC_DateTypeDef Sdate;+ −
RTC_TimeTypeDef Stime;+ −
+ −
actualAddress = DDSTART;+ −
+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&tempLengthIngnore, EF_DEVICEDATA);+ −
ext_flash_read_block(&tempLengthIngnore, EF_DEVICEDATA);+ −
+ −
ext_flash_read_block_multi((uint8_t *)data,16*3*4, EF_DEVICEDATA);+ −
ext_flash_read_block_stop();+ −
+ −
count = 0;+ −
for(int i=0;i<16;i++)+ −
{+ −
transfer = (data[i].value_int32 >> 24) & 0xFF;+ −
buffer[count++] = transfer;+ −
transfer = (data[i].value_int32 >> 16) & 0xFF;+ −
buffer[count++] = transfer;+ −
transfer = (data[i].value_int32 >> 8) & 0xFF;+ −
buffer[count++] = transfer;+ −
transfer = (data[i].value_int32) & 0xFF;+ −
buffer[count++] = transfer;+ −
+ −
translateDate(data[i].date_rtc_dr, &Sdate);+ −
translateTime(data[i].time_rtc_tr, &Stime);+ −
buffer[count++] = Sdate.Year;+ −
buffer[count++] = Sdate.Month;+ −
buffer[count++] = Sdate.Date;+ −
buffer[count++] = Stime.Hours;+ −
}+ −
}+ −
+ −
+ −
#ifndef BOOTLOADER_STANDALONE+ −
+ −
void ext_flash_write_devicedata(void)+ −
{+ −
uint8_t *pData;+ −
const uint16_t length = sizeof(SDevice);+ −
uint8_t length_lo, length_hi;+ −
uint8_t dataLength[2] = { 0 };+ −
+ −
ext_flash_disable_protection();+ −
+ −
pData = (uint8_t *)stateDeviceGetPointer();+ −
+ −
actualPointerDevicedata = DDSTART;+ −
+ −
length_lo = (uint8_t)(length & 0xFF);+ −
length_hi = (uint8_t)(length >> 8);+ −
dataLength[0] = length_lo;+ −
dataLength[1] = length_hi;+ −
+ −
ef_write_block(dataLength,2, EF_DEVICEDATA, 0);+ −
ef_write_block(pData,length, EF_DEVICEDATA, 0);+ −
}+ −
+ −
+ −
uint16_t ext_flash_read_devicedata(uint8_t *buffer, uint16_t max_length)+ −
{+ −
uint16_t length;+ −
uint8_t length_lo, length_hi;+ −
+ −
actualAddress = DDSTART;+ −
+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&length_lo, EF_DEVICEDATA);+ −
ext_flash_read_block(&length_hi, EF_DEVICEDATA);+ −
+ −
length = (length_hi * 256) + length_lo;+ −
+ −
if(length > max_length)+ −
return 0;+ −
+ −
ext_flash_read_block_multi(buffer,length,EF_DEVICEDATA);+ −
ext_flash_read_block_stop();+ −
+ −
return length;+ −
}+ −
+ −
+ −
void ext_flash_write_vpm(SVpm *vpmInput)+ −
{+ −
uint8_t *pData;+ −
const uint16_t length = sizeof(SVpm);+ −
+ −
uint8_t length_lo, length_hi;+ −
uint8_t dataLength[2] = { 0 };+ −
+ −
pData = (uint8_t *)vpmInput;+ −
+ −
actualPointerVPM = VPMSTART;+ −
+ −
length_lo = (uint8_t)(length & 0xFF);+ −
length_hi = (uint8_t)(length >> 8);+ −
dataLength[0] = length_lo;+ −
dataLength[1] = length_hi;+ −
+ −
ef_write_block(dataLength,2, EF_VPMDATA, 0);+ −
ef_write_block(pData,length, EF_VPMDATA, 0);+ −
}+ −
+ −
+ −
int ext_flash_read_vpm(SVpm *vpmOutput)+ −
{+ −
uint8_t *pData;+ −
const uint16_t length = sizeof(SVpm);+ −
uint8_t length_lo, length_hi;+ −
int output;+ −
+ −
actualAddress = VPMSTART;+ −
+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&length_lo, EF_VPMDATA);+ −
ext_flash_read_block(&length_hi, EF_VPMDATA);+ −
if((length_lo == (uint8_t)(length & 0xFF))+ −
&&(length_hi == (uint8_t)(length >> 8)))+ −
{+ −
pData = (uint8_t *)vpmOutput;+ −
for(uint16_t i = 0; i < length; i++)+ −
ext_flash_read_block(&pData[i], EF_VPMDATA);+ −
output = length;+ −
}+ −
else+ −
output = 0;+ −
+ −
ext_flash_read_block_stop();+ −
return output;+ −
}+ −
+ −
#ifdef DEMOMODE+ −
void ext_flash_write_settings(void)+ −
{+ −
return;+ −
}+ −
#else+ −
void ext_flash_write_settings(void)+ −
{+ −
uint8_t *pData;+ −
const uint16_t length = sizeof(SSettings);+ −
uint8_t length_lo, length_hi;+ −
uint8_t dataLength[2] = { 0 };+ −
+ −
ext_flash_disable_protection();+ −
+ −
if(stateRealGetPointer()->lastKnownBatteryPercentage)+ −
{+ −
settingsGetPointer()->lastKnownBatteryPercentage = stateRealGetPointer()->lastKnownBatteryPercentage;+ −
}+ −
settingsGetPointer()->backup_localtime_rtc_tr = stateRealGetPointer()->lifeData.timeBinaryFormat;+ −
settingsGetPointer()->backup_localtime_rtc_dr = stateRealGetPointer()->lifeData.dateBinaryFormat;+ −
+ −
pData = (uint8_t *)settingsGetPointer();+ −
+ −
actualPointerSettings = SETTINGSSTART;+ −
+ −
length_lo = (uint8_t)(length & 0xFF);+ −
length_hi = (uint8_t)(length >> 8);+ −
dataLength[0] = length_lo;+ −
dataLength[1] = length_hi;+ −
+ −
ef_write_block(dataLength,2, EF_SETTINGS, 0);+ −
ef_write_block(pData,length, EF_SETTINGS, 0);+ −
// ext_flash_enable_protection();+ −
}+ −
#endif+ −
+ −
+ −
/* CHANGES 150929 hw + −
* this now allows to read old settings too+ −
* but make sure that everything is fixed in + −
* set_new_settings_missing_in_ext_flash+ −
* new settings should be fine as they are added+ −
* and loaded before calling this function+ −
*/+ −
uint8_t ext_flash_read_settings(void)+ −
{+ −
uint8_t returnValue = HAL_BUSY;+ −
uint8_t *pData;+ −
const uint16_t lengthStandardNow = sizeof(SSettings);+ −
uint8_t length_lo, length_hi;+ −
uint16_t lengthOnEEPROM;+ −
uint32_t header;+ −
SSettings *pSettings = settingsGetPointer();+ −
+ −
actualAddress = SETTINGSSTART;+ −
+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&length_lo, EF_SETTINGS);+ −
ext_flash_read_block(&length_hi, EF_SETTINGS);+ −
+ −
lengthOnEEPROM = length_hi * 256;+ −
lengthOnEEPROM += length_lo;+ −
if(lengthOnEEPROM <= lengthStandardNow)+ −
{+ −
ext_flash_read_block_multi(&header, 4, EF_SETTINGS);+ −
if((header <= pSettings->header) && (header >= pSettings->updateSettingsAllowedFromHeader))+ −
{+ −
returnValue = HAL_OK;+ −
pSettings->header = header;+ −
pData = (uint8_t *)pSettings + 4; /* header */+ −
for(uint16_t i = 0; i < (lengthOnEEPROM-4); i++)+ −
ext_flash_read_block(&pData[i], EF_SETTINGS);+ −
}+ −
else+ −
{+ −
returnValue = HAL_ERROR;+ −
}+ −
}+ −
ext_flash_read_block_stop();+ −
return returnValue;+ −
}+ −
+ −
+ −
+ −
+ −
/* ext_flash_start_new_dive_log_and_set_actualPointerSample+ −
* prepares the write sample pointer+ −
* to be used by ext_flash_write_sample()+ −
* to be set in the * pHeaderPreDive+ −
* for write with ext_flash_create_new_dive_log() and ext_flash_close_new_dive_log()+ −
*/+ −
void ext_flash_start_new_dive_log_and_set_actualPointerSample(uint8_t *pHeaderPreDive)+ −
{+ −
convert_Type data;+ −
SSettings *settings = settingsGetPointer();+ −
+ −
/* new 5. Jan. 2015 */+ −
actualPointerSample = settings->logFlashNextSampleStartAddress;+ −
+ −
if(!ext_flash_test_remaining_space_of_page_empty(actualPointerSample, 4))+ −
ext_flash_set_to_begin_of_next_page(&actualPointerSample, EF_SAMPLE);+ −
+ −
if((actualPointerSample < SAMPLESTART) || (actualPointerSample > SAMPLESTOP))+ −
actualPointerSample = SAMPLESTART;+ −
+ −
data.u32bit = actualPointerSample;+ −
pHeaderPreDive[2] = data.u8bit.byteLow;+ −
pHeaderPreDive[3] = data.u8bit.byteMidLow;+ −
pHeaderPreDive[4] = data.u8bit.byteMidHigh;+ −
/* to start sample writing and header etc. pp. */+ −
ext_flash_disable_protection_for_logbook();+ −
}+ −
+ −
+ −
/* ext_flash_create_new_dive_log+ −
* uses the first header without HEADER2OFFSET+ −
* for the header it is not important to be complete+ −
* and can be reconstructed+ −
* ext_flash_start_new_dive_log_and_set_actualPointerSample()+ −
* has to be called before to set the actualPointerSample+ −
* in the header+ −
* the following func writes to header to the ext_flash+ −
*/+ −
void ext_flash_create_new_dive_log(uint8_t *pHeaderPreDive)+ −
{+ −
SSettings *settings;+ −
uint8_t id, id_next;+ −
uint8_t header1, header2;+ −
+ −
settings = settingsGetPointer();+ −
id = settings->lastDiveLogId;+ −
+ −
actualAddress = HEADERSTART + (0x800 * id);+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&header1, EF_SAMPLE);+ −
ext_flash_read_block(&header2, EF_SAMPLE);+ −
ext_flash_read_block_stop();+ −
+ −
if((header1 == 0xFA) && (header2 == 0xFA))+ −
{+ −
id += 1; /* 0-255, auto rollover */+ −
if(id & 1)+ −
{+ −
actualAddress = HEADERSTART + (0x800 * id);+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&header1, EF_SAMPLE);+ −
ext_flash_read_block(&header2, EF_SAMPLE);+ −
ext_flash_read_block_stop();+ −
if((header1 == 0xFA) && (header2 == 0xFA))+ −
id += 1;+ −
}+ −
}+ −
else+ −
{+ −
id = 0;+ −
}+ −
+ −
/* delete next header */+ −
id_next = id + 1;+ −
actualPointerHeader = HEADERSTART + (0x800 * id_next);+ −
ef_write_block(0,0, EF_HEADER, 0);+ −
+ −
settings->lastDiveLogId = id;+ −
actualPointerHeader = HEADERSTART + (0x800 * id);+ −
+ −
if(pHeaderPreDive != 0)+ −
ef_write_block(pHeaderPreDive,HEADERSIZE, EF_HEADER, 0);+ −
}+ −
+ −
+ −
void ext_flash_close_new_dive_log(uint8_t *pHeaderPostDive )+ −
{+ −
SSettings * settings = settingsGetPointer();+ −
uint8_t id;+ −
convert_Type startAddress;+ −
convert_Type data;+ −
uint32_t backup;+ −
+ −
uint8_t sampleData[3];+ −
actualAddress = actualPointerSample;+ −
sampleData[0] = 0xFD;+ −
sampleData[1] = 0xFD;+ −
ext_flash_write_sample(sampleData, 2);+ −
+ −
/* end of sample data, pointing to the last sample 0xFD+ −
*/+ −
actualAddress = actualPointerSample; // change hw 17.09.2015+ −
ext_flash_decf_address_ring(EF_SAMPLE); // 17.09.2015: this decf actualAddress only!!+ −
actualPointerSample = actualAddress; // change hw 17.09.2015+ −
data.u32bit = actualPointerSample;+ −
+ −
pHeaderPostDive[5] = data.u8bit.byteLow;+ −
pHeaderPostDive[6] = data.u8bit.byteMidLow;+ −
pHeaderPostDive[7] = data.u8bit.byteMidHigh;+ −
+ −
/* take data written before, calculate length and write+ −
SLogbookHeader has different order: length (byte# 8,9,10) prior to profile version (byte# 11)+ −
*/+ −
startAddress.u8bit.byteLow = pHeaderPostDive[2];+ −
startAddress.u8bit.byteMidLow = pHeaderPostDive[3];+ −
startAddress.u8bit.byteMidHigh = pHeaderPostDive[4];+ −
startAddress.u8bit.byteHigh = 0;+ −
+ −
if(startAddress.u32bit < actualPointerSample)+ −
data.u32bit = 1 + actualPointerSample - startAddress.u32bit;+ −
else+ −
data.u32bit = 2 + (actualPointerSample - SAMPLESTART) + (SAMPLESTOP - startAddress.u32bit);+ −
+ −
pHeaderPostDive[8] = data.u8bit.byteLow;+ −
pHeaderPostDive[9] = data.u8bit.byteMidLow;+ −
pHeaderPostDive[10] = data.u8bit.byteMidHigh;+ −
+ −
/* set id and write post-dive-header+ −
*/+ −
id = settings->lastDiveLogId;+ −
actualPointerHeader = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
+ −
ef_write_block(pHeaderPostDive,HEADERSIZE, EF_HEADER, 0);+ −
+ −
/* write length at beginning of sample+ −
and write proper beginning for next dive to actualPointerSample+ −
*/+ −
backup = actualPointerSample;+ −
actualPointerSample = startAddress.u32bit; // is still 0xFF+ −
sampleData[0] = data.u8bit.byteLow;+ −
sampleData[1] = data.u8bit.byteMidLow;+ −
sampleData[2] = data.u8bit.byteMidHigh;+ −
ext_flash_overwrite_sample_without_erase(sampleData, 3);+ −
+ −
actualAddress = backup;+ −
ext_flash_incf_address(EF_SAMPLE);+ −
actualPointerSample = actualAddress;+ −
ext_flash_enable_protection();+ −
}+ −
+ −
+ −
void ext_flash_write_sample(uint8_t *pSample, uint16_t length)+ −
{+ −
ef_write_block(pSample,length, EF_SAMPLE, 0);+ −
+ −
SSettings *settings = settingsGetPointer();+ −
settings->logFlashNextSampleStartAddress = actualPointerSample;+ −
}+ −
+ −
static void ext_flash_overwrite_sample_without_erase(uint8_t *pSample, uint16_t length)+ −
{+ −
ef_write_block(pSample,length, EF_SAMPLE, 1);+ −
}+ −
+ −
+ −
uint8_t ext_flash_count_dive_headers(void)+ −
{+ −
uint8_t id = 0;+ −
uint8_t counter = 0;+ −
uint16_t headerStartData = 0x0000;+ −
+ −
id = settingsGetPointer()->lastDiveLogId;+ −
+ −
do+ −
{+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
ext_flash_read_block_multi((uint8_t *)&headerStartData, 2, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
counter++;+ −
id -=1;+ −
} while((headerStartData == 0xFAFA) && (counter < 255));+ −
return (counter - 1);+ −
}+ −
+ −
+ −
void ext_flash_read_dive_header(uint8_t *pHeaderToFill, uint8_t StepBackwards)+ −
{+ −
SSettings *settings;+ −
uint8_t id;+ −
uint16_t i;+ −
+ −
settings = settingsGetPointer();+ −
id = settings->lastDiveLogId;+ −
id -= StepBackwards; /* 0-255, auto rollover */+ −
+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
for(i = 0; i < HEADERSIZE; i++)+ −
ext_flash_read_block(&pHeaderToFill[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
}+ −
+ −
void ext_flash_read_dive_header2(uint8_t *pHeaderToFill, uint8_t id, _Bool bOffset)+ −
{+ −
+ −
uint16_t i;+ −
actualAddress = HEADERSTART + (0x800 * id) ;+ −
+ −
if(bOffset)+ −
actualAddress += HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
for(i = 0; i < HEADERSIZE; i++)+ −
ext_flash_read_block(&pHeaderToFill[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
}+ −
+ −
+ −
uint32_t ext_flash_read_dive_raw_with_double_header_1K(uint8_t *data, uint32_t max_size, uint8_t StepBackwards)+ −
{+ −
if(max_size < 0x800) + −
return 0;+ −
+ −
uint8_t id;+ −
convert_Type dataStart, dataEnd;+ −
uint32_t LengthAll = 0;+ −
+ −
id = settingsGetPointer()->lastDiveLogId;+ −
id -= StepBackwards; /* 0-255, auto rollover */+ −
+ −
// clear data+ −
for(int i=0;i<0x800;i++)+ −
data[i] = 0xFF;+ −
+ −
// copy primary/pre-dive+ −
actualAddress = HEADERSTART + (0x800 * id);+ −
ext_flash_read_block_start();+ −
for(int i = 0; i < HEADERSIZE; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// copy main/secondary/post-dive+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
for(int i = 0x400; i < HEADERSIZE+0x400; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// data+ −
+ −
dataStart.u8bit.byteHigh = 0;+ −
dataStart.u8bit.byteLow = data[0x402];+ −
dataStart.u8bit.byteMidLow = data[0x403];+ −
dataStart.u8bit.byteMidHigh = data[0x404];+ −
+ −
dataEnd.u8bit.byteHigh = 0;+ −
dataEnd.u8bit.byteLow = data[0x405];+ −
dataEnd.u8bit.byteMidLow = data[0x406];+ −
dataEnd.u8bit.byteMidHigh = data[0x407];+ −
+ −
actualPointerSample = dataStart.u32bit;+ −
if(dataEnd.u32bit >= dataStart.u32bit)+ −
LengthAll = 1 + dataEnd.u32bit - dataStart.u32bit;+ −
else+ −
LengthAll = 2 + (dataStart.u32bit - SAMPLESTART) + (SAMPLESTOP - dataEnd.u32bit);+ −
+ −
LengthAll += 0x800;+ −
+ −
if(LengthAll > max_size)+ −
return 0x800;+ −
+ −
actualAddress = actualPointerSample;+ −
ext_flash_read_block_start();+ −
for(uint32_t i = 0x800; i < LengthAll; i++)+ −
ext_flash_read_block(&data[i], EF_SAMPLE);+ −
ext_flash_read_block_stop();+ −
return LengthAll;+ −
}+ −
+ −
void ext_flash_write_dive_raw_with_double_header_1K(uint8_t *data, uint32_t length)+ −
{+ −
convert_Type dataStart, dataEnd;+ −
SLogbookHeader headerTemp;+ −
+ −
// set actualPointerSample and get pointer to sample storage and disable flash write protect+ −
ext_flash_start_new_dive_log_and_set_actualPointerSample((uint8_t *)&headerTemp);+ −
+ −
dataStart.u8bit.byteHigh = 0;+ −
dataStart.u8bit.byteLow = headerTemp.pBeginProfileData[0];+ −
dataStart.u8bit.byteMidLow = headerTemp.pBeginProfileData[1];+ −
dataStart.u8bit.byteMidHigh = headerTemp.pBeginProfileData[2];+ −
+ −
dataEnd.u32bit = dataStart.u32bit + length - 0x801;+ −
if(dataEnd.u32bit > SAMPLESTOP)+ −
dataEnd.u32bit -= SAMPLESTOP + SAMPLESTART - 1;+ −
+ −
data[0x002] = data[0x402] = dataStart.u8bit.byteLow;+ −
data[0x003] = data[0x403] = dataStart.u8bit.byteMidLow;+ −
data[0x004] = data[0x404] = dataStart.u8bit.byteMidHigh;+ −
data[0x005] = data[0x405] = dataEnd.u8bit.byteLow;+ −
data[0x006] = data[0x406] = dataEnd.u8bit.byteMidLow;+ −
data[0x007] = data[0x407] = dataEnd.u8bit.byteMidHigh;+ −
+ −
// set actualPointerHeader to next free header and update lastDiveLogId+ −
ext_flash_create_new_dive_log(0);+ −
+ −
// copy header data+ −
ef_write_block(data,0x800,EF_HEADER, 1);+ −
+ −
// copy sample data+ −
ef_write_block(&data[0x800], length-0x800, EF_SAMPLE, 1);+ −
+ −
// update logFlashNextSampleStartAddress+ −
settingsGetPointer()->logFlashNextSampleStartAddress = actualPointerSample;+ −
}+ −
+ −
+ −
// ===============================================================================+ −
// ext_flash_read_header_memory+ −
/// @brief This function returns the entire header space 1:1+ −
/// @date 04-April-2016+ −
///+ −
/// @param *data 256KB output+ −
// ===============================================================================+ −
void ext_flash_read_header_memory(uint8_t *data)+ −
{+ −
actualAddress = HEADERSTART;+ −
actualPointerHeader = actualAddress;+ −
ext_flash_read_block_start();+ −
for(int i=0;i<8;i++)+ −
ext_flash_read_block_multi(&data[0x8000 * i], 0x8000, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
}+ −
+ −
+ −
// ===============================================================================+ −
// ext_flash_read_header_memory+ −
/// @brief This function erases and overwrites the entire logbook header block+ −
/// @date 04-April-2016+ −
///+ −
/// @param *data 256KB input of header memory 1:1+ −
// ===============================================================================+ −
void ext_flash_write_header_memory(uint8_t *data)+ −
{+ −
actualAddress = HEADERSTART;+ −
actualPointerHeader = actualAddress;+ −
ef_write_block(data, 0x40000, EF_HEADER, 0);+ −
}+ −
+ −
+ −
void ext_flash_open_read_sample(uint8_t StepBackwards, uint32_t *totalNumberOfBytes)+ −
{+ −
SSettings *settings = settingsGetPointer();+ −
uint8_t id;+ −
convert_Type dataStart, dataEnd;+ −
uint8_t header1, header2;+ −
+ −
id = settings->lastDiveLogId;+ −
id -= StepBackwards; /* 0-255, auto rollover */+ −
#+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
actualPointerHeader = actualAddress;+ −
+ −
ext_flash_read_block_start();+ −
/* little endian */+ −
ext_flash_read_block(&header1, EF_HEADER);+ −
ext_flash_read_block(&header2, EF_HEADER);+ −
dataStart.u8bit.byteHigh = 0;+ −
ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);+ −
dataEnd.u8bit.byteHigh = 0;+ −
ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER);+ −
ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER);+ −
ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
actualPointerSample = dataStart.u32bit;+ −
if(dataEnd.u32bit >= dataStart.u32bit)+ −
LengthLeftSampleRead = 1 + dataEnd.u32bit - dataStart.u32bit;+ −
else+ −
LengthLeftSampleRead = 2 + (dataStart.u32bit - SAMPLESTART) + (SAMPLESTOP - dataEnd.u32bit);+ −
*totalNumberOfBytes = LengthLeftSampleRead;+ −
+ −
actualAddress = actualPointerSample;+ −
ext_flash_read_block_start();+ −
}+ −
+ −
+ −
void ext_flash_read_next_sample_part(uint8_t *pSample, uint8_t length)+ −
{+ −
for(uint16_t i = 0; i < length; i++)+ −
ext_flash_read_block(&pSample[i], EF_SAMPLE);+ −
}+ −
+ −
+ −
void ext_flash_close_read_sample(void)+ −
{+ −
actualPointerSample = actualAddress;+ −
ext_flash_read_block_stop();+ −
}+ −
+ −
+ −
void ext_flash_set_entry_point(void)+ −
{+ −
entryPoint = actualAddress;+ −
}+ −
+ −
+ −
void ext_flash_reopen_read_sample_at_entry_point(void)+ −
{+ −
error_led_on();+ −
chip_unselect();+ −
wait_chip_not_busy();+ −
+ −
actualAddress = entryPoint;+ −
ext_flash_read_block_start();+ −
error_led_off();+ −
}+ −
+ −
/*+ −
uint8_t ext_flash_point_to_64k_block_in_headerSpace(uint8_t logId)+ −
{+ −
uint32_t pointerToData = logId * 0x800;+ −
+ −
return pointerToData / 0x10000;+ −
}+ −
*/+ −
+ −
+ −
// ===============================================================================+ −
// ext_flash_repair_dive_numbers_starting_count_helper+ −
/// @brief + −
/// @date 22-June-2016+ −
+ −
// ===============================================================================+ −
static uint16_t ext_flash_repair_dive_numbers_starting_count_helper(uint8_t *data, uint8_t *change64k, uint16_t startNumber, uint8_t lastLogId)+ −
{+ −
const uint32_t headerStep = 0x800;+ −
uint8_t actualLogId = 0;+ −
uint16_t oldNumber = 0;+ −
uint16_t actualNumber = 0;+ −
SLogbookHeader *ptrLogbookHeader = 0;+ −
+ −
if(startNumber == 0)+ −
return 0;+ −
+ −
actualNumber = startNumber - 1; + −
+ −
// where is the oldest dive (Which is now getting startNumber)+ −
// use first header for ease (without HEADER2OFFSET for end of dive header)+ −
// compare for lastLogId to prevent endless loop+ −
+ −
if(*(uint16_t*)&data[lastLogId * headerStep] != 0xFAFA)+ −
return 0;+ −
+ −
actualLogId = lastLogId - 1;+ −
while((*(uint16_t*)&data[actualLogId * headerStep] == 0xFAFA) && (actualLogId != lastLogId))+ −
{+ −
actualLogId--;+ −
}+ −
+ −
// now pointing to one behind the last+ −
while(actualLogId != lastLogId)+ −
{+ −
actualLogId++;+ −
actualNumber++;+ −
ptrLogbookHeader = (SLogbookHeader *)&data[actualLogId * headerStep];+ −
+ −
oldNumber = ptrLogbookHeader->diveNumber;+ −
if(oldNumber != actualNumber)+ −
{+ −
// change64k[ext_flash_point_to_64k_block_in_headerSpace(actualLogId )] = 1;+ −
change64k[(actualLogId * 0x800)/0x10000] = 1;+ −
ptrLogbookHeader->diveNumber = actualNumber;+ −
ptrLogbookHeader = (SLogbookHeader *)(&data[actualLogId * headerStep] + HEADER2OFFSET);+ −
ptrLogbookHeader->diveNumber = actualNumber;+ −
}+ −
}+ −
+ −
return actualNumber;+ −
}+ −
+ −
// ===============================================================================+ −
// ext_flash_repair_SPECIAL_dive_numbers_starting_count_with+ −
/// @brief This function+ −
/// @date 04-April-2016+ −
/// problem (160621): 64K blocks (32 dives) in the new flash memory chip+ −
/// This block needs to be deleted+ −
/// these where only 4KB block before+ −
/// @output endCount, last diveNumber+ −
+ −
// ===============================================================================+ −
uint16_t ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(uint16_t startCount)+ −
{+ −
uint32_t logCopyDataPtr = 0;+ −
uint8_t *data;+ −
uint16_t lastCount;+ −
uint8_t listOfChanged64kBlocks[8]; // 32 dives each 64K+ −
+ −
logCopyDataPtr = getFrame(97);+ −
data = (uint8_t *)logCopyDataPtr;+ −
+ −
for(int i=0;i<8;i++)+ −
listOfChanged64kBlocks[i] = 0;+ −
+ −
actualAddress = HEADERSTART;+ −
ext_flash_read_block_start();+ −
ext_flash_read_block_multi(data,0x100000,EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
lastCount = ext_flash_repair_dive_numbers_starting_count_helper(data, listOfChanged64kBlocks, startCount, settingsGetPointer()->lastDiveLogId);+ −
+ −
for(int i=0;i<8;i++)+ −
{+ −
if(listOfChanged64kBlocks[i] != 0)+ −
{+ −
actualPointerHeader = HEADERSTART + (i * 0x10000);+ −
ef_write_block(&data[i * 0x10000], 0x10000, EF_HEADER, 0);+ −
}+ −
}+ −
+ −
releaseFrame(97,logCopyDataPtr);+ −
if(settingsGetPointer()->totalDiveCounter < lastCount)+ −
{+ −
settingsGetPointer()->totalDiveCounter = lastCount;+ −
}+ −
return lastCount;+ −
}+ −
+ −
/*+ −
void OLD_ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(uint16_t startCount)+ −
{+ −
uint16_t counterStorage[256];+ −
uint8_t start = 0xFF;+ −
uint32_t logCopyDataPtr = 0;+ −
uint8_t *data;+ −
uint8_t startAbsolute = 0;+ −
int16_t count = 0;+ −
_Bool repair = 0;+ −
uint8_t startBackup = 0;+ −
+ −
SLogbookHeader tempLogbookHeader;+ −
SLogbookHeader *ptrHeaderInData1a;+ −
SLogbookHeader *ptrHeaderInData1b;+ −
SLogbookHeader *ptrHeaderInData2a;+ −
SLogbookHeader *ptrHeaderInData2b;+ −
+ −
logCopyDataPtr = getFrame(97);+ −
data = (uint8_t *)logCopyDataPtr;+ −
ptrHeaderInData1a = (SLogbookHeader *)logCopyDataPtr;+ −
ptrHeaderInData1b = (SLogbookHeader *)(logCopyDataPtr + HEADER2OFFSET);+ −
ptrHeaderInData2a = (SLogbookHeader *)(logCopyDataPtr + 0x800);+ −
ptrHeaderInData2b = (SLogbookHeader *)(logCopyDataPtr + 0x800 + HEADER2OFFSET);+ −
+ −
// get data+ −
for(int StepBackwards = 0; StepBackwards < 255; StepBackwards++)+ −
{+ −
logbook_getHeader(StepBackwards, &tempLogbookHeader);+ −
counterStorage[StepBackwards+1] = tempLogbookHeader.diveNumber;+ −
if(tempLogbookHeader.diveHeaderStart == 0xFAFA)+ −
start = StepBackwards;+ −
else+ −
break;+ −
}+ −
+ −
if(start == 0xFF)+ −
return;+ −
+ −
count = start + 1;+ −
startAbsolute = settingsGetPointer()->lastDiveLogId;+ −
+ −
+ −
+ −
if(start%2)+ −
{+ −
if(counterStorage[start] != startCount)+ −
{+ −
// clear data+ −
for(int i=0;i<0x800*2;i++)+ −
data[i] = 0xFF;+ −
+ −
uint8_t id = settingsGetPointer()->lastDiveLogId;+ −
id -= start; // 0-255, auto rollover+ −
+ −
// copy primary/pre-dive+ −
actualAddress = HEADERSTART + (0x800 * id);+ −
ext_flash_read_block_start();+ −
for(int i = 0; i < HEADERSIZE; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// copy main/secondary/post-dive+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
for(int i = 0x400; i < HEADERSIZE+0x400; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// repair+ −
ptrHeaderInData2a->diveNumber = startCount;+ −
ptrHeaderInData2b->diveNumber = startCount;+ −
startCount++;+ −
+ −
// write+ −
actualAddress = HEADERSTART + (0x800 * (id-1));+ −
ef_write_block(data,0x800*2,EF_HEADER, 0);+ −
}+ −
start--;+ −
}+ −
+ −
// for(int count = start; count > -1; count -= 2)+ −
+ −
while(count > 0)+ −
{+ −
// clear data+ −
for(int i=0;i<0x1000;i++)+ −
data[i] = 0xFF;+ −
+ −
repair = 0;+ −
+ −
startBackup = startAbsolute;+ −
+ −
if(startAbsolute%2) // 0x800 to 0x1000+ −
{+ −
// copy second pre-dive+ −
actualAddress = HEADERSTART + (0x800 * startAbsolute);+ −
ext_flash_read_block_start();+ −
for(int i = 0x800; i < HEADERSIZE+0x800; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// copy second post-dive+ −
actualAddress = HEADERSTART + HEADER2OFFSET + (0x800 * startAbsolute);+ −
ext_flash_read_block_start();+ −
for(int i = 0xC00; i < HEADERSIZE+0xC00; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
if(counterStorage[count] != startCount)+ −
{+ −
ptrHeaderInData2a->diveNumber = startCount;+ −
ptrHeaderInData2b->diveNumber = startCount;+ −
repair = 1; + −
}+ −
startCount += 1;+ −
+ −
startAbsolute -= 1;+ −
count -= 1;+ −
+ −
if(count > 0)+ −
{+ −
// copy first pre-dive+ −
actualAddress = HEADERSTART + (0x800 * startAbsolute);+ −
ext_flash_read_block_start();+ −
for(int i = 0; i < HEADERSIZE; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// copy first post-dive+ −
actualAddress = HEADERSTART + (0x800 * startAbsolute);+ −
ext_flash_read_block_start();+ −
for(int i = 0x400; i < HEADERSIZE+0x400; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
if(counterStorage[count] != startCount)+ −
{+ −
ptrHeaderInData1a->diveNumber = startCount;+ −
ptrHeaderInData1b->diveNumber = startCount;+ −
repair = 1;+ −
}+ −
startCount += 1;+ −
+ −
startAbsolute -= 1;+ −
count -= 1;+ −
}+ −
}+ −
else+ −
{+ −
// copy first pre-dive+ −
actualAddress = HEADERSTART + (0x800 * startAbsolute);+ −
ext_flash_read_block_start();+ −
for(int i = 0; i < HEADERSIZE; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
// copy first post-dive+ −
actualAddress = HEADERSTART + (0x800 * startAbsolute);+ −
ext_flash_read_block_start();+ −
for(int i = 0x400; i < HEADERSIZE+0x400; i++)+ −
ext_flash_read_block(&data[i], EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
if(counterStorage[count] != startCount)+ −
{+ −
ptrHeaderInData1a->diveNumber = startCount;+ −
ptrHeaderInData1b->diveNumber = startCount;+ −
repair = 1;+ −
}+ −
startCount += 1;+ −
+ −
startAbsolute -= 1;+ −
count -= 1;+ −
}+ −
+ −
// write+ −
if(repair)+ −
{+ −
actualPointerHeader = HEADERSTART + (0x1000 * startBackup%2);+ −
ef_write_block(data,0x1000,EF_HEADER, 0);+ −
}+ −
}+ −
releaseFrame(97,logCopyDataPtr);+ −
settingsGetPointer()->totalDiveCounter = startCount;+ −
}+ −
*/+ −
+ −
// ===============================================================================+ −
// ext_flash_repair_dive_log+ −
/// @brief This function + −
/// does set+ −
/// logFlashNextSampleStartAddress+ −
/// and+ −
/// lastDiveLogId+ −
///+ −
void ext_flash_repair_dive_log(void)+ −
{+ −
uint8_t header1, header2;+ −
convert_Type dataStart;+ −
+ −
for(int id = 0; id < 255;id++)+ −
{+ −
actualAddress = HEADERSTART + (0x800 * id);+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&header1, EF_HEADER);+ −
ext_flash_read_block(&header2, EF_HEADER);+ −
dataStart.u8bit.byteHigh = 0;+ −
ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
if((header1 == 0xFA) && (header2 == 0xFA))+ −
{+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&header1, EF_HEADER);+ −
ext_flash_read_block(&header2, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
if((header1 != 0xFA) || (header2 != 0xFA))+ −
{+ −
actualPointerSample = dataStart.u32bit;+ −
actualAddress = actualPointerSample;+ −
logbook_recover_brokenlog(id);+ −
SSettings *settings = settingsGetPointer();+ −
settings->logFlashNextSampleStartAddress = actualPointerSample;+ −
}+ −
}+ −
}+ −
ext_flash_find_start();+ −
}+ −
+ −
+ −
static void ext_flash_find_start(void)+ −
{+ −
uint8_t id;+ −
uint8_t header1, header2;+ −
convert_Type dataStart, dataEnd;+ −
+ −
for(id = 0; id < 255;id++)+ −
{+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&header1, EF_HEADER);+ −
ext_flash_read_block(&header2, EF_HEADER);+ −
dataStart.u8bit.byteHigh = 0;+ −
ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
if((header1 == 0xFF) && (header2 == 0xFF))+ −
{+ −
break;+ −
}+ −
}+ −
id--;+ −
SSettings *settings = settingsGetPointer();+ −
settings->lastDiveLogId = id;+ −
+ −
actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET;+ −
actualPointerHeader = actualAddress;+ −
+ −
ext_flash_read_block_start();+ −
+ −
ext_flash_read_block(&header1, EF_HEADER);+ −
ext_flash_read_block(&header2, EF_HEADER);+ −
dataStart.u8bit.byteHigh = 0;+ −
ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER);+ −
ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER);+ −
dataEnd.u8bit.byteHigh = 0;+ −
ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER);+ −
ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER);+ −
ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER);+ −
ext_flash_read_block_stop();+ −
+ −
//Find free space+ −
if((header1 == 0xFA) && (header2 == 0xFA))+ −
{+ −
uint8_t uiRead = 0;+ −
int countFF = 0;+ −
//End of last complete dive+ −
actualPointerSample = dataEnd.u32bit ;+ −
actualAddress = actualPointerSample;+ −
//Check if there are samples of dives with less than half a minute+ −
while(true)+ −
{+ −
ext_flash_read_block_start();+ −
ext_flash_read_block(&uiRead, EF_SAMPLE);+ −
if(uiRead == 0xFF)+ −
countFF++;+ −
else+ −
countFF = 0;+ −
+ −
+ −
+ −
if(countFF == 10)+ −
{+ −
actualAddress -= 10;+ −
break;+ −
}+ −
+ −
//New page: clear+ −
if(ext_flash_erase_if_on_page_start())+ −
break;+ −
}+ −
// Set new start address+ −
actualPointerSample = actualAddress;+ −
settings->logFlashNextSampleStartAddress = actualPointerSample;+ −
}+ −
else+ −
{+ −
settings->logFlashNextSampleStartAddress = SAMPLESTART;+ −
}+ −
}+ −
+ −
+ −
#endif+ −
+ −
static void ext_flash_disable_protection(void)+ −
{+ −
/* + −
extFlashStatusBit8_Type status;+ −
+ −
status.uw = 0;+ −
+ −
wait_chip_not_busy();+ −
write_spi(0x50,RELEASE); // EWSR+ −
write_spi(0x01,HOLDCS); // WRSR+ −
write_spi(status.uw,RELEASE); // new status+ −
*/+ −
}+ −
+ −
+ −
void ext_flash_disable_protection_for_logbook(void)+ −
{+ −
/*+ −
extFlashStatusBit8_Type status;+ −
+ −
status.uw = 0;+ −
status.ub.BlockProtect0 = 1;+ −
status.ub.BlockProtect1 = 0;+ −
status.ub.BlockProtect2 = 1;+ −
status.ub.BlockProtect3 = 0; // not set in OSTC3. Why?+ −
+ −
wait_chip_not_busy();+ −
write_spi(0x50,RELEASE); // EWSR+ −
write_spi(0x01,HOLDCS); // WRSR+ −
write_spi(status.uw,RELEASE); // new status+ −
*/ + −
}+ −
+ −
+ −
void ext_flash_enable_protection(void)+ −
{+ −
/* + −
extFlashStatusBit8_Type status;+ −
+ −
status.uw = 0;+ −
status.ub.BlockProtect0 = 1;+ −
status.ub.BlockProtect1 = 1;+ −
status.ub.BlockProtect2 = 1;+ −
status.ub.BlockProtect3 = 1; // not set in OSTC3. Why?+ −
+ −
wait_chip_not_busy();+ −
write_spi(0x50,RELEASE); // EWSR+ −
write_spi(0x01,HOLDCS); // WRSR+ −
write_spi(status.uw,RELEASE); // new status+ −
*/+ −
}+ −
+ −
+ −
/*void ext_flash_erase_chip(void)+ −
{+ −
wait_chip_not_busy();+ −
write_spi(0x06,RELEASE);+ −
write_spi(0x60,RELEASE);+ −
wait_chip_not_busy();+ −
}*/+ −
+ −
void ext_flash_erase_firmware(void)+ −
{+ −
uint32_t size, blocks_64k;+ −
+ −
actualAddress = FWSTART;+ −
size = 1 + FWSTOP - FWSTART;+ −
blocks_64k = size / 0x10000;+ −
ef_erase_64K(blocks_64k);+ −
}+ −
+ −
void ext_flash_erase_firmware2(void)+ −
{+ −
uint32_t size, blocks_64k;+ −
+ −
actualAddress = FWSTART2;+ −
size = 1 + FWSTOP2 - FWSTART2;+ −
blocks_64k = size / 0x10000;+ −
ef_erase_64K(blocks_64k);+ −
}+ −
+ −
+ −
+ −
void ext_flash_erase_logbook(void)+ −
{+ −
uint32_t size, blocks_64k;+ −
+ −
ext_flash_disable_protection_for_logbook();+ −
+ −
actualAddress = SAMPLESTART;+ −
size = 1 + SAMPLESTOP - SAMPLESTART;+ −
blocks_64k = size / 0x10000;+ −
ef_erase_64K(blocks_64k);+ −
+ −
actualAddress = HEADERSTART;+ −
size = 1 + HEADERSTOP - HEADERSTART;+ −
blocks_64k = size / 0x10000;+ −
ef_erase_64K(blocks_64k);+ −
+ −
ext_flash_enable_protection();+ −
}+ −
+ −
+ −
static void ext_flash_erase4kB(void)+ −
{+ −
wait_chip_not_busy();+ −
write_spi(0x06,RELEASE);/* WREN */+ −
write_spi(0x20,HOLDCS);/* sector erase cmd */+ −
write_address(RELEASE);+ −
}+ −
+ −
/* be careful - might not work with entire family and other products+ −
* see page 14 of LOGBOOK_V3_S25FS-S_00-271247.pdf+ −
*/+ −
static void ext_flash_erase32kB(void)+ −
{+ −
uint32_t actualAddress_backup;+ −
+ −
actualAddress_backup = actualAddress;+ −
actualAddress = 0;+ −
wait_chip_not_busy();+ −
write_spi(0x06,RELEASE);/* WREN */+ −
write_spi(0xD8,HOLDCS);/* sector erase cmd */+ −
write_address(RELEASE);+ −
actualAddress = actualAddress_backup;+ −
}+ −
+ −
+ −
static void ext_flash_erase64kB(void)+ −
{+ −
wait_chip_not_busy();+ −
write_spi(0x06,RELEASE);/* WREN */+ −
write_spi(0xD8,HOLDCS);/* sector erase cmd */+ −
write_address(RELEASE);+ −
}+ −
+ −
+ −
void ext_flash_read_block_start(void)+ −
{+ −
wait_chip_not_busy();+ −
write_spi(0x03,HOLDCS); /* WREN */+ −
write_address(HOLDCS);+ −
}+ −
+ −
/* 4KB, 32KB, 64 KB, not the upper 16 MB with 4 Byte address at the moment */+ −
static uint8_t ext_flash_erase_if_on_page_start(void)+ −
{+ −
if(actualAddress < 0x00008000)+ −
{+ −
/* 4K Byte is 0x1000 */+ −
if((actualAddress & 0xFFF) == 0)+ −
{+ −
ext_flash_erase4kB();+ −
return 1;+ −
}+ −
} + −
else+ −
if(actualAddress < 0x00010000)+ −
{+ −
/* 32K Byte is only one page */+ −
if(actualAddress == 0x00010000)+ −
{+ −
ext_flash_erase32kB();+ −
return 1;+ −
}+ −
} + −
else+ −
{+ −
/* 64K Byte is 0x10000 */+ −
if((actualAddress & 0xFFFF) == 0)+ −
{+ −
ext_flash_erase64kB();+ −
return 1;+ −
}+ −
} + −
return 0;+ −
}+ −
+ −
+ −
static void ext_flash_read_block(uint8_t *getByte, uint8_t type)+ −
{+ −
*getByte = read_spi(HOLDCS);/* read data */+ −
ext_flash_incf_address(type);+ −
}+ −
+ −
+ −
static void ext_flash_read_block_multi(void *getByte, uint32_t size, uint8_t type)+ −
{+ −
uint8_t *data;+ −
data = getByte;+ −
+ −
for(uint32_t i=0;i<size;i++)+ −
{+ −
data[i] = read_spi(HOLDCS);/* read data */+ −
ext_flash_incf_address(type);+ −
}+ −
}+ −
+ −
+ −
static void ext_flash_read_block_stop(void)+ −
{+ −
chip_unselect();+ −
}+ −
+ −
+ −
/* Private functions ---------------------------------------------------------*/+ −
+ −
static void ef_write_block(uint8_t * sendByte, uint32_t length, uint8_t type, uint8_t do_not_erase)+ −
{+ −
uint32_t remaining_page_size, remaining_length, remaining_space_to_ring_end;+ −
+ −
if(!length)+ −
return;+ −
+ −
uint32_t ringStart, ringStop;+ −
+ −
switch(type)+ −
{+ −
case EF_HEADER:+ −
actualAddress = actualPointerHeader;+ −
ringStart = HEADERSTART;+ −
ringStop = HEADERSTOP;+ −
break;+ −
case EF_SAMPLE:+ −
actualAddress = actualPointerSample;+ −
ringStart = SAMPLESTART;+ −
ringStop = SAMPLESTOP;+ −
break;+ −
case EF_DEVICEDATA:+ −
actualAddress = actualPointerDevicedata;+ −
ringStart = DDSTART;+ −
ringStop = DDSTOP;+ −
break;+ −
case EF_VPMDATA:+ −
actualAddress = actualPointerVPM;+ −
ringStart = VPMSTART;+ −
ringStop = VPMSTOP;+ −
break;+ −
case EF_SETTINGS:+ −
actualAddress = actualPointerSettings;+ −
ringStart = SETTINGSSTART;+ −
ringStop = SETTINGSSTOP;+ −
break;+ −
case EF_FIRMWARE:+ −
actualAddress = actualPointerFirmware;+ −
ringStart = FWSTART;+ −
ringStop = FWSTOP;+ −
break;+ −
case EF_FIRMWARE2:+ −
actualAddress = actualPointerFirmware2;+ −
ringStart = FWSTART2;+ −
ringStop = FWSTOP2;+ −
break;+ −
default:+ −
ringStart = FLASHSTART;+ −
ringStop = FLASHSTOP;+ −
break;+ −
}+ −
/* safety */+ −
if(actualAddress < ringStart)+ −
actualAddress = ringStart;+ −
+ −
if(do_not_erase == 0)+ −
ext_flash_erase_if_on_page_start();+ −
+ −
for(uint32_t i=0;i<length;i++)+ −
{+ −
ef_hw_rough_delay_us(5);+ −
wait_chip_not_busy();+ −
write_spi(0x06,RELEASE); /* WREN */+ −
write_spi(0x02,HOLDCS); /* write cmd */+ −
write_address(HOLDCS);+ −
+ −
remaining_length = length - i;+ −
remaining_page_size = actualAddress & 0xFF;+ −
remaining_space_to_ring_end = ringStop - actualAddress;+ −
+ −
if((remaining_page_size == 0) && (remaining_length >= 256) && (remaining_space_to_ring_end >= 256))+ −
{+ −
for(int j=0; j<255; j++)+ −
{+ −
write_spi(sendByte[i],HOLDCS);/* write data */+ −
actualAddress++;+ −
i++;+ −
}+ −
}+ −
/* byte with RELEASE */+ −
write_spi(sendByte[i],RELEASE);/* write data */+ −
actualAddress++;+ −
if(actualAddress > ringStop)+ −
actualAddress = ringStart;+ −
if(do_not_erase == 0)+ −
ext_flash_erase_if_on_page_start();+ −
}+ −
switch(type)+ −
{+ −
case EF_HEADER:+ −
actualPointerHeader = actualAddress;+ −
break;+ −
case EF_SAMPLE:+ −
actualPointerSample = actualAddress;+ −
break;+ −
case EF_DEVICEDATA:+ −
actualPointerDevicedata = actualAddress;+ −
break;+ −
case EF_VPMDATA:+ −
actualPointerVPM = actualAddress;+ −
break;+ −
case EF_SETTINGS:+ −
actualPointerSettings = actualAddress;+ −
break;+ −
case EF_FIRMWARE:+ −
actualPointerFirmware = actualAddress;+ −
break;+ −
case EF_FIRMWARE2:+ −
actualPointerFirmware2 = actualAddress;+ −
break;+ −
default:+ −
break;+ −
}+ −
}+ −
+ −
+ −
static _Bool ext_flash_test_remaining_space_of_page_empty(uint32_t pointer, uint16_t length)+ −
{+ −
if((pointer & 0xFFF) == 0)+ −
return 1;+ −
+ −
uint32_t backup = actualAddress;+ −
uint8_t data;+ −
uint32_t size_to_page_end;+ −
+ −
size_to_page_end = 0x1000 - (pointer & 0xFFF);+ −
if(length > size_to_page_end)+ −
length = size_to_page_end;+ −
+ −
actualAddress = pointer;+ −
ext_flash_read_block_start();+ −
+ −
for(uint16_t i = 0; i<length; i++)+ −
{+ −
ext_flash_read_block(&data, 255); // 255 = ENTIRE FLASH+ −
if(data != 0xFF)+ −
{+ −
ext_flash_read_block_stop();+ −
actualAddress = backup;+ −
return 0;+ −
}+ −
}+ −
ext_flash_read_block_stop();+ −
actualAddress = backup;+ −
return 1;+ −
}+ −
+ −
+ −
static void ext_flash_set_to_begin_of_next_page(uint32_t *pointer, uint8_t type)+ −
{+ −
uint32_t ringStart, ringStop;+ −
+ −
switch(type)+ −
{+ −
case EF_HEADER:+ −
ringStart = HEADERSTART;+ −
ringStop = HEADERSTOP;+ −
break;+ −
case EF_SAMPLE:+ −
ringStart = SAMPLESTART;+ −
ringStop = SAMPLESTOP;+ −
break;+ −
case EF_DEVICEDATA:+ −
ringStart = DDSTART;+ −
ringStop = DDSTOP;+ −
break;+ −
case EF_VPMDATA:+ −
ringStart = VPMSTART;+ −
ringStop = VPMSTOP;+ −
break;+ −
case EF_SETTINGS:+ −
ringStart = SETTINGSSTART;+ −
ringStop = SETTINGSSTOP;+ −
break;+ −
default:+ −
ringStart = FLASHSTART;+ −
ringStop = FLASHSTOP;+ −
break;+ −
}+ −
+ −
*pointer = (*pointer & 0xFFF) + 0x1000;+ −
+ −
if((*pointer < ringStart) || (*pointer >= ringStop))+ −
*pointer = ringStart;+ −
}+ −
+ −
+ −
static void ef_erase_64K(uint32_t blocks)+ −
{+ −
for(uint32_t i = 0; i < blocks; i++)+ −
{+ −
wait_chip_not_busy();+ −
write_spi(0x06,RELEASE);/* WREN */+ −
write_spi(0xD8,HOLDCS);/* 64k erase cmd */+ −
write_address(RELEASE);+ −
actualAddress += 0x10000;+ −
HAL_Delay(25);+ −
}+ −
}+ −
+ −
+ −
static void chip_unselect(void)+ −
{+ −
HAL_GPIO_WritePin(EXTFLASH_CSB_GPIO_PORT,EXTFLASH_CSB_PIN,GPIO_PIN_SET); // chip select+ −
}+ −
+ −
static void chip_select(void)+ −
{+ −
HAL_GPIO_WritePin(EXTFLASH_CSB_GPIO_PORT,EXTFLASH_CSB_PIN,GPIO_PIN_RESET); // chip select+ −
}+ −
+ −
static void error_led_on(void)+ −
{+ −
HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_SET);+ −
}+ −
+ −
static void error_led_off(void)+ −
{+ −
HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_RESET);+ −
}+ −
+ −
+ −
static uint8_t read_spi(uint8_t unselect_CS_afterwards)+ −
{+ −
uint8_t byte;+ −
+ −
chip_select();+ −
+ −
if(HAL_SPI_Receive(&hspiDisplay, &byte, 1, 10000) != HAL_OK)+ −
Error_Handler_extflash();+ −
+ −
while (HAL_SPI_GetState(&hspiDisplay) != HAL_SPI_STATE_READY)+ −
{+ −
}+ −
if(unselect_CS_afterwards)+ −
chip_unselect();+ −
+ −
return byte;+ −
}+ −
+ −
+ −
static void write_spi(uint8_t data, uint8_t unselect_CS_afterwards)+ −
{+ −
chip_select();+ −
+ −
if(HAL_SPI_Transmit(&hspiDisplay, &data, 1, 10000) != HAL_OK)+ −
Error_Handler_extflash();+ −
+ −
while (HAL_SPI_GetState(&hspiDisplay) != HAL_SPI_STATE_READY)+ −
{+ −
}+ −
if(unselect_CS_afterwards)+ −
chip_unselect();+ −
}+ −
+ −
+ −
static void write_address(uint8_t unselect_CS_afterwards)+ −
{+ −
uint8_t hi, med ,lo;+ −
+ −
hi = (actualAddress >> 16) & 0xFF;+ −
med = (actualAddress >> 8) & 0xFF;+ −
lo = actualAddress & 0xFF;+ −
+ −
write_spi(hi, HOLDCS);+ −
write_spi(med, HOLDCS);+ −
write_spi(lo, unselect_CS_afterwards);+ −
}+ −
+ −
+ −
static void wait_chip_not_busy(void)+ −
{+ −
uint8_t status;+ −
+ −
chip_unselect();+ −
+ −
write_spi(0x05,HOLDCS); /* RDSR */+ −
status = read_spi(HOLDCS);/* read status */+ −
while(status & 0x01)+ −
{+ −
HAL_Delay(1);+ −
status = read_spi(HOLDCS);/* read status */+ −
}+ −
chip_unselect();+ −
}+ −
+ −
+ −
static void ext_flash_incf_address(uint8_t type)+ −
{+ −
uint32_t ringStart, ringStop;+ −
+ −
actualAddress += 1;+ −
+ −
switch(type)+ −
{+ −
case EF_HEADER:+ −
ringStart = HEADERSTART;+ −
ringStop = HEADERSTOP;+ −
break;+ −
case EF_SAMPLE:+ −
ringStart = SAMPLESTART;+ −
ringStop = SAMPLESTOP;+ −
break;+ −
case EF_DEVICEDATA:+ −
ringStart = DDSTART;+ −
ringStop = DDSTOP;+ −
break;+ −
case EF_VPMDATA:+ −
ringStart = VPMSTART;+ −
ringStop = VPMSTOP;+ −
break;+ −
case EF_SETTINGS:+ −
ringStart = SETTINGSSTART;+ −
ringStop = SETTINGSSTOP;+ −
break;+ −
case EF_FIRMWARE:+ −
ringStart = FWSTART;+ −
ringStop = FWSTOP;+ −
break;+ −
case EF_FIRMWARE2:+ −
ringStart = FWSTART2;+ −
ringStop = FWSTOP2;+ −
break;+ −
default:+ −
ringStart = FLASHSTART;+ −
ringStop = FLASHSTOP;+ −
break;+ −
}+ −
+ −
if((actualAddress < ringStart) || (actualAddress > ringStop))+ −
actualAddress = ringStart;+ −
}+ −
+ −
+ −
static void ext_flash_decf_address_ring(uint8_t type)+ −
{+ −
uint32_t ringStart, ringStop;+ −
+ −
switch(type)+ −
{+ −
case EF_HEADER:+ −
ringStart = HEADERSTART;+ −
ringStop = HEADERSTOP;+ −
break;+ −
case EF_SAMPLE:+ −
ringStart = SAMPLESTART;+ −
ringStop = SAMPLESTOP;+ −
break;+ −
case EF_DEVICEDATA:+ −
ringStart = DDSTART;+ −
ringStop = DDSTOP;+ −
break;+ −
case EF_VPMDATA:+ −
ringStart = VPMSTART;+ −
ringStop = VPMSTOP;+ −
break;+ −
case EF_SETTINGS:+ −
ringStart = SETTINGSSTART;+ −
ringStop = SETTINGSSTOP;+ −
break;+ −
case EF_FIRMWARE:+ −
ringStart = FWSTART;+ −
ringStop = FWSTOP;+ −
break;+ −
case EF_FIRMWARE2:+ −
ringStart = FWSTART2;+ −
ringStop = FWSTOP2;+ −
break;+ −
default:+ −
ringStart = FLASHSTART;+ −
ringStop = FLASHSTOP;+ −
break;+ −
}+ −
+ −
if((actualAddress <= ringStart) || (actualAddress > ringStop))+ −
actualAddress = ringStop;+ −
else+ −
actualAddress -= 1;+ −
}+ −
+ −
+ −
static void ef_hw_rough_delay_us(uint32_t delayUs)+ −
{+ −
if(!delayUs)+ −
return;+ −
delayUs*= 12;+ −
while(delayUs--);+ −
return;+ −
}+ −
+ −
static void Error_Handler_extflash(void)+ −
{+ −
while(1)+ −
{+ −
}+ −
}+ −
/*+ −
uint8_t ext_flash_erase_firmware_if_not_empty(void)+ −
{+ −
const uint8_t TESTSIZE_FW = 4;+ −
+ −
uint8_t data[TESTSIZE_FW];+ −
uint8_t notEmpty = 0;+ −
+ −
actualAddress = FWSTART;+ −
ext_flash_read_block_start();+ −
for(int i = 0; i < TESTSIZE_FW; i++)+ −
{+ −
ext_flash_read_block(&data[i], EF_FIRMWARE);+ −
if(data[i] != 0xFF)+ −
notEmpty = 1;+ −
}+ −
ext_flash_read_block_stop();+ −
+ −
if(notEmpty)+ −
{+ −
ext_flash_erase_firmware();+ −
return 1;+ −
}+ −
else+ −
return 0;+ −
}+ −
+ −
uint8_t ext_flash_erase_firmware2_if_not_empty(void)+ −
{+ −
const uint8_t TESTSIZE_FW = 4;+ −
+ −
uint8_t data[TESTSIZE_FW];+ −
uint8_t notEmpty = 0;+ −
+ −
actualAddress = FWSTART2;+ −
ext_flash_read_block_start();+ −
for(int i = 0; i < TESTSIZE_FW; i++)+ −
{+ −
ext_flash_read_block(&data[i], EF_FIRMWARE2);+ −
if(data[i] != 0xFF)+ −
notEmpty = 1;+ −
}+ −
ext_flash_read_block_stop();+ −
+ −
if(notEmpty)+ −
{+ −
ext_flash_erase_firmware2();+ −
return 1;+ −
}+ −
else+ −
return 0;+ −
}*/+ −