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_*/