@ -22,7 +22,8 @@
# include "nanovna.h"
# include <string.h>
int16_t lastsaveid = 0 ;
uint16_t lastsaveid = 0 ;
static uint32_t checksum_ok = 0 ;
static int flash_wait_for_last_operation ( void )
{
@ -42,80 +43,71 @@ static void flash_erase_page0(uint32_t page_address)
FLASH - > CR & = ~ FLASH_CR_PER ;
}
int flash_erase_page ( uint32_t page_address )
static void flash_erase_page ( uint32_t page_address )
{
chSysLock ( ) ;
flash_erase_page0 ( page_address ) ;
chSysUnlock ( ) ;
return 0 ;
}
void flash_program_half_word ( uint32_t address , uint16_t data )
{
flash_wait_for_last_operation ( ) ;
FLASH - > CR | = FLASH_CR_PG ;
* ( __IO uint16_t * ) address = data ;
flash_wait_for_last_operation ( ) ;
FLASH - > CR & = ~ FLASH_CR_PG ;
}
void flash_unlock ( void )
static inline void flash_unlock ( void )
{
// unlock sequence
FLASH - > KEYR = 0x45670123 ;
FLASH - > KEYR = 0xCDEF89AB ;
}
static void flash_program_half_word_buffer ( uint16_t * dst , uint16_t * data , uint16_t size )
{
uint32_t i ;
flash_unlock ( ) ;
// erase flash pages for buffer (aligned to FLASH_PAGESIZE)
for ( i = 0 ; i < size ; i + = FLASH_PAGESIZE )
flash_erase_page ( ( uint32_t ) dst + i ) ;
// Save buffer
__IO uint16_t * p = dst ;
for ( i = 0 ; i < size / sizeof ( uint16_t ) ; i + + ) {
flash_wait_for_last_operation ( ) ;
FLASH - > CR | = FLASH_CR_PG ;
p [ i ] = data [ i ] ;
flash_wait_for_last_operation ( ) ;
FLASH - > CR & = ~ FLASH_CR_PG ;
}
}
static uint32_t
checksum ( const void * start , size_t len )
{
uint32_t * p = ( uint32_t * ) start ;
uint32_t * tail = ( uint32_t * ) ( start + len ) ;
uint32_t value = 0 ;
while ( p < tail )
// align by sizeof(uint32_t)
len = ( len + sizeof ( uint32_t ) - 1 ) / sizeof ( uint32_t ) ;
while ( len - - > 0 )
value = __ROR ( value , 31 ) + * p + + ;
return value ;
}
const uint32_t save_config_area = SAVE_CONFIG_ADDR ;
int
config_save ( void )
{
uint16_t * src = ( uint16_t * ) & config ;
uint16_t * dst = ( uint16_t * ) save_config_area ;
int count = sizeof ( config_t ) / sizeof ( uint16_t ) ;
// Apply magic word and calculate checksum
config . magic = CONFIG_MAGIC ;
config . checksum = checksum ( & config , sizeof config - sizeof config . checksum ) ;
flash_unlock ( ) ;
/* erase flash pages */
flash_erase_page ( ( uint32_t ) dst ) ;
/* write to flahs */
while ( count - - > 0 ) {
flash_program_half_word ( ( uint32_t ) dst , * src + + ) ;
dst + + ;
}
// write to flash
flash_program_half_word_buffer ( ( uint16_t * ) SAVE_CONFIG_ADDR , ( uint16_t * ) & config , sizeof ( config_t ) ) ;
return 0 ;
}
int
config_recall ( void )
{
const config_t * src = ( const config_t * ) save_config_area ;
void * dst = & config ;
const config_t * src = ( const config_t * ) SAVE_CONFIG_ADDR ;
if ( src - > magic ! = CONFIG_MAGIC )
if ( src - > magic ! = CONFIG_MAGIC | | checksum ( src , sizeof * src - sizeof src - > checksum ) ! = src - > checksum )
return - 1 ;
if ( checksum ( src , sizeof * src - sizeof src - > checksum ) ! = src - > checksum )
return - 1 ;
/* duplicated saved data onto sram to be able to modify marker/trace */
memcpy ( dst , src , sizeof ( config_t ) ) ;
// duplicated saved data onto sram to be able to modify marker/trace
memcpy ( & config , src , sizeof ( config_t ) ) ;
return 0 ;
}
@ -124,33 +116,16 @@ caldata_save(uint32_t id)
{
if ( id > = SAVEAREA_MAX )
return - 1 ;
uint16_t * src = ( uint16_t * ) & current_props ;
uint16_t * dst ;
int count = sizeof ( properties_t ) / sizeof ( uint16_t ) ;
dst = ( uint16_t * ) ( SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE ) ;
// Apply magic word and calculate checksum
current_props . magic = CONFIG_MAGIC ;
current_props . checksum = checksum (
& current_props , sizeof current_props - sizeof current_props . checksum ) ;
flash_unlock ( ) ;
/* erase flash pages */
void * p = dst ;
void * tail = p + sizeof ( properties_t ) ;
while ( p < tail ) {
flash_erase_page ( ( uint32_t ) p ) ;
p + = FLASH_PAGESIZE ;
}
current_props . checksum = checksum ( & current_props , sizeof current_props - sizeof current_props . checksum ) ;
/* write to flahs */
while ( count - - > 0 ) {
flash_program_half_word ( ( uint32_t ) dst , * src + + ) ;
dst + + ;
}
// write to flash
uint16_t * dst = ( uint16_t * ) ( SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE ) ;
flash_program_half_word_buffer ( dst , ( uint16_t * ) & current_props , sizeof ( properties_t ) ) ;
/* after saving data, make active configuration points to flash */
// after saving data, make active configuration points to flash
active_props = ( properties_t * ) ( SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE ) ;
lastsaveid = id ;
@ -162,56 +137,50 @@ caldata_recall(uint32_t id)
{
if ( id > = SAVEAREA_MAX )
return - 1 ;
properties_t * src ;
void * dst = & current_props ;
// point to saved area on the flash memory
src = ( properties_t * ) ( SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE ) ;
properties_t * src = ( properties_t * ) ( SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE ) ;
if ( src - > magic ! = CONFIG_MAGIC )
goto load_default ;
if ( checksum ( src , sizeof * src - sizeof src - > checksum ) ! = src - > checksum )
if ( src - > magic ! = CONFIG_MAGIC | | checksum ( src , sizeof * src - sizeof src - > checksum ) ! = src - > checksum )
goto load_default ;
/* active configuration points to save data on flash memory */
// active configuration points to save data on flash memory
active_props = src ;
lastsaveid = id ;
/* duplicated saved data onto sram to be able to modify marker/trace */
memcpy ( dst , src , sizeof ( properties_t ) ) ;
// duplicated saved data onto sram to be able to modify marker/trace
memcpy ( & current_props , src , sizeof ( properties_t ) ) ;
return 0 ;
load_default :
load_default_properties ( ) ;
return - 1 ;
return lastsaveid ;
}
// Used in interpolate
const properties_t *
caldata_ref ( uint32_t id)
caldata_ref erence( vo id)
{
if ( id > = SAVEAREA_MAX )
if ( lastsave id > = SAVEAREA_MAX )
return NULL ;
const properties_t * src ;
src = ( const properties_t * ) ( SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE ) ;
if ( src- > magic ! = CONFIG_MAGIC )
return NULL ;
if ( checksum ( src , sizeof * src - sizeof src - > checksum ) ! = src - > checksum )
src = ( const properties_t * ) ( SAVE_PROP_CONFIG_ADDR + lastsave id * SAVE_PROP_CONFIG_SIZE ) ;
// Check crc cache mask (made it only 1 time)
if ( checksum_ok& ( 1 < < lastsaveid ) )
return src ;
if ( src - > magic ! = CONFIG_MAGIC | | checksum ( src , sizeof * src - sizeof src - > checksum ) ! = src - > checksum )
return NULL ;
checksum_ok | = 1 < < lastsaveid ;
return src ;
}
void
clear_all_config_prop_data ( void )
{
uint32_t i ;
flash_unlock ( ) ;
/* erase flash pages */
void * p = ( void * ) save_config_area ;
void * tail = p + SAVE_FULL_AREA_SIZE ;
while ( p < tail ) {
flash_erase_page ( ( uint32_t ) p ) ;
p + = FLASH_PAGESIZE ;
}
// erase flash pages
for ( i = 0 ; i < SAVE_FULL_AREA_SIZE ; i + = FLASH_PAGESIZE )
flash_erase_page ( SAVE_CONFIG_ADDR + i ) ;
}