/**
 * \file    sys_config.c
 * \brief   System configuration
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-17
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-17  Original Creation
 * 
 */

#include "libc.h"
#include "drivers.h"
#include "sys_config.h"

/* Global variables */
u8_t g_sys_cfg_map[SYS_CONFIG_TOTAL_SIZE];

volatile SYS_CONFIG_t *gp_sys_cfg = (volatile SYS_CONFIG_t *)&g_sys_cfg_map[0];

sys_cfg_onchange_hook_declarer(dbg);
v_func_v_ptr_t gp_sys_cfg_onsaving_hook;

/**
 * System configuration initialization
 *
 * \see
 */
void sys_cfg_init(void)
{
    memset(&g_sys_cfg_map[0], 0, SYS_CONFIG_TOTAL_SIZE);

    gp_sys_cfg->sync[0] = SYNC_SYMBOL_0;
    gp_sys_cfg->sync[1] = SYNC_SYMBOL_1;
    gp_sys_cfg->sync[2] = SYNC_SYMBOL_2;
    gp_sys_cfg->sync[3] = SYNC_SYMBOL_3;

    //Init system configuration
    gp_sys_cfg->debug = SYS_DEBUG_LEVEL_1;
    gp_sys_cfg->idle_hold_time = SYS_CONFIG_IDLE_HOLD_TIME;
}

/**
 * Load system configuration from flash
 *
 * \see
 */
void sys_cfg_load(void)
{
#if FLASH_ENABLED
    u8_t sync[SYNC_SYMBOL_LEN];

    drv_flash_nvr_en(TRUE);
    drv_flash_read(CFG_ADDR, sync, SYNC_SYMBOL_LEN);

    if ((SYNC_SYMBOL_0 == sync[0]) &&
        (SYNC_SYMBOL_1 == sync[1]) &&
        (SYNC_SYMBOL_2 == sync[2]) &&
        (SYNC_SYMBOL_3 == sync[3]))
    {
        drv_flash_read(CFG_ADDR, &g_sys_cfg_map[0], SYS_CONFIG_TOTAL_SIZE);
        gp_sys_cfg->flash_loaded = TRUE;
    }
    else {
        sys_cfg_init();
    }
    drv_flash_nvr_en(FALSE);
#else
    sys_cfg_init();
#endif
}

/**
 * Save system configuration to flash
 *
 * \see
 */
void sys_cfg_save(void)
{
#if FLASH_ENABLED
    drv_flash_nvr_en(TRUE);
    sys_cfg_onsaving_hook();
    drv_flash_write(CFG_ADDR, &g_sys_cfg_map[0], SYS_CONFIG_TOTAL_SIZE);
    drv_flash_nvr_en(FALSE);
#endif
}

/**
 * Erase system configuration from flash
 *
 * \see
 */
void sys_cfg_erase(void)
{
#if FLASH_ENABLED
    drv_flash_nvr_en(TRUE);
    drv_flash_sector_erase(CFG_ADDR);
    drv_flash_nvr_en(FALSE);
#endif
}

void sys_cfg_sys_name_set(const char *p_val, int len)
{
    if (len < SYS_CONFIG_NAME_SIZE)
    {
        memcpy2((void *)(gp_sys_cfg->sys_name), p_val, len);
        gp_sys_cfg->sys_name[len] = 0;
    }
    else
    {
        memcpy2((void *)(gp_sys_cfg->sys_name), p_val, SYS_CONFIG_NAME_SIZE);
        gp_sys_cfg->sys_name[SYS_CONFIG_NAME_SIZE] = 0;
    }
}


