/*
  cc1000.h
  
  CC1000 Trasmiter for Arduino

  18.02.2016
  by Marcin Stolarski
 */

#ifndef CC1000_h
#define CC1000_h
 
#include "Arduino.h"
 
 
/* Constants defined for CC1000 */
/* Register addresses */

#define CC1000_MAIN            0x00
#define CC1000_FREQ_2A         0x01
#define CC1000_FREQ_1A         0x02
#define CC1000_FREQ_0A         0x03
#define CC1000_FREQ_2B         0x04
#define CC1000_FREQ_1B         0x05
#define CC1000_FREQ_0B         0x06
#define CC1000_FSEP1           0x07
#define CC1000_FSEP0           0x08
#define CC1000_CURRENT         0x09
#define CC1000_FRONT_END       0x0A
#define CC1000_PA_POW          0x0B
#define CC1000_PLL             0x0C
#define CC1000_LOCK            0x0D
#define CC1000_CAL             0x0E
#define CC1000_MODEM2          0x0F
#define CC1000_MODEM1          0x10
#define CC1000_MODEM0          0x11
#define CC1000_MATCH           0x12
#define CC1000_FSCTRL          0x13
#define CC1000_FSHAPE7         0x14
#define CC1000_FSHAPE6         0x15
#define CC1000_FSHAPE5         0x16
#define CC1000_FSHAPE4         0x17
#define CC1000_FSHAPE3         0x18
#define CC1000_FSHAPE2         0x19
#define CC1000_FSHAPE1         0x1A
#define CC1000_FSDELAY         0x1B
#define CC1000_PRESCALER       0x1C
#define CC1000_TEST6           0x40
#define CC1000_TEST5           0x41
#define CC1000_TEST4           0x42
#define CC1000_TEST3           0x43
#define CC1000_TEST2           0x44
#define CC1000_TEST1           0x45
#define CC1000_TEST0           0x46

#define  LOCK_NOK         0x00
#define  LOCK_OK          0x01
#define  LOCK_RECAL_OK    0x02

#define RX_MODE 0x01
#define TX_MODE 0x02
#define PD_MODE 0x03

#define NONE_MODE 0x00
#define RTTY_MODE 0x01
#define CW_MODE 0x02
#define NRZ_MODE 0x03
#define DATA_MODE 0x04
#define SSB_AUDIO_MODE 0x05
#define FM_AUDIO_MODE 0x06

#define VCO_AB 0x00
#define VCO_A 0x01
#define VCO_B 0x02

#define NRZ 0x00
#define MANCHESTER 0x01
#define UART 0x02

/* Contents of CURRENT register for TX and RX, use SmartRF(R) Studio */
/* to find values for your application */   
 
//#define TX_CURRENT 0xF3
#define TX_CURRENT 0x81
//#define RX_CURRENT 0x8C
#define RX_CURRENT 0x44

/* Contents of PLL register for TX and RX, use SmartRF(R) Studio */
/* to find values for your application */

//#define TX_PLL 0x00
#define TX_PLL 0x48
//#define RX_PLL 0x00
#define RX_PLL 0x48

#define PA_VALUE_M30DBM 0x01 //-30dBm
#define PA_VALUE_M20DBM 0x03 //-20dBm
#define PA_VALUE_M10DBM 0x0A //-10dBm
#define PA_VALUE_0DBM 0x5F //  0dBm
#define PA_VALUE_10DBM 0xFF //7.7dBm

//#define PA_VALUE 0xF0
//#define PA_VALUE 0x0F //0dBm
//#define PA_VALUE 0xFF  //10dBm
//#define PA_VALUE 0x01 //-20dBm

//#define PA_VALUE 0x01 //-30dBm
//#define PA_VALUE 0x03 //-20dBm
//#define PA_VALUE 0x0A //-10dBm
//#define PA_VALUE 0x5F //  0dBm
//#define PA_VALUE 0xFF //7.7dBm

//CC1000 XTAL
//#define CC1000_XTAL  3686400
//#define CC1000_XTAL  7372800
//#define CC1000_XTAL 11059200
#define CC1000_XTAL 14745600
//#define CC1000_XTAL 14740000

//CC1000 XTAL FREQUENCY RANGE
//#define CC1000_XTAL_FR 0 //3-4MHz
//#define CC1000_XTAL_FR 1 //6-8MHz
//#define CC1000_XTAL_FR 2 //9-12MHz
#define CC1000_XTAL_FR 3 //12-16MHz

//CC1000 DEVIATION (SEPARATION)
#define CC1000_DEV 300

//XTAL REFERENCE DIV
#define CC1000_REFDIV 9

//CC1000 FRREQUENCE CORRECTION Hz
//#define CC1000_FRQCOR 17000
#define CC1000_FRQCOR 0

//REFERENCE FREQUENCY 1MHz< REF < 2.4 GHz. Best 1638400
#define CC1000_REF CC1000_XTAL/CC1000_REFDIV

//ADC VREF, 2.56=256
#define CC1000_RF_VREF 256
//Max value from ADC
#define ADC_SIZE 1024

#define CAL_TIMEOUT   0x7FFE
#define LOCK_TIMEOUT  0x7FFE
//------------------------------------------------------------------

#define BITS_PER_RTTY_CHAR  11
#define RTTY_START_BIT  0
#define RTTY_STOP_BIT 1

#define RTTY_TXsize 255

//------------------------------------------------------------------
 
//namespace Cc1000Lib {
 
 class Cc1000
 {
	 public:
	
		//CC1000 pins definitions
		byte Q1_PDATA;  // CC1000_PDATA, pin 
		byte Q1_PCLK;   // CC1000_PCLK, pin 
		byte Q1_PALE;   // CC1000_PALE, pin 
		byte Q1_DIO;    // CC1000_DIO, pin 
		byte Q1_DCLK;   // CC1000_DCLK, pin 
		byte Q1_CHPO;   // CC1000_CHPO, pin 
		byte Q1_RFADC;  // CC1000 RF ADC PORT (ADC(6))

		//signal and noise RF level
		uint16_t s_value=0;
		uint16_t n_value=0;

		//vars for VCO
		uint32_t trx_dev; //deviation
		uint8_t modem_mode=0;
		uint32_t trx_bitrate=600;
		uint8_t trx_power = PA_VALUE_0DBM;
		uint8_t rssi_ready=0;

		uint8_t RTTY_TXbuffer[RTTY_TXsize];
		uint16_t RTTY_TXptr = 0;
		
		//trx configuration
		
//------------------------------------------------------------------
		Cc1000(void);
		Cc1000(uint8_t pale, uint8_t pdata, uint8_t pclk, uint8_t dclk, uint8_t dio, uint8_t chpo, uint8_t rfadc);
//------------------------------------------------------------------
		boolean config(void);
		boolean config(uint8_t pale, uint8_t pdata, uint8_t pclk, uint8_t dclk, uint8_t dio, uint8_t chpo, uint8_t rfadc);
		uint8_t init(void);
		uint8_t def_init(void);
		
//------------------------------------------------------------------
		void PortInitCC1000(void);
		void ConfigureCC1000(char Count, short Configuration[]);
		void WriteToCC1000Register(char addr, char data);
		void WriteToCC1000RegisterWord(short addranddata);
		char ReadFromCC1000Register(char addr);
		void ResetCC1000(void);
		char CalibrateCC1000(void);
		void DIO_Port_SetIn(void);
		void DIO_Port_SetOut(void);
		char SetupCC1000RX(char RXCurrent);
		char SetupCC1000TX(char TXCurrent);
		char SetupCC1000TX_calibrate(char TXCurrent);
		void SetupCC1000PD(void);
		void WakeUpCC1000ToRX(char RXCurrent);
		void WakeUpCC1000ToTX(char TXCurrent);
		void AverageManualLockCC1000(void);
		void AverageFreeRunCC1000(void);
		void AverageAutoLockCC1000(void);
		void ReadCurrentCalibration(char *val1, char *val2);
		void OverrideCurrentCalibration(char val1, char val2);
		void StopOverridingCalibration(void);
		void ResetFreqSynth(void);
		void CC1000_FM_direct(char bit);
		void CC1000_send(char bit);
		void CC1000_send_byte(char my_byte);
		char CC1000_receive(void);
		char CC1000_receive_byte(void);
		char CC1000_Init (void);
		char CC1000_Init_src (void);
		uint8_t CC1000_modem (uint32_t br, uint8_t mode);
		char CC1000_RecivePacket(uint8_t n, uint8_t buffer[]);
		void CC1000_SendPacket(uint8_t n, uint8_t buffer[]);
		char LogicEqual(char a, char b) ;
		char checksum(char data);
		char SetupCC1000TX_CW(char TXCurrent);
		uint16_t s_level (void);
		uint16_t n_level (void);
		void CC1000TX_CW(char in);
		void CC1000TX_FM(char in);
		void CC1000TX_FM7K (uint8_t in);
		
//------------------------------------------------------------------
		uint8_t send_data(String str);
		uint8_t send_data(char *data);
		
//------------------------------------------------------------------
		uint8_t get_modem_mode(void);
		uint8_t get_power(void);
		uint32_t get_deviation(void);
		uint32_t get_bitrate(void);
		uint32_t get_frequency(void);
		uint32_t get_frequency(uint8_t vco);
		
//------------------------------------------------------------------
		char set_trx_mode(char mode);
		uint8_t set_modem_mode(uint8_t mode);
		uint8_t set_power(uint8_t pow);
		uint8_t set_bitrate(uint32_t bitrate);
		uint8_t set_frequency (uint32_t frq);
		uint8_t set_frequency (uint32_t frq, uint8_t vco, boolean monitor);
		uint8_t set_deviation (uint32_t dev);
		uint8_t set_deviation (uint32_t dev, boolean monitor);

//------------------------------------------------------------------
		void RTTY_flush(void);
		void CC1000_pdataWrite(uint8_t *buff, uint16_t size);
		void RTTY_addBit(uint8_t bit);
		void RTTY_addByte(uint8_t data);
		void RTTY_addString(char *addr);
		void RTTY_addString_P(const char *addr);
		void RTTY_addNulls(uint16_t length);

//------------------------------------------------------------------
	 private:
};

//};//namespace

#endif
