unsigned short packetstatus;
unsigned short rxbytes;
unsigned short marcstate;
unsigned short lqi;       // Note: Bit 7 of this register is the CRC status bit
int rssi;

//----------------------------------------------------------------------------
//  Description:  This file contains functions that configure the CC1100/1150 
//  device.
// 
//----------------------------------------------------------------------------

#include "include.h"
#include "TI_CC_CC1100-CC2500.h"

// Product = CC1100/CC1150
// Crystal accuracy = 40 ppm
// Xtal frequency = 26 MHz
// RF output power = 0 dBm
// RX filterbandwidth = 540 or 615 kHz (dependent upon FEC setting)
// Return state:  Return to RX state upon leaving either TX or RX
// Manchester enable = (0) Manchester disabled
// Channel spacing = 250 KHz
// Sync mode = (3) 30/32 sync word bits detected
// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX
// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled
// Length configuration = (1) Variable length packets.
// Address check = 1
// FIFO autoflush = 0
// Device address = 1

void writeRFSettings(void)
{
    // Write register settings
    
    TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG2, 0x0E);        // GDO2 output pin config (Carrier Sense)  
    TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x06);        // GDO0 output pin config (Asserts when SYNC has beed sent/received
                                                      // and de-asserts when at teh end of the packet
    TI_CC_SPIWriteReg(TI_CCxxx0_PKTLEN, PACKETLEN);   // Packet length
    TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL1, 0x00);      // Packet automation control. Disable Address check and Status Append 
    TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x45);      // Packet automation control. Note: CRC enabled, whitening enabled, variable packet length
    
    TI_CC_SPIWriteReg(TI_CCxxx0_ADDR,     0x01);      // Device address.
    TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR,   0x00);      // Channel number.
 
// Set Base Frequency (902.5 MHz)    
    
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2,    0x22);      // Freq control word, high byte
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1,    0xB6);      // Freq control word, mid byte.
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0,    0x27);      // Freq control word, low byte.
    
#ifdef BAUD150GFSK

    // Modulation: GFSK
    // Data Rate: 150 kbps
    // Receiver BW: 464.3 KHz
    // Preamble: 4 bytes
    // FEC Disabled
    
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL1,  0x08);  // IF Frequency: 203.1 kHz
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL0,  0x00);  // Frequency Offset: none

    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4,  0x4C);  // RX Channel Bandwidth: 406.25 kHz
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3,  0x7A);  // Data Rate: 150 kbps
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2,  0x13);  // DEM_DCFILT: Enabled; Modulation: GFSK; SYNC_MODE: 30/32 sync bits
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1,  0x23);  // FEC: Disabled; Preamble Bytes: 4
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0,  0x3B);  // Channel Spacing: 250 kHz
    
    TI_CC_SPIWriteReg(TI_CCxxx0_DEVIATN,  0x53);  // Deviation: 69.8 kHz
#endif
 
#ifdef BAUD300FEC
    // Base Frequency: 897.5 MHz
    // Modulation: MSK
    // Data Rate: 300 kbps
    // Receiver BW: 650 KHz
    // Preamble: 4 bytes
    // FEC Enabled

    TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL1,  0x12); // Freq synthesizer control
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL0,  0x00); // Freq synthesizer control.
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2,    0x22); // Freq control word, high byte
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1,    0x84); // Freq control word, mid byte.
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0,    0xEC); // Freq control word, low byte.
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4,  0x1D); // Modem configuration. Data rate = 300 kbps, RX Filter bw = 650 KHz
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3,  0x7A); // Modem configuration.
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2,  0xF3); // Modem configuration - optimized for current.
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1,  0xA3); // Modem configuration. Note: Preamble bytes = 4, FEC enabled
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0,  0x3B); // Modem configuration.
    TI_CC_SPIWriteReg(TI_CCxxx0_DEVIATN,  0x00); // Modem deviation
#endif    
  
#ifdef BAUD300FECSENS
    // Base Frequency: 897.500 MHz
    // Modulation: MSK
    // Data Rate: 300 kbps
    // Receiver BW: 650 KHz
    // Preamble: 4 bytes
    // FEC Enabled

    TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL1,  0x0D); // Freq synthesizer control
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL0,  0x00); // Freq synthesizer control.
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2,    0x22); // Freq control word, high byte
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1,    0x84); // Freq control word, mid byte.
    TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0,    0xEC); // Freq control word, low byte.
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4,  0x1D); // Modem configuration. Data rate = 300 kbps, RX Filter bw = 650 KHz
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3,  0x7A); // Modem configuration.
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2,  0x73); // Modem configuration - optimized for sensitivity
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1,  0xA3); // Modem configuration. Note: Preamble bytes = 4, FEC enabled
    TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0,  0x3B); // Modem configuration.
    TI_CC_SPIWriteReg(TI_CCxxx0_DEVIATN,  0x00); // Modem deviation
#endif        
  
// common settings     
    
    TI_CC_SPIWriteReg(TI_CCxxx0_MCSM1 ,   0x30); // MainRadio Cntrl State Machine
                                                 // RXOFF_MODE: Idle; TXOFF_MODE: Idle   
#ifdef MONITOR    
    TI_CC_SPIWriteReg(TI_CCxxx0_MCSM0 ,   0x18); // Automatic Calibrate - IDLE to RX or TX
#else
    TI_CC_SPIWriteReg(TI_CCxxx0_MCSM0 ,   0x08); // Manual Calibration
#endif

    TI_CC_SPIWriteReg(TI_CCxxx0_FIFOTHR, 0x37);   // decrease gain by 18 dB - this allows the receiver to be placed 
                                                  // very close to the transmitter on turn on 
    
    TI_CC_SPIWriteReg(TI_CCxxx0_FOCCFG,   0x1D);  // Freq Offset Compens. Config
    TI_CC_SPIWriteReg(TI_CCxxx0_BSCFG,    0x1C);  // Bit synchronization config.

    TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2, 0xC7);  // AGC control.
    TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL1, 0x00);  // AGC control.
    TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL0, 0xB2);  // AGC Control
                                                  // Medium hysteresis, medium asymetric dead zone, medium gain
                                                  // WAIT_TIME = 32 samples
                                                  // FILTER_LENGTH = 8 samples 
    
    TI_CC_SPIWriteReg(TI_CCxxx0_FREND1,   0xB6);  // Front end RX configuration.
    TI_CC_SPIWriteReg(TI_CCxxx0_FREND0,   0x10);  // Front end RX configuration.
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL3,   0xEA);  // Frequency synthesizer cal.
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL2,   0x2A);  // Frequency synthesizer cal.
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL1,   0x00);  // Frequency synthesizer cal.
    TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL0,   0x1F);  // Frequency synthesizer cal.
    TI_CC_SPIWriteReg(TI_CCxxx0_FSTEST,   0x59);  // Frequency synthesizer cal.
   
    TI_CC_SPIWriteReg(TI_CCxxx0_TEST2,    0x81);  // Various test settings. 
    TI_CC_SPIWriteReg(TI_CCxxx0_TEST1,    0x35);  // Various test settings.
    TI_CC_SPIWriteReg(TI_CCxxx0_TEST0,    0x09);  // Various test settings.
}

// PATABLE (+10 dBm output power)       // Recommend value for use without PA
//extern char paTable[] = {0xC0};
// PATABLE (+6 dBm output power)        // Recommend value for use with PA for +20 dBm output
extern char paTable[] = {0xCE};
// PATABLE (0 dBm output power)
//extern char paTable[] = {0x3F};
extern char paTableLen = 1;

//-----------------------------------------------------------------------------
//  void RFSendPacket(char *txBuffer, char size)
//
//  DESCRIPTION:
//  This function transmits a packet with length up to 63 bytes.  To use this
//  function, GD00 must be configured to be asserted when sync word is sent and
//  de-asserted at the end of the packet, which is accomplished by setting the
//  IOCFG0 register to 0x06, per the CCxxxx datasheet.  GDO0 goes high at
//  packet start and returns low when complete.  The function polls GDO0 to
//  ensure packet completion before returning.
//
//  ARGUMENTS:
//      char *txBuffer
//          Pointer to a buffer containing the data to be transmitted
//
//      char size
//          The size of the txBuffer
//-----------------------------------------------------------------------------

void RFSendPacket(char *txBuffer, char size)
{
    TI_CC_SPIWriteBurstReg(TI_CCxxx0_TXFIFO, txBuffer, size); // Write TX data
    TI_CC_SPIStrobe(TI_CCxxx0_STX);         // Change state to TX, initiating
                                            // data transfer

    while (!(TI_CC_GDO0_PxIN&TI_CC_GDO0_PIN));
                                            // Wait GDO0 to go hi -> sync TX'ed
    while (TI_CC_GDO0_PxIN&TI_CC_GDO0_PIN);
                                            // Wait GDO0 to clear -> end of pkt
}

//-----------------------------------------------------------------------------
//  char RFReceivePacket(char *rxBuffer, char *length)
//
//  DESCRIPTION:
//  Receives a packet of variable length (first byte in the packet must be the
//  length byte).  The packet length should not exceed the RXFIFO size.  To use
//  this function, APPEND_STATUS in the PKTCTRL1 register must be enabled.  It
//  is assumed that the function is called after it is known that a packet has
//  been received; for example, in response to GDO0 going low when it is
//  configured to output packet reception status.
//
//  The RXBYTES register is first read to ensure there are bytes in the FIFO.
//  This is done because the GDO signal will go high even if the FIFO is flushed
//  due to address filtering, CRC filtering, or packet length filtering.
//
//  ARGUMENTS:
//      char *rxBuffer
//          Pointer to the buffer where the incoming data should be stored
//      char *length
//          Pointer to a variable containing the size of the buffer where the
//          incoming data should be stored. After this function returns, that
//          variable holds the packet length.
//
//  RETURN VALUE:
//          0x80:  CRC OK
//          0x00:  CRC NOT OK
//          0x01:  Packet length missmatch
//          0x02:  No data was put in the RXFIFO due to filtering
//-----------------------------------------------------------------------------

char RFReceivePacket(char *rxBuffer, char *length)
{
  char pktLen;
 
  packetstatus = TI_CC_SPIReadStatus(0x38);       // PKTSTATUS   
  rxbytes = TI_CC_SPIReadStatus(0x3B);            // RXBYTES; bits 0 - 6 contain # of bytes received 
  marcstate = TI_CC_SPIReadStatus(0x35); 
  lqi = TI_CC_SPIReadStatus(0x33);  
  rssi = TI_CC_SPIReadStatus(0x34);   
  if ((rssi & 0x0080) > 0)
    rssi |= 0xFF00;   // extend sign as needed
  
  if (rxbytes & TI_CCxxx0_NUM_RXBYTES)
  {
    pktLen = TI_CC_SPIReadReg(TI_CCxxx0_RXFIFO);  // Read length byte
    if (pktLen <= *length)                        // If pktLen size <= rxBuffer
    {
      TI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, rxBuffer, pktLen);    // Read data from CC1100
      *length = pktLen;                           // length contains the actual number of bytes received
      return (packetstatus & 0x80);               // Return CRC bit
    }                                           
    else
    {
      *length = pktLen;                           // Return the large size
      TI_CC_SPIStrobe(TI_CCxxx0_SFRX);            // Flush RXFIFO
      return 1;                                   // Packet Length Error
    }
  }
  else
    return 2;                                     // No data received
}

