SX126xDevKit

Dependencies:   mbed DmTftLibrary SX126xLib

Peripherals/Eeprom.cpp

Committer:
GregCr
Date:
2017-09-05
Revision:
0:e5420f1a8a1a
Child:
1:b96176a4ccb8

File content as of revision 0:e5420f1a8a1a:

/*
  ______                              _
 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    (C)2016 Semtech

Description: EEPROM routines

Maintainer: Gregory Cristian & Gilbert Menth
*/

#include "mbed.h"
#include "string.h"
#include "Eeprom.h"
#include "Menu.h"
#include "DemoApplication.h"
#include "sx126x.h"
#if defined( TARGET_NUCLEO_L476RG )
#include "stm32l4xx_hal_flash.h"
#elif defined( TARGET_NUCLEO_L152RE )
#include "stm32l1xx_hal_flash.h"
#else
#error "Please define include file"
#endif



#include "DisplayDriver.h"


/*!
 * \brief Define address of Emulated EEPROM (in fact region of Flash)
 */
#if defined( TARGET_NUCLEO_L476RG )
#define DATA_EEPROM_BASE    ( ( uint32_t )0x0807F800U )
#define DATA_EEPROM_END     ( ( uint32_t )DATA_EEPROM_BASE + 2048 )
#elif defined( TARGET_NUCLEO_L152RE )
#define DATA_EEPROM_BASE    ( ( uint32_t )0x08080000U ) 
#define DATA_EEPROM_END     ( ( uint32_t )0x080807FFU )
#else
#error "Please define EEPROM base address and size for your board "
#endif


/*!
 * \brief CRC of EEPROM buffer and its valid status
 */
typedef struct
{
    uint16_t Value;
    bool Valid;
}MemTestStruct_t;

/*!
 * \brief Local copy of Eeprom.
 */
Eeprom_t Eeprom;


// Check CRC of local copy of Eeprom (Buffer). This update Valid & Value
static MemTestStruct_t EepromDataCheckSum( void );
uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size );

void EepromInit( uint8_t deviceConnected )
{
    MemTestStruct_t memTestStruct;

    if( deviceConnected == 0xFF )
    {
        EepromSetDefaultSettings( deviceConnected );
    }

    EepromMcuReadBuffer( 0, Eeprom.Buffer, EEPROM_BUFFER_SIZE );
    EepromLoadGeneralSettings( );

    memTestStruct = EepromDataCheckSum( );
    if( !( memTestStruct.Valid ) || ( Eeprom.EepromData.DemoSettings.LastDeviceConnected != deviceConnected ) )
    {
#ifdef ADV_DEBUG
        printf("EepromDataCheckSum failed\n\r");
#endif
        EepromSetDefaultSettings( deviceConnected );
    }
    EepromLoadSettings( ( RadioPacketTypes_t ) Eeprom.EepromData.DemoSettings.ModulationType );
}

void EepromSaveSettings( EepromDataSet_t dataSet)
{
    MemTestStruct_t memTestStruct;

    switch( dataSet )
    {
        case RADIO_LORA_PARAMS:
            Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) Eeprom.EepromData.DemoSettings.ModulationParam1;
            Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth       = ( RadioLoRaBandwidths_t )       Eeprom.EepromData.DemoSettings.ModulationParam2;
            Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate      = ( RadioLoRaCodingRates_t )      Eeprom.EepromData.DemoSettings.ModulationParam3;

            Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength      =                                 Eeprom.EepromData.DemoSettings.PacketParam1;
            Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType          = ( RadioLoRaPacketLengthsMode_t )Eeprom.EepromData.DemoSettings.PacketParam2;
            Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength       =                                 Eeprom.EepromData.DemoSettings.PacketParam3;
            Eeprom.EepromData.PacketParams.Params.LoRa.CrcMode             = ( RadioLoRaCrcModes_t )         Eeprom.EepromData.DemoSettings.PacketParam4;
            Eeprom.EepromData.PacketParams.Params.LoRa.InvertIQ            = ( RadioLoRaIQModes_t )          Eeprom.EepromData.DemoSettings.PacketParam5;

            memcpy( Eeprom.Buffer + MOD_LORA_SPREADF_EEPROM_ADDR,      &( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor ), 1 );
            memcpy( Eeprom.Buffer + MOD_LORA_BW_EEPROM_ADDR,           &( Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth ),       1 );
            memcpy( Eeprom.Buffer + MOD_LORA_CODERATE_EEPROM_ADDR,     &( Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate ),      1 );
            memcpy( Eeprom.Buffer + PAK_LORA_PREAMBLE_LEN_EEPROM_ADDR, &( Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength ),      1 );
            memcpy( Eeprom.Buffer + PAK_LORA_HEADERTYPE_EEPROM_ADDR,   &( Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType ),          1 );
            memcpy( Eeprom.Buffer + PAK_LORA_PL_LEN_EEPROM_ADDR,       &( Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength ),       1 );
            memcpy( Eeprom.Buffer + PAK_LORA_CRC_MODE_EEPROM_ADDR,     &( Eeprom.EepromData.PacketParams.Params.LoRa.CrcMode ),             1 );
            memcpy( Eeprom.Buffer + PAK_LORA_IQ_INV_EEPROM_ADDR,       &( Eeprom.EepromData.PacketParams.Params.LoRa.InvertIQ ),            1 );
#ifdef ADV_DEBUG
            printf("Saved RADIO_LoRa_PARAMS\n\r");
#endif
            break;

        case RADIO_GFSK_PARAMS:
            Eeprom.EepromData.ModulationParams.Params.Gfsk.BitRate           =                             Eeprom.EepromData.DemoSettings.ModulationParam1;
            Eeprom.EepromData.ModulationParams.Params.Gfsk.Fdev              =                             Eeprom.EepromData.DemoSettings.ModulationParam2;
            Eeprom.EepromData.ModulationParams.Params.Gfsk.ModulationShaping = ( RadioModShapings_t )      Eeprom.EepromData.DemoSettings.ModulationParam3;
            Eeprom.EepromData.ModulationParams.Params.Gfsk.Bandwidth         = ( RadioRxBandwidth_t )      Eeprom.EepromData.DemoSettings.ModulationParam4;
            Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength        =                             Eeprom.EepromData.DemoSettings.PacketParam1;
            Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleMinDetect     = ( RadioPreambleDetection_t )Eeprom.EepromData.DemoSettings.PacketParam2;
            Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength        =                             Eeprom.EepromData.DemoSettings.PacketParam3;
            Eeprom.EepromData.PacketParams.Params.Gfsk.AddrComp              = ( RadioAddressComp_t )      Eeprom.EepromData.DemoSettings.PacketParam4;
            Eeprom.EepromData.PacketParams.Params.Gfsk.HeaderType            = ( RadioPacketLengthModes_t )Eeprom.EepromData.DemoSettings.PacketParam5;
            Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength         =                             Eeprom.EepromData.DemoSettings.PacketParam6;

            Eeprom.EepromData.PacketParams.Params.Gfsk.CrcLength             = ( RadioCrcTypes_t )         Eeprom.EepromData.DemoSettings.PacketParam7;
            Eeprom.EepromData.PacketParams.Params.Gfsk.DcFree                = ( RadioDcFree_t )           Eeprom.EepromData.DemoSettings.PacketParam8;

            memcpy( Eeprom.Buffer + MOD_GFSK_BR_EEPROM_ADDR,           &( Eeprom.EepromData.ModulationParams.Params.Gfsk.BitRate ),           4 );
            memcpy( Eeprom.Buffer + MOD_GFSK_FDEV_EEPROM_ADDR,         &( Eeprom.EepromData.ModulationParams.Params.Gfsk.Fdev ),              4 );
            memcpy( Eeprom.Buffer + MOD_GFSK_MOD_SHAPE_EEPROM_ADDR,    &( Eeprom.EepromData.ModulationParams.Params.Gfsk.ModulationShaping ), 1 );
            memcpy( Eeprom.Buffer + MOD_GFSK_BW_EEPROM_ADDR,           &( Eeprom.EepromData.ModulationParams.Params.Gfsk.Bandwidth ),         1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_PREAMBLE_LEN_EEPROM_ADDR, &( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength ),        1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_PR_MIN_DET_EEPROM_ADDR,   &( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleMinDetect ),     1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_SYNC_LEN_EEPROM_ADDR,     &( Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength ),        1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_HEADERTYPE_EEPROM_ADDR,   &( Eeprom.EepromData.PacketParams.Params.Gfsk.HeaderType ),            1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_PL_LEN_EEPROM_ADDR,       &( Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength ),         1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_ADDR_COMP_EEPROM_ADDR,    &( Eeprom.EepromData.PacketParams.Params.Gfsk.AddrComp ),              1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_CRC_LEN_EEPROM_ADDR,      &( Eeprom.EepromData.PacketParams.Params.Gfsk.CrcLength ),             1 );
            memcpy( Eeprom.Buffer + PAK_GFSK_DC_FREE_EEPROM_ADDR,      &( Eeprom.EepromData.PacketParams.Params.Gfsk.DcFree ),                1 );
            
#ifdef ADV_DEBUG
            printf("Saved RADIO_GFSK_PARAMS\n\r");
#endif
            break;

        case DEMO_SETTINGS:
            memcpy( Eeprom.Buffer + APP_ENTITY_EEPROM_ADDR,           &( Eeprom.EepromData.DemoSettings.Entity ),           1 );
            memcpy( Eeprom.Buffer + APP_RADIO_BOOSTED_RX_EEPROM_ADDR, &( Eeprom.EepromData.DemoSettings.BoostedRx ),        1 );
            memcpy( Eeprom.Buffer + APP_FREQ_EEPROM_ADDR,             &( Eeprom.EepromData.DemoSettings.Frequency ),        4 );
            memcpy( Eeprom.Buffer + APP_TXPWR_EEPROM_ADDR,            &( Eeprom.EepromData.DemoSettings.TxPower ),          1 );
            memcpy( Eeprom.Buffer + APP_MOD_TYPE_EEPROM_ADDR,         &( Eeprom.EepromData.DemoSettings.ModulationType ),   1 );
            memcpy( Eeprom.Buffer + APP_PER_NPAK_MAX_EEPROM_ADDR,     &( Eeprom.EepromData.DemoSettings.MaxNumPacket ),     4 );
            memcpy( Eeprom.Buffer + APP_RADIO_POWER_MODE_EEPROM_ADDR, &( Eeprom.EepromData.DemoSettings.RadioPowerMode ),   1 );
            memcpy( Eeprom.Buffer + MOD_PKET_TYPE_EEPROM_ADDR,        &( Eeprom.EepromData.DemoSettings.ModulationType ),  1 );
            memcpy( Eeprom.Buffer + PAK_PKET_TYPE_EEPROM_ADDR,        &( Eeprom.EepromData.DemoSettings.ModulationType ),  1 );
            memcpy( Eeprom.Buffer + EEPROM_LAST_DEVICE_CONNECTED,     &( Eeprom.EepromData.DemoSettings.LastDeviceConnected ),  1 );

#ifdef ADV_DEBUG
            printf("Saved DEMO_SETTINGS\n\r");
#endif
            break;

        case SCREEN_DATA:
            memcpy( Eeprom.Buffer + SCR_CAL_FLAG_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.ScreenCalibrated ), 1 );
            memcpy( Eeprom.Buffer + SCR_CAL_POSA_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.Calibration.a ),    4 );
            memcpy( Eeprom.Buffer + SCR_CAL_POSB_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.Calibration.b ),    4 );
            memcpy( Eeprom.Buffer + SCR_CAL_POSC_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.Calibration.c ),    4 );
            memcpy( Eeprom.Buffer + SCR_CAL_POSD_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.Calibration.d ),    4 );
            memcpy( Eeprom.Buffer + SCR_CAL_POSE_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.Calibration.e ),    4 );
            memcpy( Eeprom.Buffer + SCR_CAL_POSF_EEPROM_ADDR, &( Eeprom.EepromData.MenuSettings.Calibration.f ),    4 );
            break;

        default:
#ifdef ADV_DEBUG
            printf("data not saved\n\r");
#endif
            break;
    }

    memTestStruct = EepromDataCheckSum( );
    memcpy( Eeprom.Buffer + EEPROM_CRC_EEPROM_ADDR, &( memTestStruct.Value ), 2 );

    EepromMcuWriteBuffer( 0, Eeprom.Buffer, EEPROM_BUFFER_SIZE );
}

void EepromLoadGeneralSettings( void )
{
    printf("Load General Settings\n\r");
    memcpy( &( Eeprom.EepromData.MenuSettings.ScreenCalibrated ), Eeprom.Buffer + SCR_CAL_FLAG_EEPROM_ADDR, 1 );
    memcpy( &( Eeprom.EepromData.MenuSettings.Calibration.a ),    Eeprom.Buffer + SCR_CAL_POSA_EEPROM_ADDR, 4 );
    memcpy( &( Eeprom.EepromData.MenuSettings.Calibration.b ),    Eeprom.Buffer + SCR_CAL_POSB_EEPROM_ADDR, 4 );
    memcpy( &( Eeprom.EepromData.MenuSettings.Calibration.c ),    Eeprom.Buffer + SCR_CAL_POSC_EEPROM_ADDR, 4 );
    memcpy( &( Eeprom.EepromData.MenuSettings.Calibration.d ),    Eeprom.Buffer + SCR_CAL_POSD_EEPROM_ADDR, 4 );
    memcpy( &( Eeprom.EepromData.MenuSettings.Calibration.e ),    Eeprom.Buffer + SCR_CAL_POSE_EEPROM_ADDR, 4 );
    memcpy( &( Eeprom.EepromData.MenuSettings.Calibration.f ),    Eeprom.Buffer + SCR_CAL_POSF_EEPROM_ADDR, 4 );

    memcpy( &( Eeprom.EepromData.DemoSettings.Entity ),         Eeprom.Buffer + APP_ENTITY_EEPROM_ADDR,           1 );
    memcpy( &( Eeprom.EepromData.DemoSettings.BoostedRx ),      Eeprom.Buffer + APP_RADIO_BOOSTED_RX_EEPROM_ADDR, 1 ); 
    memcpy( &( Eeprom.EepromData.DemoSettings.Frequency ),      Eeprom.Buffer + APP_FREQ_EEPROM_ADDR,             4 );
    memcpy( &( Eeprom.EepromData.DemoSettings.RadioPowerMode ), Eeprom.Buffer + APP_RADIO_POWER_MODE_EEPROM_ADDR, 1 );
    memcpy( &( Eeprom.EepromData.DemoSettings.TxPower ),        Eeprom.Buffer + APP_TXPWR_EEPROM_ADDR,            1 );
    memcpy( &( Eeprom.EepromData.DemoSettings.ModulationType ), Eeprom.Buffer + APP_MOD_TYPE_EEPROM_ADDR,         1 );
    memcpy( &( Eeprom.EepromData.DemoSettings.MaxNumPacket ),   Eeprom.Buffer + APP_PER_NPAK_MAX_EEPROM_ADDR,     4 );
    memcpy( &( Eeprom.EepromData.DemoSettings.LastDeviceConnected ), Eeprom.Buffer + EEPROM_LAST_DEVICE_CONNECTED,         1 );

    memcpy( &( Eeprom.EepromData.ModulationParams.PacketType ),                    Eeprom.Buffer + MOD_PKET_TYPE_EEPROM_ADDR,      1 );

    memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.BitRate ),           Eeprom.Buffer + MOD_GFSK_BR_EEPROM_ADDR,        4 );
    memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.Fdev ),              Eeprom.Buffer + MOD_GFSK_FDEV_EEPROM_ADDR,      4 );
    memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.ModulationShaping ), Eeprom.Buffer + MOD_GFSK_MOD_SHAPE_EEPROM_ADDR, 1 );
    memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.Bandwidth ),         Eeprom.Buffer + MOD_GFSK_BW_EEPROM_ADDR,        1 );

    memcpy( &( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor ),   Eeprom.Buffer + MOD_LORA_SPREADF_EEPROM_ADDR,   1 );
    memcpy( &( Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth ),         Eeprom.Buffer + MOD_LORA_BW_EEPROM_ADDR,        1 );
    memcpy( &( Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate ),        Eeprom.Buffer + MOD_LORA_CODERATE_EEPROM_ADDR,  1 );

    memcpy( &( Eeprom.EepromData.PacketParams.PacketType ),                    Eeprom.Buffer + PAK_PKET_TYPE_EEPROM_ADDR,         1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength ),    Eeprom.Buffer + PAK_GFSK_PREAMBLE_LEN_EEPROM_ADDR, 1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleMinDetect ), Eeprom.Buffer + PAK_GFSK_PR_MIN_DET_EEPROM_ADDR,   1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength ),    Eeprom.Buffer + PAK_GFSK_SYNC_LEN_EEPROM_ADDR,     1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.HeaderType ),        Eeprom.Buffer + PAK_GFSK_HEADERTYPE_EEPROM_ADDR,   1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength ),     Eeprom.Buffer + PAK_GFSK_PL_LEN_EEPROM_ADDR,       1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.AddrComp ),          Eeprom.Buffer + PAK_GFSK_ADDR_COMP_EEPROM_ADDR,    1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.CrcLength ),         Eeprom.Buffer + PAK_GFSK_CRC_LEN_EEPROM_ADDR,      1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.DcFree ),            Eeprom.Buffer + PAK_GFSK_DC_FREE_EEPROM_ADDR,      1 );

    memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength ),    Eeprom.Buffer + PAK_LORA_PREAMBLE_LEN_EEPROM_ADDR, 1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType ),        Eeprom.Buffer + PAK_LORA_HEADERTYPE_EEPROM_ADDR,   1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength ),     Eeprom.Buffer + PAK_LORA_PL_LEN_EEPROM_ADDR,       1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.CrcMode ),           Eeprom.Buffer + PAK_LORA_CRC_MODE_EEPROM_ADDR,     1 );
    memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.InvertIQ ),          Eeprom.Buffer + PAK_LORA_IQ_INV_EEPROM_ADDR,       1 );
}

void EepromLoadSettings( RadioPacketTypes_t modulation )
{
    if( modulation == PACKET_TYPE_LORA )
    {
        printf("Load Settings PACKET_TYPE_LORA\n\r");
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor ), Eeprom.Buffer + MOD_LORA_SPREADF_EEPROM_ADDR,      1 );
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth ),       Eeprom.Buffer + MOD_LORA_BW_EEPROM_ADDR,           1 );
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate ),      Eeprom.Buffer + MOD_LORA_CODERATE_EEPROM_ADDR,     1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength ),      Eeprom.Buffer + PAK_LORA_PREAMBLE_LEN_EEPROM_ADDR, 1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType ),          Eeprom.Buffer + PAK_LORA_HEADERTYPE_EEPROM_ADDR,   1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength ),       Eeprom.Buffer + PAK_LORA_PL_LEN_EEPROM_ADDR,       1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.CrcMode ),             Eeprom.Buffer + PAK_LORA_CRC_MODE_EEPROM_ADDR,     1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.LoRa.InvertIQ ),            Eeprom.Buffer + PAK_LORA_IQ_INV_EEPROM_ADDR,       1 );

        Eeprom.EepromData.ModulationParams.PacketType   = PACKET_TYPE_LORA;
        Eeprom.EepromData.PacketParams.PacketType       = PACKET_TYPE_LORA;
        Eeprom.EepromData.DemoSettings.ModulationParam1 = Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor;
        Eeprom.EepromData.DemoSettings.ModulationParam2 = Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth;
        Eeprom.EepromData.DemoSettings.ModulationParam3 = Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate;

        Eeprom.EepromData.DemoSettings.PacketParam1 = Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength;
        Eeprom.EepromData.DemoSettings.PacketParam2 = Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType;
        Eeprom.EepromData.DemoSettings.PacketParam3 = Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength;
        Eeprom.EepromData.DemoSettings.PacketParam4 = Eeprom.EepromData.PacketParams.Params.LoRa.CrcMode;
        Eeprom.EepromData.DemoSettings.PacketParam5 = Eeprom.EepromData.PacketParams.Params.LoRa.InvertIQ;
        Eeprom.EepromData.DemoSettings.PacketParam6 = 0x00;
        Eeprom.EepromData.DemoSettings.PacketParam7 = 0x00;
    }
    else// if( modulation == PACKET_TYPE_GFSK )
    {
        printf("Load Settings PACKET_TYPE_GFSK\n\r");
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.BitRate ),           Eeprom.Buffer + MOD_GFSK_BR_EEPROM_ADDR,           4 );
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.Fdev ),              Eeprom.Buffer + MOD_GFSK_FDEV_EEPROM_ADDR,         4 );
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.ModulationShaping ), Eeprom.Buffer + MOD_GFSK_MOD_SHAPE_EEPROM_ADDR,    1 );
        memcpy( &( Eeprom.EepromData.ModulationParams.Params.Gfsk.Bandwidth ),         Eeprom.Buffer + MOD_GFSK_BW_EEPROM_ADDR,           1 );
        
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength ),        Eeprom.Buffer + PAK_GFSK_PREAMBLE_LEN_EEPROM_ADDR, 1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleMinDetect ),     Eeprom.Buffer + PAK_GFSK_PR_MIN_DET_EEPROM_ADDR,   1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength ),        Eeprom.Buffer + PAK_GFSK_SYNC_LEN_EEPROM_ADDR,     1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.HeaderType ),            Eeprom.Buffer + PAK_GFSK_HEADERTYPE_EEPROM_ADDR,   1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength ),         Eeprom.Buffer + PAK_GFSK_PL_LEN_EEPROM_ADDR,       1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.AddrComp ),              Eeprom.Buffer + PAK_GFSK_ADDR_COMP_EEPROM_ADDR,    1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.CrcLength ),             Eeprom.Buffer + PAK_GFSK_CRC_LEN_EEPROM_ADDR,      1 );
        memcpy( &( Eeprom.EepromData.PacketParams.Params.Gfsk.DcFree ),                Eeprom.Buffer + PAK_GFSK_DC_FREE_EEPROM_ADDR,      1 );

        Eeprom.EepromData.ModulationParams.PacketType   = PACKET_TYPE_GFSK;
        Eeprom.EepromData.PacketParams.PacketType       = PACKET_TYPE_GFSK;
        Eeprom.EepromData.DemoSettings.ModulationParam1 = Eeprom.EepromData.ModulationParams.Params.Gfsk.BitRate;
        Eeprom.EepromData.DemoSettings.ModulationParam2 = Eeprom.EepromData.ModulationParams.Params.Gfsk.Fdev;
        Eeprom.EepromData.DemoSettings.ModulationParam3 = Eeprom.EepromData.ModulationParams.Params.Gfsk.ModulationShaping;
        Eeprom.EepromData.DemoSettings.ModulationParam4 = Eeprom.EepromData.ModulationParams.Params.Gfsk.Bandwidth;

        Eeprom.EepromData.DemoSettings.PacketParam1 = Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength;
        Eeprom.EepromData.DemoSettings.PacketParam2 = Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleMinDetect;
        Eeprom.EepromData.DemoSettings.PacketParam3 = Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength;
        Eeprom.EepromData.DemoSettings.PacketParam4 = Eeprom.EepromData.PacketParams.Params.Gfsk.AddrComp;
        Eeprom.EepromData.DemoSettings.PacketParam5 = Eeprom.EepromData.PacketParams.Params.Gfsk.HeaderType;
        Eeprom.EepromData.DemoSettings.PacketParam6 = Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength;

        Eeprom.EepromData.DemoSettings.PacketParam7 = Eeprom.EepromData.PacketParams.Params.Gfsk.CrcLength;
        Eeprom.EepromData.DemoSettings.PacketParam8 = Eeprom.EepromData.PacketParams.Params.Gfsk.DcFree;
    }

    Eeprom.EepromData.DemoSettings.ModulationType = modulation;
}

void EepromSetDefaultSettings( uint8_t deviceConnected )
{
    Eeprom.EepromData.MenuSettings.ScreenCalibrated = false;

    printf("Set Default Settings\n\r");
    EepromSaveSettings( SCREEN_DATA );

    Eeprom.EepromData.DemoSettings.ModulationType = PACKET_TYPE_LORA;
    Eeprom.EepromData.ModulationParams.PacketType = PACKET_TYPE_LORA;
    Eeprom.EepromData.PacketParams.PacketType     = PACKET_TYPE_LORA;

    Eeprom.EepromData.DemoSettings.ModulationParam1 = LORA_SF7;
    Eeprom.EepromData.DemoSettings.ModulationParam2 = LORA_BW_500;
    Eeprom.EepromData.DemoSettings.ModulationParam3 = LORA_CR_4_5;
    Eeprom.EepromData.DemoSettings.ModulationParam4 = 0x00;

    Eeprom.EepromData.DemoSettings.PacketParam1 = 8;        // PreambleLength
    Eeprom.EepromData.DemoSettings.PacketParam2 = LORA_PACKET_VARIABLE_LENGTH;
    Eeprom.EepromData.DemoSettings.PacketParam3 = 16;       // PayloadLength
    Eeprom.EepromData.DemoSettings.PacketParam4 = LORA_CRC_ON;
    Eeprom.EepromData.DemoSettings.PacketParam5 = LORA_IQ_NORMAL;

    EepromSaveSettings( RADIO_LORA_PARAMS );

    Eeprom.EepromData.DemoSettings.ModulationType = PACKET_TYPE_GFSK;
    Eeprom.EepromData.ModulationParams.PacketType = PACKET_TYPE_GFSK;
    Eeprom.EepromData.PacketParams.PacketType     = PACKET_TYPE_GFSK;

    Eeprom.EepromData.DemoSettings.ModulationParam1 = 19200;
    Eeprom.EepromData.DemoSettings.ModulationParam2 = 5000;
    Eeprom.EepromData.DemoSettings.ModulationParam3 = MOD_SHAPING_G_BT_1;
    Eeprom.EepromData.DemoSettings.ModulationParam4 = RX_BW_39000;

    Eeprom.EepromData.DemoSettings.PacketParam1 = 40;
    Eeprom.EepromData.DemoSettings.PacketParam2 = RADIO_PREAMBLE_DETECTOR_08_BITS;
    Eeprom.EepromData.DemoSettings.PacketParam3 = 4;
    Eeprom.EepromData.DemoSettings.PacketParam4 = RADIO_ADDRESSCOMP_FILT_OFF;
    Eeprom.EepromData.DemoSettings.PacketParam5 = RADIO_PACKET_VARIABLE_LENGTH;
    Eeprom.EepromData.DemoSettings.PacketParam6 = 16;           // PayloadLength
    Eeprom.EepromData.DemoSettings.PacketParam7 = RADIO_CRC_2_BYTES_CCIT;
    Eeprom.EepromData.DemoSettings.PacketParam8 = RADIO_DC_FREE_OFF;

    EepromSaveSettings( RADIO_GFSK_PARAMS );

    Eeprom.EepromData.DemoSettings.Entity         = SLAVE;
    Eeprom.EepromData.DemoSettings.BoostedRx      = 0x00;
    if( deviceConnected == SX1261 )
    {
        Eeprom.EepromData.DemoSettings.LastDeviceConnected = deviceConnected;
        Eeprom.EepromData.DemoSettings.RadioPowerMode = USE_DCDC;
        Eeprom.EepromData.DemoSettings.Frequency      = DEMO_CENTRAL_FREQ_PRESET1;
        Eeprom.EepromData.DemoSettings.TxPower        = SX1261_POWER_TX_MAX;
    }
    else
    {
        Eeprom.EepromData.DemoSettings.LastDeviceConnected = deviceConnected;
        Eeprom.EepromData.DemoSettings.RadioPowerMode = USE_LDO;
        Eeprom.EepromData.DemoSettings.Frequency      = DEMO_CENTRAL_FREQ_PRESET2;
        Eeprom.EepromData.DemoSettings.TxPower        = SX1262_POWER_TX_MAX;
    }
    Eeprom.EepromData.DemoSettings.MaxNumPacket   = 0x00;
    Eeprom.EepromData.DemoSettings.ModulationType = PACKET_TYPE_LORA;

    EepromSaveSettings( DEMO_SETTINGS );
}

/*!
 * \brief Erase a page of Flash. Here used to Erase EEPROM region.
 *
 * \param [in]  page          address of page to erase
 * \param [in]  banks         address of banks to erase
 */
void FlashPageErase( uint32_t page, uint32_t banks )
{
    // Check the parameters
    assert_param( IS_FLASH_PAGE( page ) );
    assert_param( IS_FLASH_BANK_EXCLUSIVE( banks ) );

    if( ( banks & FLASH_BANK_1 ) != RESET )
    {
        CLEAR_BIT( FLASH->CR, FLASH_CR_BKER );
    }
    else
    {
        SET_BIT( FLASH->CR, FLASH_CR_BKER );
    }

    // Proceed to erase the page
    MODIFY_REG( FLASH->CR, FLASH_CR_PNB, ( page << 3 ) );
    SET_BIT( FLASH->CR, FLASH_CR_PER );
    SET_BIT( FLASH->CR, FLASH_CR_STRT );
}

/*!
 * \brief Write Eeprom to emulated EEPROM (in fact in Flash " higher address).
 *
 * \param [in]  addr          address of data (EEPROM offset not to be include)
 * \param [in]  buffer        buffer to use for copy
 * \param [in]  size          size of data to copy
 *
 * \retval      status        Status of operation (SUCCESS, ..)
 */
uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size )
{
    uint64_t *flash = ( uint64_t* )buffer;
    
    // assert_param( addr >= DATA_EEPROM_BASE );
    assert_param( buffer != NULL );
    assert_param( size < ( DATA_EEPROM_END - DATA_EEPROM_BASE ) );

    HAL_FLASH_Unlock( );
    
    FlashPageErase( 255, 1 );
    
    WRITE_REG( FLASH->CR, 0x40000000 );

    for( uint32_t i = 0; i < size; i++ )
    {
        HAL_FLASH_Program( FLASH_TYPEPROGRAM_DOUBLEWORD, DATA_EEPROM_BASE + \
                           ( 8 * i ), flash[i] );
    }

    HAL_FLASH_Lock( );

    return SUCCESS;
}

uint8_t EepromMcuReadBuffer( uint16_t addr, uint8_t *buffer, uint16_t size )
{
    assert_param( buffer != NULL );

    // assert_param( addr >= DATA_EEPROM_BASE );
    assert_param( buffer != NULL );
    assert_param( size < ( DATA_EEPROM_END - DATA_EEPROM_BASE ) );

    memcpy( buffer, ( uint8_t* )DATA_EEPROM_BASE, size );
    return SUCCESS;
}

static MemTestStruct_t EepromDataCheckSum( void )
{
    MemTestStruct_t memTestStruct;
    uint8_t x;
    uint8_t i;
    uint16_t crcBuf;
    memTestStruct.Value = 0xFFFF;

    for( i = 0; i < EEPROM_BUFFER_SIZE - sizeof( uint16_t ); i++ )
    {
        x = memTestStruct.Value >> 8 ^ Eeprom.Buffer[i];
        x ^= x >> 4;
        memTestStruct.Value = ( memTestStruct.Value << 8 ) ^ \
                              ( ( uint16_t )( x << 12 ) ) ^ \
                              ( ( uint16_t )( x << 5 ) ) ^ \
                              ( ( uint16_t )x );
    }
    memcpy( &crcBuf, Eeprom.Buffer + EEPROM_CRC_EEPROM_ADDR, 2 );
    memTestStruct.Valid = ( crcBuf == memTestStruct.Value );

    return memTestStruct;
}