//*****************************************************************************
//
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  Redistributions of source code must retain the above copyright
//  notice, this list of conditions and the following disclaimer.
//
//  Redistributions in binary form must reproduce the above copyright
//  notice, this list of conditions and the following disclaimer in the
//  documentation and/or other materials provided with the
//  distribution.
//
//  Neither the name of Texas Instruments Incorporated nor the names of
//  its contributors may be used to endorse or promote products derived
//  from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// MSP432 main.c
//
//****************************************************************************
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "msp432.h"
#include "driverlib.h"

#include <cpy_tbl.h>

//***** Definitions *****
#define CPU_FREQ                    (48000000)
typedef void ( *function_ptr_t )    ( void );

//***** Function Prototypes *****
void startCrystalOscillator(void);
void setSystemClock(uint32_t CPU_Frequency);
void configureTimerA(void);

//***** Global Data *****
extern void toggle1(void);
extern void toggle2(void);
extern void toggle3(void);

/***********************************************************
  Function:
*/
void main(void)
{
    volatile uint32_t i;

	WDT_A_holdTimer();
	MAP_Interrupt_disableMaster();                // Disabling master interrupts

	// Configure clocks
	startCrystalOscillator();
	setSystemClock(CPU_FREQ);

	// P1.0 as output
	MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);

	// P2.0 as output
	MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0);

	// P2.1 as output
	MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);

    extern COPY_TABLE _task1_copy_table;
    copy_in(&_task1_copy_table);

    while(1)
    {
       toggle1();
       toggle2();
//       toggle3();
    }
}

/***********************************************************
  Function:

   The following function is responsible for starting XT1 in the
   MSP432 that is used to source the internal FLL that drives the
   MCLK and SMCLK.
*/
void startCrystalOscillator(void)
{
	/* Configuring pins for peripheral/crystal HFXT*/
	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
			GPIO_PIN3 | GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);

	/* Configuring pins for peripheral/crystal LFXT*/
	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
			GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION);
}

/***********************************************************
  Function:

   The following function is responsible for setting up the system
   clock at a specified frequency.
*/
void setSystemClock(uint32_t CPU_Frequency)
{
	/* Setting the external clock frequency. This API is optional, but will
	 * come in handy if the user ever wants to use the getMCLK/getACLK/etc
	 * functions
	 */
	MAP_CS_setExternalClockSourceFrequency(32768, CPU_Frequency);

	/* Before we start we have to change VCORE to 1 to support the 48MHz frequency */
	MAP_PCM_setCoreVoltageLevel(PCM_AM_LDO_VCORE1);
	MAP_FlashCtl_setWaitState(FLASH_BANK0, 2);
	MAP_FlashCtl_setWaitState(FLASH_BANK1, 2);

	/* Starting HFXT and LFXT in non-bypass mode without a timeout. */
	MAP_CS_startHFXT(false);
	MAP_CS_startLFXT(false);

	/* Initializing the clock source as follows:
	 *      MCLK = HFXT = 48MHz
	 *      ACLK = LFXT = 32KHz
	 *      HSMCLK = HFXT/4 = 12MHz
	 *      SMCLK = HFXT/2 = 24MHz
	 *      BCLK  = REFO = 32kHz
	 */
	MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
	MAP_CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
	MAP_CS_initClockSignal(CS_HSMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);
	MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_2);
	MAP_CS_initClockSignal(CS_BCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
}

/***********************************************************
  Function: _system_pre_init
 */
int _system_pre_init(void)
{
  // stop WDT
   MAP_WDT_A_holdTimer();                        // Hold watchdog timer

  // Perform C/C++ global data initialization
  return 1;
}
