/*******************************************************************************
 *
 * This is a template for early application low-level initialization.
 *
 * Copyright 1996-2010 IAR Systems AB.
 *
 * $Revision: 5993 $
 *
 ******************************************************************************/

/*
 * The function __low_level_init it called by the start-up code before
 * "main" is called, and before data segment initialization is
 * performed.
 *
 * This is a template file, modify to perform any initialization that
 * should take place early.
 *
 * The return value of this function controls if data segment
 * initialization should take place. If 0 is returned, it is bypassed.
 *
 * For the MSP430 microcontroller family, please consider disabling
 * the watchdog timer here, as it could time-out during the data
 * segment initialization.
 */

#include <intrinsics.h>
#include "msp430i2041.h"
/* Define if external resistor is used */
#define DCO_EXTERNAL_RESISTOR_MODE  (1)

int __low_level_init(void)
//int main(void)
{
    unsigned long * jtagPwd = (unsigned long *) JTAG_DIS_PWD1;

    /* Stop watchdog timer */
    WDTCTL = WDTPW + WDTHOLD;
    if ((*jtagPwd != 0x00000000) && (*jtagPwd != 0xFFFFFFFF))
    {
        /* Disable JTAG */
//        SYSJTAGDIS = JTAGDISKEY;
    }
    /* Else the JTAG will be enabled in the 64th cycle after reset. */

    /* Calibration section
     * Check for the BORIFG flag in IFG1. Execute calibration if this was a BORIFG.
     * Else skip calibration
     */
    if(IFG1 & BORIFG)
    {
        /* Perform 2's complement checksum on 62 bytes of TLV data */
        unsigned int checksum = 0;
        unsigned char * TLV_address_for_parse = ((unsigned char *) TLV_START);
        unsigned int * TLV_address_for_checksum = ((unsigned int *) TLV_START + 1);

        do
        {
            checksum ^= *TLV_address_for_checksum++;
        } while (TLV_address_for_checksum <= (unsigned int *) TLV_END);

        checksum ^= 0xFFFF;
        checksum++;

        /* If check sum is not correct go to LPM4 */
        if (*((unsigned int *) TLV_START) != checksum)
        {
            /* Enter LPM4 if checksum failed */
            __bis_SR_register(LPM4_bits);
        }

        /* Check sum matched, now set calibration values */

        /* Re-initialize the TLV address pointer again */

        /* Calibrate REF */
        REFCAL1 = *(TLV_address_for_parse + TLV_CAL_REFCAL1);
        REFCAL0 = *(TLV_address_for_parse + TLV_CAL_REFCAL0);

        /* Calibrate DCO */
        CSIRFCAL = *(TLV_address_for_parse + TLV_CAL_CSIRFCAL);
        CSIRTCAL = *(TLV_address_for_parse + TLV_CAL_CSIRTCAL);
#if DCO_EXTERNAL_RESISTOR_MODE
        CSERFCAL = *(TLV_address_for_parse + TLV_CAL_CSERFCAL);
        CSERTCAL = *(TLV_address_for_parse + TLV_CAL_CSERTCAL);
#endif

      /* Calibrate SD24 */
        SD24TRIM = *(TLV_address_for_parse + TLV_CAL_SD24TRIM);

        /* Clear BORIFG */
        IFG1 &= ~(BORIFG);
    }

    /* Restart watchdog timer */
    WDTCTL = WDTPW + WDTCNTCL;

    /*
     * Return value:
     *
     *  1 - Perform data segment initialization.
     *  0 - Skip data segment initialization.
     */

    return 1;
}

