/**************************************************************************************************
  Filename:       cavalier_board_cfg_rev2.h
  Revised:        $Date:$
  Revision:       $Revision:$

  Description:    Cavalier Board Definition File, board Rev2

 **************************************************************************************************/

#ifndef CAVALIER_BOARD_CFG_REV2_H
#define CAVALIER_BOARD_CFG_REV2_H


/* ------------------------------------------------------------------------------------------------
 *                                           INCLUDES
 * ------------------------------------------------------------------------------------------------
 */
#include <msp430.h>
#include "msp430_mcu.h"
#include <assert.h>

/* ------------------------------------------------------------------------------------------------
 *                                           General MACROS
 * ------------------------------------------------------------------------------------------------
 */
#ifndef st
#define st(x)      do { x } while (__LINE__ == -1)
#endif
#ifndef BV
#define BV(n)      (1 << (n))
#endif

#define ASSIGN_PIN(name, port, bit) \
   inline static void SET_##name##_PIN()      {P##port##OUT |= BIT##bit;} \
   inline static void CLR_##name##_PIN()      {P##port##OUT &= ~BIT##bit;} \
   inline static char READ_##name##_PIN()     {return 0x01 & (P##port##IN >> bit);} \
   inline static void MAKE_##name##_OUT()     {P##port##DIR |= BIT##bit;} \
   inline static void MAKE_##name##_IN()      {P##port##DIR &= ~BIT##bit;} \
   inline static void MAKE_##name##_GP()      {P##port##SEL &= ~BIT##bit;} \
   inline static void MAKE_##name##_SFUN()    {P##port##SEL |= BIT##bit;} \
   inline static void TOGGLE_##name##_PIN()       {P##port##OUT ^= BIT##bit;}

#define ASSIGN_INT_PIN(name, port, bit) \
    ASSIGN_PIN(name, port, bit) \
    static inline void SET_##name##_INT()      { P##port##IFG &= ~BIT##bit; \
						 						 P##port##IE |= BIT##bit; }  \
    static inline void CLR_##name##_INT()      { P##port##IE &= ~BIT##bit; } \
    static inline void MAKE_##name##_INT_RISING() { P##port##IES &= ~BIT##bit; } \
    static inline void MAKE_##name##_INT_FALLING(){ P##port##IES |= BIT##bit; }


/**************************************************************************************************
 *                                            DEFINES
 **************************************************************************************************/

//#define HAL_BOARD_CAV_REV1
#define HAL_BOARD_CAV_REV2

/*
 * 		CAVALIER PORT DEFINITIONS, V2 - 3/8/17
 *
 * 	P1.7	I/O/TA1.0					�  I:		nLSM_INT_MAG
	P1.6	I/O/TA1CLK/CBOUT			�  I:		XBEE_nSPI_ATTN
	P1.5	I/O/TA0.4					�  I:		nANA_PRESENT
	P1.4	I/O/TA0.3					�  I: 		nLSM_INT2_XL
	P1.3	I/O/TA0.2					�  I:		nLSM_INT1_XL
	P1.2	I/O/TA0.1					�  I:		nXBEE_SLEEP
	P1.1	I/O/TA0.0					�  I  		nPIXL_PRESENT
	P1.0	I/O/TA0CLK/ACLK				�  O: 		was nPIXL_PWR_EN

	P2.7	I/O/UCB0STE/UCA0CLK			�  O: 		XBEE-SSEL

	P3.4	I/O/UCA0RXD/UCA0SOMI		�  RXD:		MSP_RXD
	P3.3	I/O/UCA0TXD/UCA0SIMO		�  TXD:		MSP_TXD
	P3.2	I/O/UCB0CLK/UCA0STE			�  SCLK:	XBEE_SCK
	P3.1	I/O/UCB0SOMI/UCB0SCL		�  SOMI:	XBEE_MISO
	P3.0	I/O/UCB0SIMO/UCB0SDA		�  SIMO:	XBEE_MOSI

	P4.7	I/O/PM_NONE					�  O:		nXBEE_RST
	P4.6	I/O/PM_NONE					�  O:		XBEE_SLEEP_REQ
	P4.5	I/O/PM_UCA1RXD/PM_UCA1SOMI	�  RXD:		PIXL_IN (UART)
	P4.4	I/O/PM_UCA1TXD/PM_UCA1SIMO	�  TXD:		TP7
	P4.3	I/O/PM_UCB1CLK/PM_UCA1STE	�  O:		DE_RS485
	P4.2	I/O/PM_UCB1SOMI/PM_UCB1SCL	�  SCL		XL_SCL
	P4.1	I/O/PM_UCB1SIMO/PM_UCB1SDA	�  SDA		XL_SDA
	P4.0	I/O/PM_UCB1STE/PM_UCA1CLK	�  O:		nRE_RS485

	P5.7	I/O/TB0.1					�  O:		nDEV_LED
	P5.5	I/O/XOUT					�  XOUT:	XTAL-32K
	P5.4	I/O/XIN						�  XIN: 	XTAL-32K
	P5.3	I/O/XT2OUT					�  O:		TP6
	P5.2	I/O/XT2IN					�  O:		TP8
	P5.1	I/O/VREF-/A9/VeREF-			�  O:		nc
	P5.0	I/O/VREF+/A8/VeREF+			�  O:		nANA_PWR_EN

	P6.5	I/O/A5/CB5					�  A5:		MSP_VBATT
	P6.4	I/O/A4/CB4					�  A4:		MSP_ANA_PWR
	P6.3	I/O/A3/CB3					�  A3:		MSP_ANA3
	P6.2	I/O/A2/CB2					�  A2:		MSP_ANA2
	P6.1	I/O/A1/CB1					�  A1:		MSP_ANA1
 */

#define HAL_CPU_CLOCK_MHZ     	1
#define HAL_MCLK_CLOCK_FREQ     1048576
#define HAL_SMCLK_CLOCK_FREQ    HAL_MCLK_CLOCK_FREQ
#define HAL_ACLK_CLOCK_FREQ     32768

#define INFOD_ADR               (0x1800)
#define INFOC_ADR               (0x1880)
#define INFOB_ADR               (0x1900)
#define INFOA_ADR               (0x1980)

/* ------------------------------------------------------------------------------------------------
 *                                          Clock Type
 * ------------------------------------------------------------------------------------------------
 */
#define HAL_CLOCK_TYPE_DCO         0
#define HAL_CLOCK_TYPE_CRYSTAL     1

#if defined (HAL_CLOCK_CRYSTAL)
#define HAL_CLOCK_TYPE             HAL_CLOCK_TYPE_CRYSTAL
#else
#define HAL_CLOCK_TYPE             HAL_CLOCK_TYPE_DCO
#endif


/* ------------------------------------------------------------------------------------------------
 *                                       LED Configuration
 * ------------------------------------------------------------------------------------------------
 */

/* LED1 -  LED_POWER */
#define LED1_BV           BV(7)
#define LED1_PORT         P5OUT
#define LED1_DDR          P5DIR

ASSIGN_PIN(nDEV_LED,          5,7)   //

#define HAL_TURN_ON_DBGLED1()           CLR_nDEV_LED_PIN()
#define HAL_TURN_OFF_DBGLED1()          SET_nDEV_LED_PIN()
//#define HAL_TOGGLE_DBGLED1()            TOGGLE_nDEV_LED_PIN()

/* ------------------------------------------------------------------------------------------------
 *                                    TICK Timer HW Defines
 * ------------------------------------------------------------------------------------------------
 */


// # of ms's per Tick
#define TICK_TIMER_FAST_MS_PER_TICK     10
#define TICK_PRESCAL_FAST_DIV			2
#define TICK_FAST_CCR_COUNT				((HAL_ACLK_CLOCK_FREQ/TICK_PRESCAL_FAST_DIV*TICK_TIMER_FAST_MS_PER_TICK +500)/1000L)

// # of ms's per Tick
#define TICK_TIMER_SLOW_MS_PER_TICK     1000
#define TICK_PRESCAL_SLOW_DIV			2
#define TICK_SLOW_CCR_COUNT				(HAL_ACLK_CLOCK_FREQ/TICK_PRESCAL_SLOW_DIV*TICK_TIMER_SLOW_MS_PER_TICK/1000L)

#define FAST_TICKS_PER_SLOW				TICK_TIMER_SLOW_MS_PER_TICK / TICK_TIMER_FAST_MS_PER_TICK

/* * * Currently using TimerA1 for Tick & oneshot timers * * */

// 10ms tick
#define TICK_TIMER_START_FAST()	\
{								\
	TA1CTL = 0;					\
	TA1R = 0;					\
	TA1CCTL0 = 0;				\
	TA1CCR0 = TICK_FAST_CCR_COUNT;	\
	TA1IV = 0;					\
	TA1CTL |= TASSEL_1 + MC_1 + ID_1; 	/* ACLK, /2 PRESCAL */	\
								\
	TA1CCTL0 |= CCIE;			\
}

// 1s tick
#define TICK_TIMER_START_SLOW()	\
{								\
	TA1CTL = 0;					\
	TA1R = 0;					\
	TA1CCTL0 = 0;				\
	TA1CCR0 = TICK_SLOW_CCR_COUNT;	\
	TA1IV = 0;					\
	TA1CTL |= TASSEL_1 + MC_1 + ID_1; 	/* ACLK, /2 PRESCAL */	\
								\
	TA1CCTL0 |= CCIE;			\
}


#define TICK_TIMER_STOP()		\
{								\
	TA1CTL = 0;					\
	TA1R = 0;					\
	TA1CCTL0 = 0;				\
	TA1IV = 0;					\
}


#define TICK_ONESHOT_SET(ms)	st( TA1CCR1 = (HAL_SMCLK_CLOCK_FREQ/TICK_PRESCAL_DIV*TICK_TIMER_MS_PER_TICK/1000L) )

// Abstract timer resource regs
#define TICK_CC0_VECTOR		TIMER1_A0_VECTOR
#define TICK_CC1_VECTOR		TIMER1_A1_VECTOR
#define TICK_TMRIV			TA1IV
#define TICK_CCTL1			TA1CCTL1
#define TICK_CCR0			TA1CCR0
#define TICK_CCR1			TA1CCR1
#define TICK_TR				TA1R


/* ------------------------------------------------------------------------------------------------
 *                                    PRESENCE Inputs
 * ------------------------------------------------------------------------------------------------
 */

ASSIGN_INT_PIN(nANA_PRESENT,	1,5)
ASSIGN_INT_PIN(nPIXL_PRESENT,	1,1)

//ASSIGN_PIN(CAV_REV, 6,4)

/* ------------------------------------------------------------------------------------------------
 *                                    Port1 IRQ Definitions
 * ------------------------------------------------------------------------------------------------
 */



/* ------------------------------------------------------------------------------------------------
 *                                    RADIO Defines
 * ------------------------------------------------------------------------------------------------
 */
// Radio serial intfc Uses UCB0 in 4w SPI mode
ASSIGN_PIN(XBEE_SSEL,			2,7)

ASSIGN_PIN(XBEE_nRST,			4,7)
ASSIGN_PIN(XBEE_SLEEP_RQ,		4,6)

ASSIGN_INT_PIN(XBEE_SLEEP_STAT,	1,2)
ASSIGN_INT_PIN(XBEE_nSPI_ATTN,	1,6)

#define P1IV_SLEEP_STAT			P1IV_P1IFG2		//P1.2

// SPI Defines
#define XBEE_SPICLK_FREQ        500000
#define	XBEE_SPI_PORT			USCI_B0_BASE

#define SELECT_XBEE_SPI()		CLR_XBEE_SSEL_PIN()
#define DESELECT_XBEE_SPI()		SET_XBEE_SSEL_PIN()
#define XBEE_ATTN_ASSERTED()	(READ_XBEE_nSPI_ATTN_PIN() == 0)

#define ASSERT_XBEE_RESET()		MAKE_XBEE_nRST_OUT()
#define DEASSERT_XBEE_RESET()	MAKE_XBEE_nRST_IN()

/* ------------------------------------------------------------------------------------------------
 *                                    UART Defines
 * ------------------------------------------------------------------------------------------------
 */
/// RS485 serial intfc Uses UCA0 in UART mode (full duplex)
ASSIGN_PIN(RS422_DE,			4,3)
ASSIGN_PIN(RS422_nRE,			4,0)

#define HAL_UART_ENABLE_PORT_0
#define MONITOR_SERIAL_PORT			HAL_UART_PORT_0
#define ANA_SERIAL_PORT             HAL_UART_PORT_0
#define MONITOR_UART_RX_MAX_BUFFER_SIZE	256
#define MONITOR_UART_TX_MAX_BUFFER_SIZE	256
//#define MONITOR_BAUDRATE			HAL_UART_BR_115200
#define MONITOR_BAUDRATE            HAL_UART_BR_9600
#define MONITOR_BAUDRATE_1200       HAL_UART_BR_1200

#define HAL_UART0_PORT_IN         P3IN
#define HAL_UART0_RXD_BV          BV(4)
#define HAL_UART1_PORT_IN         P4IN
#define HAL_UART1_RXD_BV          BV(5)

#define MONITOR_UART_RXD_IN		  HAL_UART0_PORT_IN
#define MONITOR_UART_RXD_BV		  HAL_UART0_RXD_BV

/* ------------------------------------------------------------------------------------------------
 *                                    PIXL Defines
 * ------------------------------------------------------------------------------------------------
 */
#ifndef REV3_DAFE //include rev1/rev2/rev3.2/rev4, exclude for rev3/dafe
// PIXL serial intfc Uses UCA1 in UART mode - receive only
#define PIXL_SERIAL_PORT                HAL_UART_PORT_1
#define PIXL_UART_RX_MAX_BUFFER_SIZE    256 // was 40
#define PIXL_UART_TX_MAX_BUFFER_SIZE    256 //was 0
#define PIXL_BAUDRATE                   HAL_UART_BR_9600
#else
// include for rev3 cavalier has one shared port, exclude for rev4 - uses the pixl port
#define PIXL_SERIAL_PORT                HAL_UART_PORT_0
#define PIXL_UART_RX_MAX_BUFFER_SIZE    256
#define PIXL_UART_TX_MAX_BUFFER_SIZE    256
#define PIXL_BAUDRATE                   HAL_UART_BR_9600
#endif

#define HAL_UART_ENABLE_PORT_1
//#define HAL_UART_HALF_DUPLEX_PORT_0	// is half duplex, but only one direction

ASSIGN_PIN(PIXL_PWR_EN,       1,0)

#define ENABLE_PIXL_PWR()		SET_PIXL_PWR_EN_PIN();
#define DISABLE_PIXL_PWR()		CLR_PIXL_PWR_EN_PIN();

/* ------------------------
 *
 * ------------------------------------------------------------------------
 *                                    Mag/Accel Defines
 * ------------------------------------------------------------------------------------------------
 */

// Mag / accel uses UCB1 in I2C Master Mode
#define MAGACCEL_I2CBASEADR		USCI_B1_BASE

//// For LSM303AGR
//#define MAG_SLAVEADDR		0x1e
//#define ACC_SLAVEADDR		0x19

// For LSM303C
#define MAG_SLAVEADDR		0x1e
#define ACC_SLAVEADDR		0x1d

/* ------------------------------------------------------------------------------------------------
 *                                    ADC Configuration
 * ------------------------------------------------------------------------------------------------
 */

/* Channels */
#define ADC_CHANNEL_0          0x00
#define ADC_CHANNEL_1          0x01
#define ADC_CHANNEL_2          0x02
#define ADC_CHANNEL_3          0x03
#define ADC_CHANNEL_4          0x04
#define ADC_CHANNEL_5          0x05
#define ADC_CHANNEL_6          0x06
#define ADC_CHANNEL_7          0x07

#define ADC_CHANNEL_TEMP       0x0A
#define ADC_CHANNEL_VDD        0x0B
#define ADC_CHANNEL_12         0x0C
#define ADC_CHANNEL_13         0x0D
#define ADC_CHANNEL_14         0x0E
#define ADC_CHANNEL_15         0x0F

// App specific 
#define ADC_CHANNEL_ANA1    		ADC_CHANNEL_1
#define ADC_CHANNEL_ANA2   			ADC_CHANNEL_2
#define ADC_CHANNEL_ANA3   			ADC_CHANNEL_3
#define ADC_CHANNEL_ANA_PWR         ADC_CHANNEL_4
#define ADC_CHANNEL_VBATT        	ADC_CHANNEL_5

// configure P5 & P6 SEL regs
#define ADCIN_P6SEL     	0x3E        // Enable A/D channel A1,A2,A3,A4,A5
#define XT1_P5SEL			0x30		// Select XT1 osc pins

// Sensor Power Control
// Uplanned difference from rev3.2/3.3 below need another flag to control this
//#ifndef REV3_DAFE // include for rev3.2 and all revs prior to rev3.2 exclude rev3.2, 3.5 and above
ASSIGN_PIN(ANA_PWR_EN,         5,0) // rev4 active low rev3 active low

#define ENABLE_ANA_PWR()		SET_ANA_PWR_EN_PIN();
#define DISABLE_ANA_PWR()		CLR_ANA_PWR_EN_PIN();

/* ------------------------------------------------------------------------------------------------
 *                                    Misc Defines
 * ------------------------------------------------------------------------------------------------
 */


/* ------------------------------------------------------------------------------------------------
 *                                    UART & Serial Comm Detect
 * ------------------------------------------------------------------------------------------------
 */

//#define UART_RXD_BV     BV(5)
//#define UART_RXD_REN    P3REN
//#define UART_RXD_IN     P3IN
//#define UART_RXD_OUT    P3OUT
//#define UART_RXD_DIR    P3DIR



/* ------------------------------------------------------------------------------------------------
 *                                          Watchdog Macros
 * ------------------------------------------------------------------------------------------------
 */
// Set watchdog counter to about 16 seconds

// Reset  Watchdog timer
#define RESET_WATCHDOG()             st( WDTCTL = WDTPW | WDTSSEL0 | WDTCNTCL | WDTIS1 | WDTIS0; )
#define STOP_WATCHDOG()              st( WDTCTL = WDTPW + WDTHOLD; )
#define FORCE_WATCHDOG()             st( WDTCTL = ~WDTPW; )

/* ------------------------------------------------------------------------------------------------
 *                                            Macros
 * ------------------------------------------------------------------------------------------------
 */

#define HAL_CLOCK_INIT(x)                            \
{                                                    \
  /* The DCO library does not handle the stack */    \
  /* frame well. As a result, this macro must */     \
  /* be the first thing that runs after main. */     \
  /* Disable watchdog timer */                       \
  STOP_WATCHDOG();                          		 \
                                                     \
  if (x == HAL_CLOCK_TYPE_CRYSTAL)                   \
  {                                                  \
    /* Configure external crystal TBD */             \
  }                                                  \
  else if (x == HAL_CLOCK_TYPE_DCO)                  \
  {                                                  \
	P5SEL = XT1_P5SEL;								 \
    UCS_turnOnLFXT1(UCS_XT1_DRIVE_0,UCS_XCAP_3);     \
  }                                                  \
  else                                               \
  {                                                  \
    /* Unknown clock type */                         \
    assert(0);                                   \
  }                                                  \
}

/* ----------- Board Initialization ---------- */

// Powerup port initialization macro
// P3DIR was 0x0d
#define HAL_PORT_INIT()                                         \
{                                                               \
  P1REN =  0x22;        \
  P1SEL =  0x00;        \
  P1OUT =  0xDD;        \
  P1DIR =  0x01;        \
\
  P2REN =  0x00;        \
  P2SEL =  0x00;        \
  P2OUT =  0x80;        \
  P2DIR =  0x80;        \
\
  P3REN =  0x00;        \
  P3SEL =  0x1F;        \
  P3OUT =  0x0F;    	\
  P3DIR =  0x0D;        \
\
  P4REN =  0x00;        \
  P4SEL =  0x36;        \
  P4OUT =  0x17;        \
  P4DIR =  0x59;        \
\
  P5REN =  0x00;        \
  P5SEL =  XT1_P5SEL;   \
  P5OUT =  0x81;        \
  P5DIR =  0xEF;        \
\
  P6REN =  0x00;        \
  P6SEL =  ADCIN_P6SEL; \
  P6OUT =  0x00;        \
  P6DIR =  0x00;        \
\
  PJREN = 0xFF;         \
  PJOUT = 0x00;         \
  PJDIR = 0x00;         \
\
}


#define HAL_BOARD_INIT()                                         \
{                                                                \
  /* initialize MCU clocks */                                    \
  HAL_CLOCK_INIT(HAL_CLOCK_TYPE);                                \
  HAL_PORT_INIT();                                               \
}

// Restart system from absolute beginning
// Disables interrupts, forces WatchDog reset
#define SystemReset()       \
{                           \
  __disable_interrupt();    \
  HAL_SYSTEM_RESET();       \
}

// Wait for specified microseconds
//#define MicroWait(t) Onboard_wait(t)


#endif  //CAVALIER_BOARD_CFG_REV2_H


