Mercurial > public > ostc4
diff BootLoader/Src/externLogbookFlash_mini.c @ 985:aeafa631147d BootloaderOstc5
Exchange shared files with Bootloader specific mini version
author | Ideenmodellierer |
---|---|
date | Sun, 30 Mar 2025 21:32:37 +0200 (2 weeks ago) |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BootLoader/Src/externLogbookFlash_mini.c Sun Mar 30 21:32:37 2025 +0200 @@ -0,0 +1,872 @@ +/** + ****************************************************************************** + * @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" + +/* 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 preparedPageAddress = 0; +static uint32_t closeSectorAddress = 0; +static uint32_t actualPointerHeader = 0; +static uint32_t actualPointerSample = 0; +static uint32_t actualPointerDevicedata = DDSTART; +static uint32_t actualPointerVPM = 0; +static uint32_t actualPointerSettings = SETTINGSSTART; +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 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_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); + + +/* 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; + } +} + +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); +} + + + +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) + { + if(preparedPageAddress == actualAddress) /* has page already been prepared before? (at the moment for samples only) */ + { + preparedPageAddress = 0; + + } + else + { + 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; + uint32_t i=0; + + 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(); + } + + while( i<length) + { + 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 = 0xFF - (uint8_t)(actualAddress & 0xFF) +1; + remaining_space_to_ring_end = ringStop - actualAddress; + + if(remaining_length >= 256) + { + remaining_length = 255; /* up to 256 bytes may be written in one burst. Last byte is written with release */ + } + else + { + remaining_length--; /* last byte needed for release */ + } + if(remaining_length >= (remaining_page_size) ) /* use 256 byte page and calculate number of bytes left */ + { + remaining_length = remaining_page_size - 1; + } + if( (remaining_space_to_ring_end >= 256)) + { + for(int j=0; j<remaining_length; j++) + { + write_spi(sendByte[i],HOLDCS);/* write data */ + actualAddress++; + i++; + } + } + /* byte with RELEASE */ + write_spi(sendByte[i],RELEASE);/* write data */ + actualAddress++; + i++; + + 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 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 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 ef_hw_rough_delay_us(uint32_t delayUs) +{ + if(!delayUs) + return; + delayUs*= 12; + while(delayUs--); + return; +} + +static void Error_Handler_extflash(void) +{ + while(1) + { + } +} + +void ext_flash_CloseSector(void) +{ + uint32_t actualAddressBackup = actualAddress; + int i=0; + + if(closeSectorAddress != 0) + { + /* write some dummy bytes to the sector which is currently used for storing samples. This is done to "hide" problem if function is calles again */ + actualAddress = closeSectorAddress; + + wait_chip_not_busy(); + write_spi(0x06,RELEASE); /* WREN */ + write_spi(0x02,HOLDCS); /* write cmd */ + write_address(HOLDCS); + for(i = 0; i<8; i++) + { + write_spi(0xA5,HOLDCS);/* write data */ + actualAddress++; + } + /* byte with RELEASE */ + write_spi(0xA5,RELEASE);/* write data */ + actualAddress = actualAddressBackup; + closeSectorAddress = 0; + } +} + + +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; +}