This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1101 - receiving wrong data bytes

Other Parts Discussed in Thread: CC1101

Hi,

I'm using the CC1101 as the receiver part in my communication link. I am able to configure the chip, send data and sometimes receive some data. It is really curious, because every time the first three data bytes are right and all the following are faulty. It doesn't matter how long the packets are (packet lengths 4, 5 and 8 are tested, also fixed packet length mode), only the first three bytes are right.

And sometimes the receiver stops receiving, although nothing has changed.. and sometimes it only receives something at startup

If I use the IOCFG0 register value 0x06 nothing can be seen at the GDO0 pin, but with 0x07 configuration the GDO0 pin asserts if a packet with rigth CRC has been recieved.So, the CRC is right, but the last data bytes are wrong, why?

 

Thanks for your interest and best regards

Jasmin

 

//SPI interface -- USART1, SPI 4-wire MSP430 Master

#include <msp430xG46x.h>
#include "SPI.h"

#include <stdio.h>
#include "lcd.h"
#include "time.h"
#include "defines.h"


int MST_DATA[25] = {IOCFG2_DATA, IOCFG0_DATA, PKTCTRL1_DATA, PKTCTRL0_DATA, ADDR_DATA, FSCTRL1_DATA, FREQ2_DATA, FREQ1_DATA, MDMCFG4_DATA, MDMCFG3_DATA, MDMCFG2_DATA,
					MDMCFG1_DATA, MDMCFG0_DATA, DEVIATN_DATA, MCSM1_DATA, MCSM0_DATA, FOCCFG_DATA, WORCTRL_DATA, FREND0_DATA, FSCAL3_DATA, 
					FSCAL2_DATA, FSCAL1_DATA, FSCAL0_DATA, TEST2_DATA, TEST1_DATA};
				 
int MST_REG[25] = {IOCFG2, IOCFG0, PKTCTRL1, PKTCTRL0, ADDR, FSCTRL1, FREQ2, FREQ1,MDMCFG4, MDMCFG3, MDMCFG2, MDMCFG1, MDMCFG0, DEVIATN, MCSM1, MCSM0, FOCCFG, WORCTRL,
				 	FREND0, FSCAL3, FSCAL2, FSCAL1, FSCAL0, TEST2, TEST1};

int SLV_DATA[25] = {0};
//char RF_DATA[22] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00};
char RF_DATA[3] = {0xD2, 0x2D, 0xD2};
char RF_DATA_len = 0x04;
char RF_DATA_ADDR = 0x67;

char Received_DATA[] = {0x00};
char Received_DATA_len = 0x00;
char status = 0x00;
char status_bytes[] = {0x00};

char syncword0;
char syncword1;
char RX_BYTES;

char x;
char y;
char z;
char count;

//char ausgabe[8];
//int wert;

int DATA_RECEIVED = 0x00;
int STATE_RECEIVED = 0x00;

char tx_buffer;

//F�r ASK/OOK gilt:
//extern char paTABLE[] = {0x00, 0xC0}; 				//0x60 = 0dBm; 0xC0 = 10dBm
//extern char paTABLE_len = 2;

//F�r 2FSK gilt:
extern char paTABLE[] = {0xC0}; 				//0x60 = 0dBm; 0xC0 = 10dBm
extern char paTABLE_len = 1;

void init_system(void) {
    P9DIR |= BIT6 + BIT7;                                   // LCD
    P10DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5;      // LCD
    P7DIR |= BIT7;                                          // Hintergurndbeleuchtung

    P2DIR |= BIT2 + BIT3 + BIT0;        //  Motor, Magnetventil, Sensor
    MOTOR_OFF;
    VALVE_OPEN;
    PSENSOR_OFF;

    LCDBACKLIGHT_OFF;

    // LCD Reset
    P10OUT = 0;
    P10OUT |= LCD_RESET;

    // Bluetooth AN
//  P2DIR |= BIT1;
//  P2OUT |= BIT1;      // BT Strom AN
}

void initClock(void) {
  unsigned int i;

  FLL_CTL0 |= XCAP10PF;                     // Set load capacitance
  FLL_CTL1 &= ~XT2OFF;                      // Turn on XT2

  // Loop until (32kHz) crystal stabilizes
  do {
    IFG1 &= ~OFIFG;                         // Clear oscillator fault flag
    for (i = 50000; i; i--);                // Delay
  }
  while (IFG1 & OFIFG);                     // Test osc fault flag

  FLL_CTL1 = SELS;                          // Select SMCLK source as XT2CLK
  FLL_CTL1 |= SELM_XT2;                     // Select MCLK source as XT2CLK
}


void main(void)
{
	volatile unsigned int i;
	volatile unsigned int k;
	//int data = IOCFG0; 
	
	WDTCTL = WDTPW + WDTHOLD;
	FLL_CTL0 |= XCAP14PF;
	
	//Warte bis Crystal stabil ist
	
	do
	{
		IFG1 &= ~OFIFG;						//L�sche OSCFault flag
		for(i = 0x47FF; i > 0; i--);		//Timer zum Setzen des Flags
	}
	while((IFG1 & OFIFG));					//�berpr�fe, ob OSCFault flag noch gesetzt ist
	
	for(i = 2100; i > 0; i--);				//Warte bis DCO stabil ist

 	delay(10);
  
	SPI_SETUP();							//Initialisierungssequenz der SPI-Schnittstelle
	CC1101_RST();							//CC1101 Reset

	delay(10);

	P1SEL |= 0x02;							//P1.1 als MCLK
	P1DIR |= 0x02;							//P1.1 als output
	
	P3DIR |= 0x40;							//P3.6 als output
	P3OUT |= 0x40;							//P3.6 high --> Enable XPRESSO
	
//Konfiguration des CC1101 -- Register settings
	for(k = 0; k <= 24; k++)
	{
		SPI_REG_WRITE(MST_REG[k], MST_DATA[k]);
		delay_us(20);
	}
	
	//SPI_REG_WRITE(PKTLEN, 8);
	SPI_REG_WRITE(PKTLEN, 5);
	DATA_RECEIVED = SPI_REG_READ(PKTLEN);
	
//Auslesen der beschriebenen Register
	for(k = 0; k <= 24; k++)
	{
		SLV_DATA[k] = SPI_REG_READ(MST_REG[k]);
		delay_us(20);
	}

	init_system();
    lcd_backlight_on();

    initClock();

    init_lcd();
    blink_lcd(0,0,0);               // Blinken des Cursors AUS

//Vergleich der beschriebenen mit den ausgelesenen Werten    
    for(k = 0; k <= 24; k++)
    {
    	if(SLV_DATA[k] == MST_DATA[k])
    	{
    		printf_lcd(1, 0, "Reg Status ok", 1);
    		delay_us(2);
    	}else
    	{
   			printf_lcd(5, 0, "Error", 1);
       		delay_us(2);
    	}
	}

//Programmieren der Ausgangsleistung (0 dBm)
	//SPI_REG_WRITE_BURST(PATABLE, paTABLE, paTABLE_len);
	SPI_REG_WRITE(PATABLE, paTABLE[0]);
	//SPI_REG_WRITE(TXFIFO_single, 0x00);
	syncword0 = SPI_REG_READ(0x04); 	//Abfrage des Sync words high byte
	syncword1 = SPI_REG_READ(0x05);		//Abfrage des Sync words low byte

//Senden von Daten
	//SPI_STROBE(SRX);
	//tx_buffer = 0x0F;	
		
	//binary_print_lcd(tx_buffer);
	
	
	
	SPI_STROBE(SIDLE);
	delay_us(10);
	STATE_RECEIVED = SPI_STATUS_READ(MARCSTATE);
	SPI_STROBE(SFTX);
	delay_us(10);
	STATE_RECEIVED = SPI_STATUS_READ(MARCSTATE);
	SPI_STROBE(SFRX);
	delay_us(10);
	STATE_RECEIVED = SPI_STATUS_READ(MARCSTATE);
	delay_us(50);
	
	/*while(1)
	{
		
		DATA_RECEIVED = 0x00;
		DATA_RECEIVED = SPI_STATUS_READ(TXBYTES);
		SPI_REG_WRITE(TXFIFO_single, RF_DATA_len);
		SPI_REG_WRITE(TXFIFO_single, 0x67);
		for(i = 0; i < 3; i++)
		{
			SPI_REG_WRITE(TXFIFO_single, RF_DATA[i]);
			DATA_RECEIVED = SPI_STATUS_READ(TXBYTES);
		}
		SPI_STROBE(STX);
		STATE_RECEIVED = SPI_STATUS_READ(MARCSTATE);
		DATA_RECEIVED = SPI_STATUS_READ(TXBYTES);
		delay(255);
		delay(255);
		delay(255);
				
	}*/
	/*while(1)
	{
		RFSend(RF_DATA, RF_DATA_len, RF_DATA_ADDR);
		delay(255);
		delay(255);
	}*/
	
	
//Datenempfang mit IOCFG0 = 0x06;
/*
	while(1)
	{
		Received_DATA_len = 0x00;							//L�sche Variable f�r Packetl�nge
		delay(10);
		SPI_STROBE(SRX);								//Befehl zum Empfangen
		//delay(255);									//Warte bis Calibrierung beendet
		
		printf_lcd(0, 1, "Start Polling", 1);						//Starte SPI Polling des PKTSTATUS registers
		while(!(((STATE_RECEIVED = SPI_STATUS_READ(PKTSTATUS)) & GDO0) == GDO0));	//Sync Word empfangen?	GDO0 asserts (goes high)
		printf_lcd(0, 1, "Sync received!", 1);
		delay(10);
		
		while((((STATE_RECEIVED = SPI_STATUS_READ(PKTSTATUS)) & GDO0) == GDO0));	//Vollst�ndiges Packet empfangen? GDO0 de-asserts (goes low)
		printf_lcd(0, 1, "Packet received!", 1);
		delay(100);
		
		status = SPI_STATUS_READ(PKTSTATUS);
		printf_lcd(0, 1, "Packet Status:", 1);
		binary_print_lcd(status);
		delay(100);

		RX_BYTES = SPI_STATUS_READ(RXBYTES);
		binary_print_lcd(RX_BYTES);
		delay(100);

		if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == 0)
		{
			printf_lcd(0, 1, "FIFO empty!!", 1);
		}
		else
		{
			Received_DATA_len = SPI_REG_READ(FIFO);				//Packetl�nge == 1.Byte im RXFIFO 
			printf_lcd(0, 1, "Length received!", 1);
			binary_print_lcd(Received_DATA_len);
			delay(100);

			if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == 0)
			{
				printf_lcd(0, 1, "FIFO empty!!", 1);
				delay(100);
			}
			else if(SPI_STATUS_READ(MARCSTATE) == RX_FIFO_OVERFLOW)				//Pr�fe MARCSTATE Register auf RXFIFO �berlauf
			{
				SPI_STROBE(SIDLE);
				SPI_STROBE(SFRX);
				status = RX_FIFO_OVERFLOW;
				printf_lcd(0, 1, "State: RX Overflow", 1);
				delay_us(10);
			}
			else if((Received_DATA_len == 0)||(Received_DATA_len > 61))			//Pr�fe, ob L�nge == 0 und/oder gr��er als zul�ssige L�nge
			{
				SPI_STROBE(SIDLE);
				SPI_STROBE(SFRX);
				status = RX_LENGTH_VIOLATION;
				printf_lcd(0, 1, "Wrong length!", 1);
				delay_us(10);
			}
			else
			{
				while(!((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == Received_DATA_len));
			
				for(i = 0; i < Received_DATA_len ; i++)
				{
					
					Received_DATA[i] = SPI_REG_READ(FIFO);				//Lese Daten aus RX FIFO
				
				}
				printf_lcd(0, 1, "Data received!", 1);
				delay(100);
			
				for(i = 0; i < 2; i++)
				{
					status_bytes[i] = SPI_REG_READ(FIFO);				//Lese CRC, RSSI status bytes
					delay_us(10);
				}
				printf_lcd(0, 1, "Status received!", 1);
			
				if(!((status_bytes[1]) & 0x80) == 0x80)
				{
					status = RX_CRCMISMATCH;					//CRC falsch
					printf_lcd(2, 2, "CRC wrong!", 1);
					delay(100);
				}
				else
				{
					status = RX_OK;
					printf_lcd(0, 1, "State ok!", 1);
					for(i = 0; i < Received_DATA_len; i++)
					{
						binary_print_lcd(Received_DATA[i]);			//Ausgabe der RX Daten auf dem LCD
						delay(255);
						delay(255);
						if(i == (Received_DATA_len - 1))
						{
							printf_lcd(2, 2, "FIFO empty", 1);
							delay(255);
						}
					}

					printf_lcd(2, 2, "RX done!", 1);				//Ende des Datenempfangs
				}
			}

		}
		SPI_STROBE(SFRX);								//L�sche RXFIFO
	}
*/

//Datenempfang mit IOCFG0 = 0x07;
/*

	while(1)
	{
		//SPI_STROBE(SFRX);								//L�sche RXFIFO
		Received_DATA_len = 0x00;						//L�sche Variable f�r Packetl�nge
		delay(10);
		SPI_STROBE(SRX);								//Befehl zum Empfangen
		//delay(255);									//Warte bis Calibrierung beendet
		count = 0;
		
		printf_lcd(0, 1, "Start Polling", 1);			//Starte SPI Polling des PKTSTATUS registers
		while(!(((STATE_RECEIVED = SPI_STATUS_READ(PKTSTATUS)) & GDO0) == GDO0))	//Packet mit CRC ok empfangen?
		{
			printf_lcd(0, 1, "Polling!", 1);
			count++;					//Z�hler bis 10, um Timeout zu verhindern
			if(count == 50)
			{
				SPI_STROBE(SRX);
				printf_lcd(0, 1, "TimeOut!", 1);
				count = 0;
			}
		}
				
		printf_lcd(0, 1, "Packet received!", 1);
		delay(100);
		
		status = SPI_STATUS_READ(PKTSTATUS);
		printf_lcd(0, 1, "Packet Status:", 1);
		binary_print_lcd(status);
		delay(100);

		RX_BYTES = SPI_STATUS_READ(RXBYTES);
		printf_lcd(0, 1, "RX FIFO Bytes:", 1);
		binary_print_lcd(RX_BYTES);
		delay(100);

		if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == 0)
		{
			printf_lcd(0, 1, "FIFO empty!!", 1);
		}
		else
		{
			Received_DATA_len = SPI_REG_READ(FIFO);				//Packetl�nge == 1.Byte im RXFIFO 
			printf_lcd(0, 1, "Length received!", 1);
			binary_print_lcd(Received_DATA_len);
			delay(100);

			if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == 0)
			{
				printf_lcd(0, 1, "FIFO empty!!", 1);
				delay(100);
			}
			else if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) < Received_DATA_len)
			{
				printf_lcd(0, 1, "Length Mismatch", 1);
				delay(100);				
			}
			else if(SPI_STATUS_READ(MARCSTATE) == RX_FIFO_OVERFLOW)				//Pr�fe MARCSTATE Register auf RXFIFO �berlauf
			{
				SPI_STROBE(SIDLE);
				SPI_STROBE(SFRX);
				status = RX_FIFO_OVERFLOW;
				printf_lcd(0, 1, "State: RX Overflow", 1);
				delay_us(10);
			}
			else if((Received_DATA_len == 0)||(Received_DATA_len > 61))			//Pr�fe, ob L�nge == 0 und/oder gr��er als zul�ssige L�nge
			{
				SPI_STROBE(SIDLE);
				SPI_STROBE(SFRX);
				status = RX_LENGTH_VIOLATION;
				printf_lcd(0, 1, "Wrong length!", 1);
				delay_us(10);
			}
			else
			{
				x = Received_DATA_len;
				y = x + 2;
				z = y - 1;
				while(!((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == y));
			
				for(i = 0; i < x ; i++)
				{
					
					Received_DATA[i] = SPI_REG_READ(FIFO);				//Lese Daten aus RX FIFO
				}
				printf_lcd(0, 1, "Data received!", 1);
				delay(100);
			
				for(i = 0; i < 2; i++)
				{
					status_bytes[i] = SPI_REG_READ(FIFO);				//Lese CRC, RSSI status bytes
				}
				printf_lcd(0, 1, "Status received!", 1);
			
				if(!((status_bytes[1]) & 0x80) == 0x80)
				{
					status = RX_CRCMISMATCH;					//CRC falsch
					printf_lcd(2, 2, "CRC wrong!", 1);
					delay(100);
				}
				else
				{
					status = RX_OK;
					printf_lcd(0, 1, "State ok!", 1);
					for(i = 0; i < y; i++)
					{
						if(i < x)
						{
							binary_print_lcd(Received_DATA[i]);			//Ausgabe der RX Daten auf dem LCD
							delay(255);
						}
						else
						{
							binary_print_lcd(status_bytes[i]);
							delay(255);
							if(i == z)
							{
								printf_lcd(2, 2, "FIFO empty", 1);
								delay(255);
							}
						}
					}
					printf_lcd(2, 2, "RX done!", 1);				//Ende des Datenempfangs
				}
			}

		}

	}*/

//Datenempfang mit fester Packetl�nge
	while(1)
	{
		//SPI_STROBE(SFRX);								//L�sche RXFIFO
		Received_DATA_len = 0x00;						//L�sche Variable f�r Packetl�nge
		delay(10);
		SPI_STROBE(SRX);								//Befehl zum Empfangen
		//delay(255);									//Warte bis Calibrierung beendet
		count = 0;
		
		printf_lcd(0, 1, "Start Polling", 1);			//Starte SPI Polling des PKTSTATUS registers
		while(!(((STATE_RECEIVED = SPI_STATUS_READ(PKTSTATUS)) & GDO0) == GDO0))	//Packet mit CRC ok empfangen?
		{
			printf_lcd(0, 1, "Polling!", 1);
			count++;					//Z�hler bis 10, um Timeout zu verhindern
			if(count == 50)
			{
				SPI_STROBE(SRX);
				printf_lcd(0, 1, "TimeOut!", 1);
				count = 0;
			}
		}
				
		printf_lcd(0, 1, "Packet received!", 1);
		delay(100);
		
		status = SPI_STATUS_READ(PKTSTATUS);
		printf_lcd(0, 1, "Packet Status:", 1);
		binary_print_lcd(status);
		delay(100);

		RX_BYTES = SPI_STATUS_READ(RXBYTES);
		printf_lcd(0, 1, "RX FIFO Bytes:", 1);
		binary_print_lcd(RX_BYTES);
		delay(100);

		if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == 0)
		{
			printf_lcd(0, 1, "FIFO empty!!", 1);
		}
		else
		{
			Received_DATA_len = 5;				//Packetl�nge == 1.Byte im RXFIFO 
			printf_lcd(0, 1, "Fixed Length!", 1);
			binary_print_lcd(Received_DATA_len);
			delay(100);

			if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == 0)
			{
				printf_lcd(0, 1, "FIFO empty!!", 1);
				delay(100);
			}
			else if((RX_BYTES = SPI_STATUS_READ(RXBYTES)) < Received_DATA_len)
			{
				printf_lcd(0, 1, "Length Mismatch", 1);
				delay(100);				
			}
			else if(SPI_STATUS_READ(MARCSTATE) == RX_FIFO_OVERFLOW)				//Pr�fe MARCSTATE Register auf RXFIFO �berlauf
			{
				SPI_STROBE(SIDLE);
				SPI_STROBE(SFRX);
				status = RX_FIFO_OVERFLOW;
				printf_lcd(0, 1, "State: RX Overflow", 1);
				delay_us(10);
			}
			else if((Received_DATA_len == 0)||(Received_DATA_len > 61))			//Pr�fe, ob L�nge == 0 und/oder gr��er als zul�ssige L�nge
			{
				SPI_STROBE(SIDLE);
				SPI_STROBE(SFRX);
				status = RX_LENGTH_VIOLATION;
				printf_lcd(0, 1, "Wrong length!", 1);
				delay_us(10);
			}
			else
			{
				x = Received_DATA_len;
				y = x + 2;
				z = y - 1;
				while(!((RX_BYTES = SPI_STATUS_READ(RXBYTES)) == y));
			
				for(i = 0; i < x ; i++)
				{
					
					Received_DATA[i] = SPI_REG_READ(FIFO);				//Lese Daten aus RX FIFO
				}
				printf_lcd(0, 1, "Data received!", 1);
				delay(100);
			
				for(i = 0; i < 2; i++)
				{
					status_bytes[i] = SPI_REG_READ(FIFO);				//Lese CRC, RSSI status bytes
				}
				printf_lcd(0, 1, "Status received!", 1);
			
				if(!((status_bytes[1]) & 0x80) == 0x80)
				{
					status = RX_CRCMISMATCH;					//CRC falsch
					printf_lcd(2, 2, "CRC wrong!", 1);
					delay(100);
				}
				else
				{
					status = RX_OK;
					printf_lcd(0, 1, "State ok!", 1);
					for(i = 0; i < y; i++)
					{
						if(i < x)
						{
							binary_print_lcd(Received_DATA[i]);			//Ausgabe der RX Daten auf dem LCD
							delay(255);
						}
						else
						{
							binary_print_lcd(status_bytes[i]);
							delay(255);
							if(i == z)
							{
								printf_lcd(2, 2, "FIFO empty", 1);
								delay(255);
							}
						}
					}
					printf_lcd(2, 2, "RX done!", 1);				//Ende des Datenempfangs
				}
			}

		}

	}


}


void SPI_REG_WRITE(char tx_addr, char tx_data)
{
	P4OUT &= ~CS;							//CS = low
	while(P4IN & SPI_SOMI);					//Warte bis SO = low
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis U1TXBUF leer ist (UTXIFG1 = 1)
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	//IFG2 &= ~UTXIFG1;						//L�sche TX-Flag vom vorherigen Byte
	U1TXBUF = tx_addr;						//Registeraddresse senden
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis UTXBUF leer ist (UTXIFG1 = 1)
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte)empfangen wurde
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	//IFG2 &= ~UTXIFG1;						//L�sche TX-Flag vom vorherigen Byte
	U1TXBUF = tx_data;						//Daten senden
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte) empfangen wurde										
	P4OUT |= CS;							//CS = high zur �bernahme der Daten
}	
		
char SPI_REG_READ(char reg_addr)
{
	char rx_data;
	
	P4OUT &= ~CS;							//CS = low
	while(P4IN & SPI_SOMI);					//Warte bis SO = low
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis U1TXBUF leer ist (UTXIFG1 = 1)
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	U1TXBUF = (reg_addr | RWbit);			//Sende Adresse + R/W bit = 1 f�r Lesezugriff
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis UTXBUF leer ist (UTXIFG1 = 1)
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte)empfangen wurde
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	U1TXBUF = 0x00;							//Sende Dummybits zum Lesezugriff
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte) empfangen wurde
	rx_data = U1RXBUF;						//Lese Daten aus Register
	P4OUT |= CS;							//CS = high zur �bernahme der Daten
	return rx_data;
}	
		
void SPI_SETUP(void)
{
	P4SEL |= 0x38;							//P4.3 - P4.5 peripheral modul
	P4DIR |= CS;							//P4.2 output (CS)
	P4OUT |= CS;							//CS high
	U1CTL |= SWRST;
	U1CTL = CHAR + SYNC + MM;				//8-bit + SPI mode + USART master + SWRST enabled
	U1TCTL = SSEL1 + STC;					//Source select SMCLK, 3-wire
	U1BR0 = 0x02;
	U1BR1 = 0x00;							//SPICLK = SMCLK / (U1BR0 + U1BR1) = SMCLK/2
	U1MCTL = 0x00;							//Modulation control register wird im SPI Modus nicht benutzt
	ME2 |= USPIE1;							//USART1 SPI enable
	U1CTL &= ~SWRST;						//SPI enable
	IE2 |= URXIE1 + UTXIE1;							//Receive interrupt enable
}	

void CC1101_RST(void)
{
	P4OUT &= ~CS;							//CS = low
	delay_us(5);
	P4OUT |= CS;							//CS high
	delay_us(35);
	P4OUT &= ~CS;							//CS = low
	//while(P4IN & SPI_SOMI);					//Warte bis SO = low		
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis UTXBUF leer ist (UTXIFG1 = 1)
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	U1TXBUF = SRES;							//Strobe command f�r Chip Reset
	while(!(IFG2 & URXIFG1));				//Warte bis ein vollst�ndiges Wort (hier: SO status byte) empfangen wurde
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	while(P4IN & SPI_SOMI);					//Warte bis SO = low
	P4OUT |= CS;							//CS high
}

void SPI_STROBE(char strobe)
{
	P4OUT &= ~CS;							//CS = low
	while(P4IN & SPI_SOMI);					//Warte bis SO = low
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis U1TXBUF leer ist (UTXIFG1 = 1)
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	//IFG2 &= ~UTXIFG1;						//L�sche TX-Flag vom vorherigen Byte
	U1TXBUF = strobe;						//Registeraddresse senden
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis UTXBUF leer ist (UTXIFG1 = 1)
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte)empfangen wurde
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte				
	P4OUT |= CS;							//CS = high zur �bernahme der Daten
}	

void SPI_REG_WRITE_BURST(char tx_addr, char *tx_buffer, char count)
{
	int i;
	P4OUT &= ~CS;							//CS = low
	while(P4IN & SPI_SOMI);					//Warte bis SO = low
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis U1TXBUF leer ist (UTXIFG1 = 1)
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	//IFG2 &= ~UTXIFG1;						//L�sche TX-Flag vom vorherigen Byte
	U1TXBUF = (tx_addr | BURST);			//Registeraddresse senden + Burst bit
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis UTXBUF leer ist (UTXIFG1 = 1)
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte)empfangen wurde
	for(i = 0; i < count; i++)
	{
		U1TXBUF = tx_buffer[i];
		while(!(IFG2 & UTXIFG1));
		while(!(IFG2 & URXIFG1));
		IFG2 &= ~URXIFG1;
	}
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	//IFG2 &= ~UTXIFG1;						//L�sche TX-Flag vom vorherigen Byte
	//U1TXBUF = 0;						//Daten senden
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte) empfangen wurde										
	P4OUT |= CS;							//CS = high zur �bernahme der Daten
}	


void RFSend(char *tx_buffer, char length, char address)
{
	int i;
	int k;
	k = length - 1;
	SPI_REG_WRITE(FIFO, length); //L�nge des Packets + Addresse (optional)
	SPI_REG_WRITE(FIFO, address);
	for(i = 0; i < k; i++)
	{
		SPI_REG_WRITE(FIFO, tx_buffer[i]);
	}
	SPI_STROBE(STX);
	delay(255);
}


char SPI_STATUS_READ(char reg_addr)
{
	char rx_data;
	
	P4OUT &= ~CS;							//CS = low
	while(P4IN & SPI_SOMI);					//Warte bis SO = low
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis U1TXBUF leer ist (UTXIFG1 = 1)
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	U1TXBUF = (reg_addr | RWbit | BURST);			//Sende Adresse + R/W bit = 1 f�r Lesezugriff
	while(!(IFG2 & UTXIFG1));				//Warteschleife bis UTXBUF leer ist (UTXIFG1 = 1)
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte)empfangen wurde
	IFG2 &= ~URXIFG1;						//L�sche RX-Flag vom vorherigen Byte
	U1TXBUF = 0x00;							//Sende Dummybits zum Lesezugriff
	while(!(IFG2 & URXIFG1));				//Warteschleife bis ein vollst�ndiges Wort (hier: SO status byte) empfangen wurde
	rx_data = U1RXBUF;						//Lese Daten aus Register
	P4OUT |= CS;							//CS = high zur �bernahme der Daten
	return rx_data;
}	

void binary_print_lcd(char buffer)
{
	int i;
	int wert;
	char ausgabe[9];
	for(i=0;i<8;i++)
	{
		wert=((buffer>>i)&1);
		if(wert == 0)
		{
			ausgabe[7-i] = '0';
		}
		else
		{
			ausgabe[7-i] = '1';
		}
	}
	ausgabe[8] = '\0';
	printf_lcd(2, 2, ausgabe, 1);
}

#ifndef SPI_H_
#define SPI_H_


#define SPI_SOMI 0x10
#define SPI_SIMO 0x08
#define SPI_CLK 0x20
#define CS 0x04


#define RWbit 0x80
#define BURST 0x40

#define RX_OK 0x00
#define RX_LENGTH_VIOLATION 0x01
#define RX_CRCMISMATCH 0x10
#define RX_FIFO_OVERFLOW 0x11

#define GDO0 0x01

//CC1101 Power Settings
#define PATABLE 0x3E

//Status Register
#define TXBYTES 0x3A
#define RXBYTES 0x3B
#define MARCSTATE 0x35
#define PKTSTATUS 0x38

//CC1101 Configuration Registers
#define IOCFG2 0x00			//GDO2 Output Pin Configuration
#define IOCFG0 0x02			//GDO0 Output Pin Configuration
#define PKTCTRL1 0x07			//Packet Automation Control
#define PKTCTRL0 0x08			//Packet Automation Control
#define ADDR 0x09			//Device Adress
#define PKTLEN 0x06			//Packet lenght
#define FSCTRL1 0x0B			//Frequency Synthesizer Control
#define FREQ2 0x0D			//Frequency Control Word, High Byte
#define FREQ1 0x0E			//Frequency Control Word, Middle Byte
#define MDMCFG4 0x10			//Modem Configuration
#define MDMCFG3 0x11			//Modem Configuration
#define MDMCFG2 0x12			//Modem Configuration
#define MDMCFG1 0x13			//Modem Configuration
#define MDMCFG0 0x14			//Modem Configuration
#define DEVIATN 0x15			//Modem Deviation Setting
#define MCSM1 0x17			//Main RadioControl State Machine Configuration
#define MCSM0 0x18			//Main RadioControl State Machine Configuration
#define FOCCFG 0x19			//Frequency Offset Compensation Configuration
#define WORCTRL 0x20			//Wake On Radio Control
#define FREND0 0x22			//Front End TX Configuration
#define FSCAL3 0x23			//Frequency Synthesizer Calibration
#define FSCAL2 0x24			//Frequency Synthesizer Calibration
#define FSCAL1 0x25			//Frequency Synthesizer Calibration
#define FSCAL0 0x26			//Frequency Synthesizer Calibration
#define TEST2 0x2C			//Various Test Settings
#define TEST1 0x2D			//Various Test Settings

//CC1101 RF settings f = 403,5 MHz
#define IOCFG2_DATA 0x04		//GDO2 Output Pin Configuration 0x06
#define IOCFG0_DATA 0x07		//GDO0 Output Pin Configuration 0x06
#define PKTCTRL1_DATA 0x04		//Packet Automation Control 0x04
#define PKTCTRL0_DATA 0x04		//Packet Automation Control 0x05
#define ADDR_DATA 0x67			//Device Adress 0x67
#define FSCTRL1_DATA 0x06		//Frequency Synthesizer Control
#define FREQ2_DATA 0x0F			//Frequency Control Word, High Byte
#define FREQ1_DATA 0x84			//Frequency Control Word, Middle Byte
#define MDMCFG4_DATA 0x05//0x0B		//Modem Configuration
#define MDMCFG3_DATA 0x43//0xF8		//Modem Configuration
#define MDMCFG2_DATA 0x03		//Modem Configuration //0x73: MSK //0x33: ASK/OOK //0x03: 2FSK	
#define MDMCFG1_DATA 0x22		//Modem Configuration
#define MDMCFG0_DATA 0x7A		//Modem Configuration
#define DEVIATN_DATA 0x15		//Modem Deviation Setting
#define MCSM1_DATA 0x30 		//Main RadioControl State Machine Configuration //0x30: after TX go to IDLE mode //0x32: after TX stay in TX mode			
#define MCSM0_DATA 0x18			//Main RadioControl State Machine Configuration
#define FOCCFG_DATA 0x16		//Frequency Offset Compensation Configuration
#define WORCTRL_DATA 0xFB		//Wake On Radio Control
#define FREND0_DATA 0x10		//0x10 MSK/2FSK 0x11 ASK/OOK		//Front End TX Configuration
#define FSCAL3_DATA 0xEA		//Frequency Synthesizer Calibration
#define FSCAL2_DATA 0x2A		//Frequency Synthesizer Calibration
#define FSCAL1_DATA 0x00		//Frequency Synthesizer Calibration
#define FSCAL0_DATA 0x1F		//Frequency Synthesizer Calibration
#define TEST2_DATA 0x81			//Various Test Settings
#define TEST1_DATA 0x35			//Various Test Settings


//CC1101 command strobes
#define SRES 0x30				//Chip Reset
#define SFSTXON 0x31			//Enable and calibrate frequency synthesizer
#define SXOFF 0x32				//Turn Off OSC
#define SCAL 0x33				//Calibrate frequency synthesizer
#define SRX 0x34				//Enable RX
#define STX 0x35				//Enable TX
#define SIDLE 0x36				//Exit RX/TX, go in idle mode
#define SWOR 0x38				//Start automatic polling sequence
#define SPWD 0x39				//Enter power down mode
#define SFRX 0x3A				//Flush RX FIFO
#define SFTX 0x3B				//Flush TX FIFO
#define SWORRST 0x3C			//Reset real time clock
#define SNOP 0x3D				//no operation
#define MARCSTATE 0x35

//RX/TX FIFO access - Header bytes
#define FIFO 0x3F
//#define TXFIFO_single 0x3F
//#define TXFIFO_burst 0x7F
//#define RXFIFO_single 0xBF
//#define RXFIFO_burst 0xFF


//SPI Funktionen
void SPI_SETUP(void);
void SPI_REG_WRITE(char tx_addr, char tx_data);
void SPI_REG_WRITE_BURST(char tx_addr, char *tx_buffer, char count);
char SPI_REG_READ(char reg_addr);
void SPI_STROBE(char strobe);
char SPI_STATUS_READ(char reg_addr);


//Reset CC1101
void CC1101_RST(void);

//Senden
void RFSend(char *tx_buffer, char length, char address);
void RFSendPacket(char *txBuffer, char size);
void TI_CC_Wait(unsigned int cycles);
void writeRFSettings(void);

void binary_print_lcd(char buffer);

#endif /*SPI_H_*/