/****************************************************************************/
/* Copyright 2009-2013 MBARI.                                               */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Written by Mike Risi for Respirometer project in 2009                    */
/* Modified by Bob Herlien for SensorNode for xFOCE, May 2013               */
/****************************************************************************/
#include "config.h"
#include "flash_mem.h"
#include <string.h>

typedef struct
{
    ConfigData config;
    unsigned int checksum;
} ConfigBlock;

unsigned int calcCheckSum(char* buff, int size);

/****************************************************************************/
/*                             Config functions                             */
/****************************************************************************/
int cfgCheck(ConfigData* config)
{
    /* check the id */
    if ( (config->id < 1) || (config->id > 32) )
         return -1;

    /* check the baud */
    switch ( config->baud )
    {
        case 9600: break;
        case 19200: break;
        case 38400: break;
        case 57600: break;
        case 115200: break;
        default: return -1;
    }

    return 0;
}

int cfgRead(ConfigData* config)
{
    ConfigBlock cb;
    unsigned int cs_calc;

    /* read the configuation struct from memory */
    memRead((char*)&cb, sizeof(cb));

    cs_calc = calcCheckSum((char*)&cb.config, sizeof(ConfigData));

    if ( cs_calc != cb.checksum )
        return -1;
    
    /* assign stored data to the config data struct */
    memcpy(config, &cb, sizeof(ConfigData));

    return cfgCheck(config);
}

int cfgWrite(ConfigData* config)
{
    ConfigBlock cb;
    
    /* if config params are not in a valid range, don't write it */
    if ( cfgCheck(config) != 0 )
        return -1;
    
    /* assign stored data to the config data struct */
    memcpy(&cb, config, sizeof(ConfigData));

    /* calc and assign the checksum */
    cb.checksum = calcCheckSum((char*)&cb.config, sizeof(ConfigData));

    /* erase the old config */
    memErase();

    /* write the new config */
    memWrite((char*)&cb, sizeof(cb));
    
    return 0;
}

int cfgSetBootFlag()
{
    ConfigBlock cb;

    memset(&cb, 0, sizeof(ConfigBlock));
    /* set the boot flag */
    cb.config.id = BOOTLOADER_FLAG;

    /* calc and assign the checksum */
    cb.checksum = calcCheckSum((char*)&cb.config, sizeof(ConfigData));

    /* erase the old config */
    memErase();

    /* write the new config */
    memWrite((char*)&cb, sizeof(cb));
    
    return 0;
}


unsigned int calcCheckSum(char* buff, int size)
{
    int i;
    unsigned int cs = 0;

    for (i = 0; i < size; i++)
        cs += buff[i];

    return cs;
}

