mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-14 22:18:14 +08:00
695 lines
32 KiB
C
695 lines
32 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "mico.h"
|
|
#include "platform_config.h"
|
|
#include "platform_init.h"
|
|
#include "platform_peripheral.h"
|
|
#include "platform_toolchain.h"
|
|
#include "linker_symbols.h"
|
|
|
|
/*
|
|
* Test mode defines
|
|
*
|
|
* #define DEBUG_PRINT
|
|
* #define WIPE_SFLASH
|
|
* #define TEST_SFLASH_WRITE
|
|
* #define TEST_SFLASH_READ
|
|
* #define DEBUG_PRINT_READ_CONTENT
|
|
* #define DEBUG_PRINT_VERIFY_READ_CONTENT
|
|
*/
|
|
|
|
/******************************************************
|
|
* Macros
|
|
******************************************************/
|
|
//#define DEBUG_PRINT
|
|
|
|
#ifdef DEBUG_PRINT
|
|
#define flash_program_log(format, ...) custom_log("Flash", format, ##__VA_ARGS__)
|
|
#define DEBUG_PRINTF(x) printf x
|
|
#else
|
|
#define flash_program_log(format, ...)
|
|
#define DEBUG_PRINTF(x)
|
|
#endif /* ifdef DEBUG_PRINT */
|
|
|
|
/******************************************************
|
|
* Constants
|
|
******************************************************/
|
|
/*
|
|
* Commands to execute - bitwise OR together
|
|
* TCL script write_sflash.tcl must match these defines
|
|
*/
|
|
#define MFG_SPI_FLASH_COMMAND_NONE (0x00000000)
|
|
|
|
#define MFG_SPI_FLASH_COMMAND_INITIAL_VERIFY (0x00000001)
|
|
#define MFG_SPI_FLASH_COMMAND_ERASE_CHIP (0x00000002)
|
|
#define MFG_SPI_FLASH_COMMAND_WRITE (0x00000004)
|
|
#define MFG_SPI_FLASH_COMMAND_POST_WRITE_VERIFY (0x00000008)
|
|
#define MFG_SPI_FLASH_COMMAND_VERIFY_CHIP_ERASURE (0x00000010)
|
|
#define MFG_SPI_FLASH_COMMAND_READ (0x00000040)
|
|
#define MFG_SPI_FLASH_COMMAND_WRITE_ERASE_IF_NEEDED (0x00000080)
|
|
#define MFG_SPI_FLASH_COMMAND_WRITE_DONE (0x00000100)
|
|
|
|
#define WRITE_CHUNK_SIZE (8*1024) /* Writing in chunks is only needed to prevent reset by watchdog */
|
|
#define SECTOR_SIZE (4096)
|
|
|
|
int partition_remapping[] =
|
|
{
|
|
[BOOTLOADER_FIRMWARE_PARTITION_TCL] = MICO_PARTITION_BOOTLOADER,
|
|
[APPLICATION_FIRMWARE_PARTITION_TCL] = MICO_PARTITION_APPLICATION,
|
|
[ATE_FIRMWARE_PARTITION_TCL] = MICO_PARTITION_ATE,
|
|
[WIFI_FIRMWARE_PARTITION_TCL] = MICO_PARTITION_RF_FIRMWARE,
|
|
[PARAMETER_1_IMAGE_PARTITION_TCL] = MICO_PARTITION_PARAMETER_1,
|
|
[PARAMETER_2_IMAGE_PARTITION_TCL] = MICO_PARTITION_PARAMETER_2,
|
|
#ifdef MICO_USE_BT_PARTITION
|
|
[BT_PATCH_FIRMWARE_PARTITION_TCL] = MICO_PARTITION_BT_FIRMWARE,
|
|
#else
|
|
[BT_PATCH_FIRMWARE_PARTITION_TCL] = -1,
|
|
#endif
|
|
[FILESYSTEM_IMAGE_PARTITION_TCL] = -1,
|
|
|
|
};
|
|
|
|
/******************************************************
|
|
* Enumerations
|
|
******************************************************/
|
|
/*
|
|
* Result codes
|
|
* TCL script write_sflash.tcl must match this enum
|
|
*/
|
|
typedef enum
|
|
{
|
|
MFG_SPI_FLASH_RESULT_IN_PROGRESS = 0xffffffff,
|
|
MFG_SPI_FLASH_RESULT_OK = 0,
|
|
MFG_SPI_FLASH_RESULT_ERASE_FAILED = 1,
|
|
MFG_SPI_FLASH_RESULT_VERIFY_AFTER_WRITE_FAILED = 2,
|
|
MFG_SPI_FLASH_RESULT_SIZE_TOO_BIG_BUFFER = 3,
|
|
MFG_SPI_FLASH_RESULT_SIZE_TOO_BIG_CHIP = 4,
|
|
MFG_SPI_FLASH_RESULT_DCT_LOC_NOT_FOUND = 5,
|
|
MFG_SPI_FLASH_RESULT_WRITE_FAILED = 6,
|
|
MFG_SPI_FLASH_RESULT_READ_FAILED = 7,
|
|
MFG_SPI_FLASH_RESULT_END = 0x7fffffff /* force to 32 bits */
|
|
} mfg_spi_flash_result_t;
|
|
|
|
//extern const platform_qspi_t platform_qspi_peripherals[];
|
|
//extern int init_qsflash( /*@out@*/ const platform_qspi_t* peripheral, uint32_t flash_length, /*@out@*/ sflash_handle_t* const handle, sflash_write_allowed_t write_allowed_in );
|
|
//extern int qsflash_write( const sflash_handle_t* const handle, unsigned long device_address, const void* const data_addr, unsigned int size );
|
|
//extern int qsflash_read( const sflash_handle_t* const handle, unsigned long device_address, void* const data_addr, unsigned int size );
|
|
//extern int qsflash_sector_erase ( unsigned long device_address );
|
|
extern const mico_logic_partition_t mico_partitions[];
|
|
extern const platform_flash_t platform_flash_peripherals[];
|
|
|
|
/******************************************************
|
|
* Type Definitions
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Structures
|
|
******************************************************/
|
|
/*
|
|
* TCL script write_sflash.tcl must match this structure
|
|
*/
|
|
typedef struct
|
|
{
|
|
void * entry_point;
|
|
void * stack_addr;
|
|
unsigned long data_buffer_size;
|
|
} data_config_area_t;
|
|
|
|
/*
|
|
* TCL script write_sflash.tcl must match this structure
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
unsigned long size;
|
|
unsigned long partition;
|
|
unsigned long partition_offset;
|
|
unsigned long command;
|
|
mfg_spi_flash_result_t result;
|
|
unsigned char data[__JTAG_FLASH_WRITER_DATA_BUFFER_SIZE__ ];
|
|
} data_transfer_area_t;
|
|
|
|
/******************************************************
|
|
* Static Function Declarations
|
|
******************************************************/
|
|
#ifdef WIPE_SFLASH
|
|
static void add_wipe_data( void );
|
|
#elif defined( TEST_SFLASH_WRITE )
|
|
static void add_test_data( void );
|
|
#elif defined( TEST_SFLASH_READ )
|
|
static void read_test_data2( void );
|
|
#endif /* ifdef TEST_SFLASH_READ */
|
|
|
|
/******************************************************
|
|
* Variable Definitions
|
|
******************************************************/
|
|
static uint8_t Rx_Buffer[SECTOR_SIZE + 10]; /* A temporary buffer used for reading data from the Serial flash when performing verification */
|
|
|
|
/******************************************************************************
|
|
* This structure provides configuration parameters, and communication area
|
|
* to the TCL OpenOCD script
|
|
* It will be located at the start of RAM by the linker script
|
|
*****************************************************************************/
|
|
#if defined(__ICCARM__)
|
|
/* IAR specific */
|
|
#pragma section= "data_config_section"
|
|
const data_config_area_t data_config @ "data_config_section";
|
|
#endif /* #if defined(__ICCARM__) */
|
|
const data_config_area_t data_config =
|
|
{
|
|
.entry_point = (void*) ENTRY_ADDRESS,
|
|
.stack_addr = &link_stack_end,
|
|
.data_buffer_size = __JTAG_FLASH_WRITER_DATA_BUFFER_SIZE__,
|
|
};
|
|
|
|
/******************************************************************************
|
|
* This structure provides a transfer area for communications with the
|
|
* TCL OpenOCD script
|
|
* It will be located immediately after the data_config structure at the
|
|
* start of RAM by the linker script
|
|
*****************************************************************************/
|
|
#if defined (__ICCARM__)
|
|
/* IAR specific */
|
|
#pragma section= "data_transfer_section"
|
|
data_transfer_area_t data_transfer @ "data_transfer_section";
|
|
#else /* #if defined (__ICCARM__) */
|
|
data_transfer_area_t data_transfer;
|
|
#endif /* #if defined (__ICCARM__) */
|
|
|
|
/******************************************************
|
|
* Function Definitions
|
|
******************************************************/
|
|
|
|
int not_erased (const void *a1, size_t size)
|
|
{
|
|
uint8_t* cmp_ptr = (uint8_t *)a1;
|
|
uint8_t* end_ptr = (uint8_t *)a1 + size;
|
|
|
|
while ( ( cmp_ptr < end_ptr ) && ( *cmp_ptr == (uint8_t) 0xff ) )
|
|
{
|
|
cmp_ptr++;
|
|
}
|
|
|
|
/* No not erase if already all 0xFF*/
|
|
if ( cmp_ptr < end_ptr )
|
|
return (int)(cmp_ptr - (uint8_t *)a1 + 1);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
int main( void )
|
|
{
|
|
unsigned long pos;
|
|
// sflash_handle_t sflash_handle;
|
|
unsigned long chip_size = 0;
|
|
bool erase_once = true;
|
|
#if defined ( __IAR_SYSTEMS_ICC__ )
|
|
/* IAR allows init functions in __low_level_init(), but it is run before global
|
|
* variables have been initialised, so the following init still needs to be done
|
|
* When using GCC, this is done in crt0_GCC.c
|
|
*/
|
|
platform_init_mcu_infrastructure( );
|
|
platform_init_external_devices( );
|
|
#endif /* #elif defined ( __IAR_SYSTEMS_ICC__ ) */
|
|
|
|
//NoOS_setup_timing( );
|
|
|
|
#ifdef WIPE_SFLASH
|
|
add_wipe_data( );
|
|
#elif defined( TEST_SFLASH_WRITE )
|
|
add_test_data( );
|
|
#elif defined( TEST_SFLASH_READ )
|
|
read_test_data2( );
|
|
#endif /* ifdef TEST_SFLASH_READ */
|
|
|
|
#ifdef PLATFORM_HAS_OTP
|
|
platform_otp_setup( );
|
|
#endif /* ifdef PLATFORM_HAS_OTP */
|
|
|
|
/* loop forever */
|
|
while ( 1 == 1 )
|
|
{
|
|
flash_program_log( "Waiting for command" );
|
|
|
|
/* wait for a command to be written. */
|
|
/*@-infloopsuncon@*//* Lint: Loop variable is modified by JTAG writing directly into the data transfer memory */
|
|
while ( data_transfer.command == MFG_SPI_FLASH_COMMAND_NONE )
|
|
{
|
|
(void) platform_watchdog_kick( );
|
|
}
|
|
/*@-infloopsuncon@*/
|
|
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_IN_PROGRESS;
|
|
|
|
flash_program_log( "Received command: %s%s%s%s%s%s%s",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_INITIAL_VERIFY )? "INITIAL_VERIFY " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_ERASE_CHIP )? "ERASE_CHIP " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_WRITE )? "WRITE " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_POST_WRITE_VERIFY )? "POST_WRITE_VERIFY " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_VERIFY_CHIP_ERASURE )? "VERIFY_CHIP_ERASURE " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_READ )? "READ " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_WRITE_ERASE_IF_NEEDED)? "WRTIE_ERASE_IF_NEEDED " : "",
|
|
( data_transfer.command & MFG_SPI_FLASH_COMMAND_WRITE_DONE)? "MFG_SPI_FLASH_COMMAND_WRITE_DONE " : ""
|
|
);
|
|
flash_program_log( "Destination partition: %u, Destination address: %lx", partition_remapping[data_transfer.partition], data_transfer.partition_offset );
|
|
flash_program_log( "Size: %lu", data_transfer.size );
|
|
|
|
/* Check the data size is sane - cannot be bigger than the data storage area */
|
|
if ( data_transfer.size > (unsigned long) __JTAG_FLASH_WRITER_DATA_BUFFER_SIZE__ )
|
|
{
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_SIZE_TOO_BIG_BUFFER;
|
|
flash_program_log( "Size %lu too big to for storage area %d - aborting!", data_transfer.size, __JTAG_FLASH_WRITER_DATA_BUFFER_SIZE__);
|
|
goto back_to_idle;
|
|
}
|
|
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_READ) != 0 )
|
|
{
|
|
flash_program_log( "Reading data!" );
|
|
|
|
/* Read data from SPI FLASH memory */
|
|
pos = 0;
|
|
unsigned long position = 0;
|
|
position = pos + data_transfer.partition_offset;
|
|
if ( 0
|
|
!= MicoFlashRead( partition_remapping[data_transfer.partition], &position, data_transfer.data,
|
|
(unsigned int) data_transfer.size ) )
|
|
{
|
|
/* Read failed */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_READ_FAILED;
|
|
flash_program_log( "Read error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
#ifdef DEBUG_PRINT_READ_CONTENT
|
|
{
|
|
int i;
|
|
for( i = 0;i < data_transfer.size; i++ )
|
|
{
|
|
DEBUG_PRINTF( ( "%02X ", data_transfer.data[i]));
|
|
if( ( i & 0xf ) == 0xf )
|
|
{
|
|
DEBUG_PRINTF( ( "\r\n") );
|
|
}
|
|
}
|
|
}
|
|
#endif /* DEBUG_PRINT_READ_CONTENT */
|
|
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_OK;
|
|
flash_program_log( "Finished Read!" );
|
|
goto back_to_idle;
|
|
}
|
|
|
|
/* Check the data will fit on the sflash chip */
|
|
if ( (chip_size != 0) && (data_transfer.size + data_transfer.partition_offset > chip_size) )
|
|
{
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_SIZE_TOO_BIG_CHIP;
|
|
flash_program_log( "Size (%lu from address %lu) too big to fit on partition (%lu) - aborting!", data_transfer.size, data_transfer.partition_offset, chip_size );
|
|
goto back_to_idle;
|
|
}
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_INITIAL_VERIFY) != 0 )
|
|
{
|
|
flash_program_log( "Verifying existing data!" );
|
|
|
|
/* Read data from SPI FLASH memory */
|
|
pos = 0;
|
|
while ( pos < data_transfer.size )
|
|
{
|
|
unsigned int read_size =
|
|
(data_transfer.size - pos > (unsigned long) sizeof(Rx_Buffer)) ?
|
|
(unsigned int) sizeof(Rx_Buffer) :
|
|
(unsigned int) (data_transfer.size - pos);
|
|
unsigned long position = 0;
|
|
position = pos + data_transfer.partition_offset;
|
|
if ( 0
|
|
!= MicoFlashRead( partition_remapping[data_transfer.partition], &position, Rx_Buffer,
|
|
read_size ) )
|
|
{
|
|
/* Verify Error - Chip not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_READ_FAILED;
|
|
flash_program_log( "Read error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
if ( 0 != memcmp( Rx_Buffer, &data_transfer.data[pos], (size_t) read_size ) )
|
|
{
|
|
/* Existing data different */
|
|
flash_program_log( "Existing data is different - stop verification" );
|
|
/*@innerbreak@*//* Only break out of inner-most loop */
|
|
break;
|
|
}
|
|
pos += read_size;
|
|
(void) platform_watchdog_kick( );
|
|
}
|
|
if ( pos >= data_transfer.size )
|
|
{
|
|
/* Existing data matches */
|
|
/* No write required */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_OK;
|
|
flash_program_log( "Existing data matches - successfully aborting!" );
|
|
goto back_to_idle;
|
|
}
|
|
}
|
|
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_ERASE_CHIP) != 0 )
|
|
{
|
|
flash_program_log( "Erasing entire chip" );
|
|
|
|
/* Erase the serial flash chip */
|
|
/*delete for test*/
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_VERIFY_CHIP_ERASURE) != 0 )
|
|
{
|
|
flash_program_log( "Verifying erasure of entire chip" );
|
|
|
|
/* Verify Erasure */
|
|
pos = 0;
|
|
while ( pos < chip_size )
|
|
{
|
|
uint8_t* cmp_ptr;
|
|
uint8_t* end_ptr;
|
|
unsigned int read_size;
|
|
|
|
read_size =
|
|
(chip_size - pos > (unsigned long) sizeof(Rx_Buffer)) ?
|
|
(unsigned int) sizeof(Rx_Buffer) : (unsigned int) (chip_size - pos);
|
|
if ( 0
|
|
!= MicoFlashRead( partition_remapping[data_transfer.partition], &pos, Rx_Buffer, read_size ) )
|
|
{
|
|
/* Verify Error - Chip not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_READ_FAILED;
|
|
flash_program_log( "Read error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
cmp_ptr = Rx_Buffer;
|
|
end_ptr = &Rx_Buffer[read_size];
|
|
while ( (cmp_ptr < end_ptr) && (*cmp_ptr == (uint8_t) 0xff) )
|
|
{
|
|
cmp_ptr++;
|
|
}
|
|
if ( cmp_ptr < end_ptr )
|
|
{
|
|
/* Verify Error - Chip not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_ERASE_FAILED;
|
|
flash_program_log( "Chip was not erased properly - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
pos += read_size;
|
|
(void) platform_watchdog_kick( );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_WRITE) != 0 )
|
|
{
|
|
flash_program_log( "Writing location" );
|
|
|
|
/* Write the WLAN firmware into memory */
|
|
pos = 0;
|
|
while ( pos < data_transfer.size )
|
|
{
|
|
unsigned int write_size =
|
|
(data_transfer.size - pos > (unsigned long) WRITE_CHUNK_SIZE) ?
|
|
(unsigned int) WRITE_CHUNK_SIZE : (unsigned int) (data_transfer.size - pos);
|
|
unsigned long position = 0;
|
|
position = pos + data_transfer.partition_offset;
|
|
if ( 0
|
|
!= MicoFlashWrite( partition_remapping[data_transfer.partition], &position,
|
|
&data_transfer.data[pos], write_size ) )
|
|
{
|
|
/* Verify Error - Chip not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_WRITE_FAILED;
|
|
flash_program_log( "Write error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
pos += write_size;
|
|
(void) platform_watchdog_kick( );
|
|
}
|
|
|
|
}
|
|
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_WRITE_ERASE_IF_NEEDED) != 0 )
|
|
{
|
|
mico_logic_partition_t *partition_info;
|
|
uint32_t compare_start = (uint32_t) data_transfer.partition_offset % SECTOR_SIZE;
|
|
int32_t size_left_to_compare = (int32_t) data_transfer.size;
|
|
unsigned char* cmp_ptr = data_transfer.data;
|
|
pos = (data_transfer.partition_offset / SECTOR_SIZE) * SECTOR_SIZE;
|
|
|
|
|
|
/* Force erase embedded flash once before program */
|
|
partition_info = MicoFlashGetInfo( partition_remapping[data_transfer.partition] );
|
|
if( platform_flash_peripherals[partition_info->partition_owner].flash_type == FLASH_TYPE_EMBEDDED && erase_once )
|
|
{
|
|
flash_program_log( "Partition erase!" );
|
|
MicoFlashErase( partition_remapping[data_transfer.partition], 0x0, partition_info->partition_length);
|
|
erase_once = false;
|
|
}
|
|
|
|
flash_program_log( "Verifying existing data!" );
|
|
/* Read data from SPI FLASH memory */
|
|
while ( size_left_to_compare > 0 )
|
|
{
|
|
uint32_t cmp_len;
|
|
unsigned long position;
|
|
position = pos;
|
|
|
|
if ( 0
|
|
!= MicoFlashRead( partition_remapping[data_transfer.partition], &position, Rx_Buffer,
|
|
(unsigned int) SECTOR_SIZE ) )
|
|
{
|
|
/* Verify Error - Chip not read properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_READ_FAILED;
|
|
flash_program_log( "Read error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
cmp_len = (uint32_t) MIN( (int32_t) ( SECTOR_SIZE - compare_start ), size_left_to_compare );
|
|
#ifndef ALWAYS_ERASE_SECTOR
|
|
if ( 0 != memcmp( &Rx_Buffer[compare_start], cmp_ptr, cmp_len ) )
|
|
#endif /* ALWAYS_ERASE_SECTOR */
|
|
{
|
|
flash_program_log("Need to erase if non 0xFF");
|
|
/* No not erase if already all 0xFF */
|
|
if ( not_erased( &Rx_Buffer[compare_start], cmp_len ) )
|
|
{
|
|
/* Existing data different */
|
|
uint32_t offset;
|
|
flash_program_log( "Erasing sector 0x%lx", pos );
|
|
offset = pos;
|
|
if ( 0 != MicoFlashErase( partition_remapping[data_transfer.partition], offset, SECTOR_SIZE ) )
|
|
{
|
|
/* Sector Erase Error - Chip not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_ERASE_FAILED;
|
|
flash_program_log( "Sector erase error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
}
|
|
#ifdef VERIFY_ERASE_SECTOR
|
|
{
|
|
#ifdef DEBUG
|
|
memset(Rx_Buffer,0xa5,SECTOR_SIZE);
|
|
#endif /* DEBUG */
|
|
if ( 0 != MicoFlashRead( partition_remapping[data_transfer.partition], &position, Rx_Buffer,
|
|
(unsigned int) SECTOR_SIZE ) )
|
|
{
|
|
/* Verify Error - Chip not read properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_READ_FAILED;
|
|
flash_program_log( "Read error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
|
|
if ( not_erased( Rx_Buffer, SECTOR_SIZE ) )
|
|
{
|
|
/* Verify Error - sector not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_ERASE_FAILED;
|
|
flash_program_log( "Sector was not erased properly - abort!" );
|
|
flash_program_log( "First bystes read: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", Rx_Buffer[0], Rx_Buffer[1], Rx_Buffer[2], Rx_Buffer[3],
|
|
Rx_Buffer[4], Rx_Buffer[5], Rx_Buffer[6], Rx_Buffer[7] );
|
|
goto back_to_idle;
|
|
}
|
|
}
|
|
#endif /* ifdef VERIFY_ERASE_SECTOR */
|
|
|
|
flash_program_log( "Writing address 0x%lx", pos );
|
|
memcpy( &Rx_Buffer[compare_start], cmp_ptr, cmp_len );
|
|
unsigned long position;
|
|
position = pos;
|
|
flash_program_log("position is 0x%lx",position);
|
|
if ( 0
|
|
!= MicoFlashWrite( partition_remapping[data_transfer.partition], &position, Rx_Buffer,
|
|
(unsigned int) SECTOR_SIZE ) )
|
|
{
|
|
/* Write Error - Chip not written properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_WRITE_FAILED;
|
|
flash_program_log( "Write error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
flash_program_log("Write success");
|
|
}
|
|
cmp_ptr += cmp_len;
|
|
size_left_to_compare -= cmp_len;
|
|
compare_start = 0;
|
|
|
|
pos += SECTOR_SIZE;
|
|
(void) platform_watchdog_kick( );
|
|
}
|
|
}
|
|
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_POST_WRITE_VERIFY) != 0 )
|
|
{
|
|
flash_program_log( "Verifying after write" );
|
|
|
|
/* Read data from SPI FLASH memory */
|
|
pos = 0;
|
|
while ( pos < data_transfer.size )
|
|
{
|
|
unsigned int read_size =
|
|
(data_transfer.size - pos > (unsigned long) sizeof(Rx_Buffer)) ?
|
|
(unsigned int) sizeof(Rx_Buffer) : data_transfer.size - pos;
|
|
unsigned long position;
|
|
position = pos + data_transfer.partition_offset;
|
|
if ( 0
|
|
!= MicoFlashRead( partition_remapping[data_transfer.partition], &position, Rx_Buffer,
|
|
read_size ) )
|
|
{
|
|
/* Verify Error - Chip not erased properly */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_READ_FAILED;
|
|
flash_program_log( "Read error - abort!" );
|
|
goto back_to_idle;
|
|
}
|
|
#ifdef DEBUG_PRINT_VERIFY_READ_CONTENT
|
|
{
|
|
int i;
|
|
for( i = 0;i < read_size; i++ )
|
|
{
|
|
DEBUG_PRINTF(( "%02X %02X ", Rx_Buffer[i], data_transfer.data[i]));
|
|
if( ( i & 0xf ) == 0xf )
|
|
{
|
|
DEBUG_PRINTF( ( "\r\n") );
|
|
}
|
|
}
|
|
}
|
|
#endif /* DEBUG_PRINT_VERIFY_READ_CONTENT */
|
|
if ( 0 != memcmp( Rx_Buffer, &data_transfer.data[pos], (size_t) read_size ) )
|
|
{
|
|
/* Verify Error - Read data different to written data */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_VERIFY_AFTER_WRITE_FAILED;
|
|
flash_program_log( "Verify error - Data was not written successfully - abort!Pos=%lx", pos );
|
|
goto back_to_idle;
|
|
}
|
|
pos += read_size;
|
|
(void) platform_watchdog_kick( );
|
|
}
|
|
}
|
|
if ( (data_transfer.command & MFG_SPI_FLASH_COMMAND_WRITE_DONE) != 0 )
|
|
{
|
|
erase_once = true;
|
|
flash_program_log( " Write operation finished at partition %d", APPLICATION_FIRMWARE_PARTITION_TCL );
|
|
}
|
|
/* OK! */
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_OK;
|
|
|
|
back_to_idle:
|
|
data_transfer.command = MFG_SPI_FLASH_COMMAND_NONE;
|
|
data_transfer.partition_offset = 0;
|
|
data_transfer.size = 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(__ICCARM__)
|
|
#pragma section="CSTACK"
|
|
__root void _mico_iar_program_start(void)
|
|
{
|
|
/* When the execution of the program is initiated from an external debugger */
|
|
/* it will perform a reset of the CPU followed by halt and set a program counter to program entry function __iar_program_start leaving */
|
|
/* SP unchanged */
|
|
|
|
/* Consequently, the SP value will be set to the value which was read from address 0x00000000(applicable for CM3) */
|
|
/* For apps which have an interrupt vector table placed at the start of the flash, the value of the SP will */
|
|
/* contain correct value, however for apps which have interrupt vectors shifted to a different memory location, */
|
|
/* the SP will contain garbage. On entry we must call this function which will set the SP to point to the end */
|
|
/* of the CSTACK section */
|
|
iar_set_msp(__section_end("CSTACK"));
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef WIPE_SFLASH
|
|
|
|
static void add_wipe_data( void )
|
|
{
|
|
data_transfer.command = MFG_SPI_FLASH_COMMAND_ERASE_CHIP;
|
|
data_transfer.sflash_address = 0;
|
|
data_transfer.size = 0;
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_IN_PROGRESS;
|
|
}
|
|
|
|
#elif defined( TEST_SFLASH_WRITE )
|
|
|
|
static void add_test_data( void )
|
|
{
|
|
const char test_data[] = /* 0 */
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
/* 1024 */
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
/* 2048 */
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
/* 3072 */
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
/* 4096 */
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
"0123456789abcdef0123456789abcdef012";
|
|
/* 4643 */
|
|
|
|
data_transfer.command = MFG_SPI_FLASH_COMMAND_WRITE_ERASE_IF_NEEDED | MFG_SPI_FLASH_COMMAND_POST_WRITE_VERIFY;
|
|
// data_transfer.command |= MFG_SPI_FLASH_COMMAND_ERASE_CHIP;
|
|
data_transfer.partition = APPLICATION_FIRMWARE_PARTITION_TCL;
|
|
data_transfer.partition_offset = 0x00;
|
|
data_transfer.size = sizeof(test_data)-1;
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_IN_PROGRESS;
|
|
memcpy( data_transfer.data, test_data, sizeof(test_data)-1);
|
|
}
|
|
|
|
#elif defined( TEST_SFLASH_READ )
|
|
|
|
static void read_test_data2( void )
|
|
{
|
|
data_transfer.command = MFG_SPI_FLASH_COMMAND_READ;
|
|
data_transfer.partition = APPLICATION_FIRMWARE_PARTITION_TCL;
|
|
data_transfer.partition_offset = 0x00;
|
|
data_transfer.size = 0x1000;
|
|
data_transfer.result = MFG_SPI_FLASH_RESULT_IN_PROGRESS;
|
|
}
|
|
|
|
#endif /* ifdef TEST_SFLASH_READ */
|
|
|