
/*--------------------------------INCLUDES-------------------------------------*/
#include "msp430.h"
#include "CC2MSP.h"
#include <stdlib.h>
#include <string.h>

void initADC(void);
void initTimer(void);
void initSPI(void);
void ledUpdate(void);
void UpdateTimer(void);

// typedefs
typedef unsigned char uint8_t;





bool CartA;
uint8_t CartA_DC;

// Variables
uint8_t nBuckled = 0;
uint8_t nUnbuckled = 0;
uint8_t nCartAStart = 0;
uint8_t nCartBStart = 0;

uint8_t length = 0;
uint8_t CRCok = 0;
uint8_t nGoodPackets = 0;
uint8_t nPackets = 0;
int nCRCBuffer = 0;
uint8_t fifosize = 0;
uint8_t nState;
uint8_t secondpacketcount = 1;
uint8_t PacketRXcount = 0;
uint8_t PacketRXcount255 = 0;
uint8_t nCounterTime = 0;
uint8_t nCounterSec = 0;
uint8_t nCounterMins = 0;


uint8_t nRepeats = 1;



uint8_t initial_power = 0xFE;
char rxBuffer[20];
//char rxBuffer2[6];
char status[2];
char CRCCheckBuffer[20];


char *ptrA;
char *ptrB;
uint8_t rxbytes;
uint8_t rxbytes2;

// Counters
short int nCounter = 0;
short int nCounter_DMU = 0;
short int nCounter_Cart = 0;

unsigned int nCount = 0;

const uint8_t sec_1 = 20;

const uint8_t sec_3_5 = 70;

uint8_t nCounter_R = 0;
uint8_t nCounter_B = 0;
uint8_t nCounter_Y = 0;
uint8_t nCounter_Beeps = 0;

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
 
  initTimer();
  initSPI();
  initADC();
  
  
    for (int i = 0; i < 20; i++) {
    rxBuffer[i] = 0x00;
    }
  
    for (int i = 0; i < 19; i++) {    //i < sizeof(rxBuffer)
        CRCCheckBuffer[i] = 0x00;
      }
    
                                                       //Flush RXFIFO (Overflown)
      
      cc_strobe(TI_CCxxx0_SIDLE); 
    __delay_cycles(1000);
      cc_strobe(TI_CCxxx0_SFRX);   
      __delay_cycles(1000);
      cc_strobe(TI_CCxxx0_SRX); //Start RX

  
  __bis_SR_register(LPM3_bits + GIE);       // Enter LPM0 w/ interrupt
}

/*--------------------------------FUNCTIONS------------------------------------*/

void UpdateTimer(void){
  
    if(nCounterTime == sec_1){
    nCounterSec++;
    nCounterTime = 0;
  }
  if(nCounterSec == 60){
    nCounterMins++;
    nCounterSec = 0;
  }
  
}

void initADC(void) {
  
  ADC10CTL0 = ADC10SHT_0 + ADC10ON + ADC10SR; // ADC10ON, reduced buffer
  ADC10AE0 |= A0;                         // P2.0 ADC option select
}

void initTimer(void) {
  //Port Direction Setup
  P1OUT = 0x00; 
  P2OUT = 0x00; 
  P1DIR |= 0xF7;                              //P1 All but 1.3 Outputs
  P1SEL |= BIT2;                              // P1.2 pwm
  P2DIR |= 0xEA;
  
  //CC2500 Packet RX Interrupt
  GDO0_PxIES |= GDO0_PIN;                     // Int on falling edge (end of pkt)
  GDO0_PxIFG &= ~GDO0_PIN;                    // Clear flag
  GDO0_PxIE |= GDO0_PIN;                      // Enable int on end of packet
  
  
  //Main Timer Setup  
  TA1CCTL0 = CCIE;                            // TACCR0 interrupt enabled
  TA1CCR0 = 1638;
  TA1CTL = TASSEL_1 + MC_2;                   // ACLK, contmode
}

//Setup MSP SPI and CC2500 Settings
void initSPI(void) {
  spi_setup();                                                  //Setup SPI on MCU
  cc_powerup_reset(); 		                                //Reset CC2500
  writeRFSettings();		    		                //Write RF settings to config reg
  cc_write_burst_reg( TI_CCxxx0_PATABLE, &initial_power, 1);	//Write PATABLE, Would like to move this into the WriteRFSettings Function
}

//LED Status Update
void ledUpdate () {
 //Update Program LED heres
}

// Timer1_A0 interrupt service routine
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A0 (void)
{


    
    //Reset Cart Status for Next Update
    CartA = false;
    
    
    //Update Timer
    nCounterTime++;
    UpdateTimer();
	
    //Clear rxBuffer
    for (int i = 0; i < 20; i++) {    //i < sizeof(rxBuffer)
      rxBuffer[i] = 0x00;
    }
      
    //Total Recieved Packet Counter   
    if(nPackets == 255){
      CRCCheckBuffer[nCRCBuffer] = nGoodPackets;
      nPackets = 0;
      nGoodPackets = 0;
      nCRCBuffer++;
    }
          
    //Read Packet into RX Buffer
    fifosize = (cc_read_status( TI_CCxxx0_RXBYTES ) & TI_CCxxx0_NUM_RXBYTES);   //Number of Bytes on FIFO
    //if((PacketRXcount > 0) || (fifosize >= 6)){
    if(fifosize >= 6){
    rxbytes = cc_read_reg( TI_CCxxx0_RXFIFO );                                  //Read in Length Byte
      if((rxbytes == 0x02) && (fifosize > 5)){                                  //Data+Status+Length = 5 Bytes
        TI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, rxBuffer, rxbytes);             //Read in main data packet
        TI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, status, 2);                     //Read in Status Byte
        memcpy( &rxBuffer[rxbytes], status, 2 );                                //Append Status Byte to rxBuffer
        rxBuffer[rxbytes + 2] = ( status[TI_CCxxx0_LQI_RX] & TI_CCxxx0_CRC_OK );//Add CRC check to rxBuffer
        nPackets++;                                                             //Update Total RX packets Counter
        //CRC Confirmed Packet Counter
        if(rxBuffer[4] == 0x80){                              
          nGoodPackets++;                                                       //Updated Total CRCok Packets
        }
      }
      if(PacketRXcount > 0){
        //PacketRXcount--;                                                        //Decrement PacketRXcount - Included to keep track of packets in fifo
      }
    }
    
    //RX Overflow Handle
    nState = cc_read_status( TI_CCxxx0_MARCSTATE );
    if(nState == 0x11){
      cc_strobe(TI_CCxxx0_SFRX);                                                //Flush RXFIFO (Overflown)
      __delay_cycles(1000);
      cc_strobe(TI_CCxxx0_SRX);                                                 //Put back into RX
    }
      
      
	                            
        if(strstr(rxBuffer,"11") != NULL) {
          CartA = true; 
        }
    
    
	
  //Cart A Disconnect Counters/Alerts  
  if (!(CartA)) {
    CartA_DC++;
    
    if(CartA_DC >= sec_3_5) {
      //If it loses connection after 3.5 Seconds, Do a task 

    }
 
  
  
  TA1CCR0 += 1638;                         // Add Offset to TACCR0
  }
}


// The ISR assumes the int came from the pin attached to GDO0. 
//  Interprets this as a signal from. CCxxxx indicating packet received.
#pragma vector=PORT1_VECTOR
__interrupt void port1_ISR (void){

  //Keep track of Packets Recieved -> 
PacketRXcount++;
if(PacketRXcount == 255){
  PacketRXcount255++;
  PacketRXcount = 0;
}
        
  GDO0_PxIFG &= ~GDO0_PIN;                                                      //Clear GDO0 Int Flag
}