/*****************************************************************
    CC1101.c

This file is used by all AT200 modules so send data to the CC1100


These routines will read and write the CC1100
 *
 * V2   - 0927-18
 *      Removed all watchdog resets and created a new counter
 *        for the SO wait function.
 *      This version seems to not have a lockup issue. If the radio
 *        stalls, the watchdog will time out

    Last change:  JRB  10 Jun 2008    8:54 am
*****************************************************************/
#include "SPI_ADI.h"
#include "CC1101Setup.h"
#include "Timers_ADI.h"
#include <SoftwareSerial.h>
#include "RF_Keys.h"
#include "RF.h"

byte RFTXArray[15];
byte RFRXIndex;
byte RFLastByte;
short RFValidStart;

long LastData;
short TXToggleFlag;

#define CLK_DELAY 5
#define CC_READ_MASK 0x80
#define CC_WRITE_MASK 0x00
#define CC_BURST_MASK 0x40

// COMMAND REGISTERS
#define CC_CMD_RESET 0x30
#define CC_CMD_STX 0x31
#define CC_CMD_RX 0x34
#define CC_CMD_TX 0x35
#define CC_CMD_IDLE 0x36
#define CC_CMD_SPWD 0x39
#define CC_CMD_RX_FLUSH 0x3A
#define CC_CMD_TX_FLUSH 0x3B
#define CC_CMD_NOP 0x3D
#define CC_CMD_PATABLE 0x3E
#define CC_CMD_FIFO 0x3F

// STATUS REGISTERS
#define CC_STATUS_VERSION (0x31 | CC_BURST_MASK)
#define CC_STATUS_MSTATE (0x35 | CC_BURST_MASK)
#define CC_STATUS_TX (0x3A | CC_BURST_MASK)
#define CC_STATUS_RX (0x3B | CC_BURST_MASK)

#define CLEAR_CS (digitalWrite(RF_CS, LOW))
#define SET_CS (digitalWrite(RF_CS, HIGH))

void sendUpKey(void);
void spiWrite(byte data);
void spiTransmit(byte state);
byte spiRead(void);
void sendDnKey(byte key);
long RFReadyCounter;

uint16_t rfState = 0;

#define RF_TX 17

SoftwareSerial ccTx(0, RF_TX);

#define SOWait() (digitalRead(12) != 0)

// void SOWait(void)
// {
// RFReadyCounter = 0;
// while(SO_INPUT)
// {
// if(RFReadyCounter > 1000)
// break;
// };
// }
/*****************************************************************
byte SendCCCommand(byte Address)

This sends commands to the CC and retrieves the status of the CC part.
*****************************************************************/
byte SendCCCommand(byte command)
{
    byte data;

    CLEAR_CS;

    SOWait();
    data = spi_readwrite(command);

    SET_CS;

    return (data);
}
/*****************************************************************
byte GetCCData(byte Address)

This retrieves the status of the CC part.
*****************************************************************/
byte GetCCData(byte address)
{
    byte data;

    CLEAR_CS;

    address |= CC_READ_MASK;
    SOWait();
    spi_readwrite(address);
    data = spi_readwrite(0);

    SET_CS;

    return (data);
}
/*****************************************************************
void SendCCData(byte Address, byte Data)

This sends a single byte of data to the CC.
*****************************************************************/
void SendCCData(byte address, byte data)
{
    CLEAR_CS;

    address |= CC_WRITE_MASK;

    SOWait();
    spi_readwrite(address);
    spi_readwrite(data);

    SET_CS;
}
/*****************************************************************
void SendCCDataBurst(byte Address, byte *Buffer, byte Count)

This sends multiple data bytes to the CC.
*****************************************************************/
void SendCCDataBurst(byte address, byte *buffer, byte count)
{
    byte dataCounter, data;

    CLEAR_CS;

    address |= CC_WRITE_MASK | CC_BURST_MASK;

    SOWait();
    spi_readwrite(address);

    for (dataCounter = 0; dataCounter < count; dataCounter++)
    {
        spi_readwrite(buffer[dataCounter]);
    }

    SET_CS;
}
/*****************************************************************
void SendCCDataBurst(byte Address, byte *Buffer, byte Count)

This sends multiple data bytes to the CC.
*****************************************************************/
void GetCCDataBurst(byte address, byte *buffer, byte count)
{
    byte dataCounter, data;

    CLEAR_CS;

    address |= CC_READ_MASK | CC_BURST_MASK;

    SOWait();
    spi_readwrite(address);
    for (dataCounter = 0; dataCounter < count; dataCounter++)
    {
        buffer[dataCounter] = spi_readwrite(0);
    }

    SET_CS;
}
/*****************************************************************
void SetChannel(byte Channel);

This sets up center frequency channel RF Module.

1 channel = 333kHz
*****************************************************************/
void SetChannel(byte Channel)
{
    SendCCData(0x0A, Channel * 3);
}
/*****************************************************************
void InitRFModule(void)

This sets up the configuration for the RF Module.
*****************************************************************/
void initCC1101(void)
{

    // Init the serial lines.
    SendCCCommand(CC_CMD_RESET);
    delay(2);
    SendCCDataBurst(0, (uint8_t *)rfSettings, sizeof(rfSettings));

    SendCCData(CC_CMD_PATABLE, 0xC0); // +10dBm
    SetChannel(0);

    SendCCCommand(CC_CMD_IDLE);
    pinMode(RF_TX, OUTPUT);
    delay(1);
    ccTx.begin(40000);
    Serial.println("RF Init Complete");
}

void ccTxOn(void)
{
    uint32_t time;

    SendCCCommand(CC_CMD_TX);
    time = millis();
    while (GetCCData(CC_STATUS_MSTATE) != 19)
    {
        if (millis() - time > 20)
            break;
    }
}

void ccTxOff(void)
{
    uint32_t time;

    SendCCCommand(CC_CMD_IDLE);
    time = millis();
    while (GetCCData(CC_STATUS_MSTATE) != 1)
    {
        if (millis() - time > 20)
            break;
    }
}
