
Kod: Zaznacz cały
#include <io2313v.h>
#include <macros.h>
#include "cc1000.h"
#pragma interrupt_handler ObslugaPrzerwania_int0: iv_INT0
#define ROZMIAR_NAGLOWKA 4 // 4 bytes header
#define ROZMIAR_BUFORA_TX 32 // Size (in bytes) of transmit buffer
#define ROZMIAR_BUFORA_RX 32 // Size (in bytes) of receive ring-buffer
#define DLUGOSC_PREAMBULY 4 // Number of bytes of preamble to send */
#define BITY_PREAMBULY_WYMAGANE 4 /* Number of bits required in addition to */
/* the initial 8 bits for the preamble to be */
/* accepted */
#define ZNACZNIK1 0x33 /* First byte of unique identifier */
#define ZNACZNIK2 0xCC /* Second byte of unique identifier */
#define FALSZ 0
#define PRAWDA (!FALSZ)
#define ON PRAWDA
#define OFF FALSZ
char RejestrDanych;
volatile char BuforTX[ROZMIAR_BUFORA_TX];
volatile char BuforRX[ROZMIAR_BUFORA_RX];
// Index pointers for use with buffers
volatile char LicznikBuforaTX;
char LicznikOdczytuBuforaRX;
volatile char LicznikZapisuBuforaRX;
// Counter variables
char LiczbaPreambul;
char BladPreambuly;
char LicznikBajtow;
char LicznikBitow;
char k_nad=0;
volatile char LiczbaBajtowDoWyslania;
volatile char LiczbaBajtowDoOdebrania;
// State variable stores the current state of the state machine
enum TypStanu {NADAWANIE=0,ODBIOR=1,BEZCZYNNY=2} Stan;
// This variable stores the state to switch to
// It is updated by the interrupt routine, while the main program
// does the actual state switch
volatile enum TypStanu NastepnyStan;
// This struct stores various flags in a space-efficient manner
//struct {
//unsigned PreambleFound:1,ZNACZNIK1Found:1,LastPreambleBit:1,LockAverage:1,UnlockAverage:1;} flagi;
volatile unsigned char PreambulaZnaleziona;
// This routine initialises the TX buffer at startup
void PrzygotowanieBuforaTX(void)
{
char i;
// Put preamble into buffer
for (i=0;i<DLUGOSC_PREAMBULY;i++) {
BuforTX[i]=0xAA;
}
BuforTX[DLUGOSC_PREAMBULY]=ZNACZNIK1; // First byte of unique identifier
BuforTX[DLUGOSC_PREAMBULY+1]=ZNACZNIK2; // Second byte of unique identifier
BuforTX[DLUGOSC_PREAMBULY+2]=0x00; // Unit address
BuforTX[DLUGOSC_PREAMBULY+3]=0x00; // Default : no data
}
#define PALE 3 // PORTD, pin 3
#define PDATA 4 // PORTD, pin 4
#define PCLK 5 // PORTD, pin 5
#define DCLK 2 // PORTD, pin 2
#define DIO 6 // PORTD, pin 6
#define RTS 2 // PORTB, pin 1
#define CTS 1 // PORTB, pin 2
#define CAL_TIMEOUT 0xFF
#define LOCK_TIMEOUT 0xFF
/* Contents of CURRENT register for TX and RX, use SmartRF(R) Studio */
/* to find values for your application */
#define TX_CURRENT 0x81
#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 0x48
#define RX_PLL 0x48
#define PA_VALUE 0xFF
/****************************************************************************/
/* This routine sends new configuration data to the CC1000 */
/* Based on bit bashing (general I/O pin use) */
/****************************************************************************/
void ConfigureCC1000(char addr, char data) //short Configuration[])
{
char BitCounter;
//char WordCounter;
//short Data;
char adres;
char dana;
//PORTB&=~(1<<0); //(****)
PORTD|=(1<<PALE); //PALE=1
//for (WordCounter=0;WordCounter<Count;WordCounter+=2)
//{
//adres=adres_i_dane[WordCounter];
adres=addr;
adres=adres<<1;
//dana=adres_i_dane[WordCounter+1];
dana=data;
PORTD&=~(1<<PALE); // PALE=0
/* Send address bits */
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PORTD|=(1<<PCLK); // PCLK=1
if ((adres&0x80)==0) {
PORTD&=~(1<<PDATA); // PDATA=0
}
else {
PORTD|=(1<<PDATA); // PDATA=1
}
adres=adres<<1;
PORTD&=~(1<<PCLK); //PCLK=0;
}
/* Send read/write bit */
/* Ignore bit in data, always use 1 */
PORTD|=(1<<PCLK); //PCLK=1
PORTD|=(1<<PDATA); //PDATA=1
PORTD&=~(1<<PCLK); //PCLK=0
//Data=Data<<1;
PORTD|=(1<<PCLK); //PCLK=1
PORTD|=(1<<PALE); //PALE=1
/* Send data bits */
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PORTD|=(1<<PCLK); //PCLK=1
if ((dana&0x80)==0) {
PORTD&=~(1<<PDATA); // PDATA=0
}
else {
PORTD|=(1<<PDATA); // PDATA=1
}
dana=dana<<1;
PORTD&=~(1<<PCLK); //PCLK=0
}
PORTD|=(1<<PCLK); //PCLK=1
//} /* Finished with word */
}
/****************************************************************************/
/* This routine writes to a single CC1000 register */
/****************************************************************************/
void WriteToCC1000Register(char addr, char data)
{
//short val;
//val=(addr&0x7F)<<9 | (data&0xFF);
ConfigureCC1000(addr,data);
}
/****************************************************************************/
/* This routine writes to a single CC1000 register, with data and address */
/* given in the same variable */
/****************************************************************************/
/*
void WriteToCC1000RegisterWord(short addranddata)
{
ConfigureCC1000(1,&addranddata);
}
/****************************************************************************/
/* This routine reads from a single CC1000 register */
/****************************************************************************/
char ReadFromCC1000Register(char addr)
{
char BitCounter;
char Data;
char Debug;
//PORTB&=~(1<<0);//(****)
PORTD|=(1<<PALE); //PALE=1
Data=addr<<1;
PORTD&=~(1<<PALE);
/* Send address bits */
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PORTD|=(1<<PCLK); // PCLK=1
if ((Data&0x80)==0) {
PORTD&=~(1<<PDATA); // PDATA=0
}
else {
PORTD|=(1<<PDATA); // PDATA=1
}
Data=Data<<1;
PORTD&=~(1<<PCLK); //PCLK=0;
}
/* Send read/write bit */
/* Ignore bit in data, always use 0 */
PORTD|=(1<<PCLK); //PCLK=1
PORTD&=~(1<<PDATA); //PDATA=0
PORTD&=~(1<<PCLK); //PCLK=0
PORTD|=(1<<PCLK); //PCLK=1
PORTD|=(1<<PALE); //PALE=1
//PORTB|=(1<<0); //(****)
/* Receive data bits */
PORTD|=(1<<PDATA); //PDATA=1
DDRD&=~(1<<PDATA); /* Set up PDATA as an input */
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PORTD&=~(1<<PCLK); //PCLK=0
Data=Data<<1;
Debug=(1<<PDATA);
if ((PIND&Debug)==0) {
Data&=0xFE;
} else {
Data|=0x01;
}
PORTD|=(1<<PCLK); //PCLK=1
}
//PORTB&=~(1<<0);//(****)
DDRD|=(1<<PDATA); /* Set up PDATA as an output again */
return Data;
}
/****************************************************************************/
/* This routine resets the CC1000, clearing all registers. */
/****************************************************************************/
void ResetCC1000(void)
{
char MainValue;
MainValue=ReadFromCC1000Register(CC1000_MAIN);
WriteToCC1000Register(CC1000_MAIN,MainValue & 0xFE); // Reset CC1000
WriteToCC1000Register(CC1000_MAIN,MainValue | 0x01); // Bring CC1000 out of reset
}
/****************************************************************************/
/* This routine calibrates the CC1000 */
/* Returns 0 if calibration fails, non-zero otherwise. Checks the LOCK */
/* to check for success. */
/****************************************************************************/
char CalibrateCC1000(void)
{
unsigned char TimeOutCounter,j;
WriteToCC1000Register(CC1000_PA_POW,0x00); // Turn off PA to avoid spurs
// during calibration in TX mode
WriteToCC1000Register(CC1000_CAL,0xA6); // Start calibration
// Wait for calibration complete
for(TimeOutCounter=CAL_TIMEOUT,j=0; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); j++)
{
if (j==255){TimeOutCounter--;}
}
// Wait for lock
for(TimeOutCounter=LOCK_TIMEOUT,j=0; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(TimeOutCounter>0); j++)
{
if (j==255){TimeOutCounter--;}
}
WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); /* Restore PA setting */
return ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==1);
}
/****************************************************************************/
/* This routine puts the CC1000 into RX mode (from TX). When switching to */
/* RX from PD, use WakeupC1000ToRX first */
/****************************************************************************/
void SetupCC1000RX(char RXCurrent)
{
unsigned char i,j;
//char lock_status;
WriteToCC1000Register(CC1000_MAIN,0x11); // Switch into RX, switch to freq. reg A
WriteToCC1000Register(CC1000_PLL,RX_PLL); // Use RX refdiv setting
WriteToCC1000Register(CC1000_CURRENT,RXCurrent); // Program VCO current for RX
// Wait 250us before monitoring LOCK
for (i=0;i<4;i++) { for(j=0;j<205;j++);}
// Wait for lock
/*for(i=LOCK_TIMEOUT,j=0; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(i>0); j++)
{
if (j==255){i--;}
}
/*
// If PLL in lock
if ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x01){
// Indicate PLL in LOCK
lock_status = LOCK_OK;
// Else (PLL out of LOCK)
}else{
// If recalibration ok
if(CalibrateCC1000()){
// Indicate PLL in LOCK
lock_status = LOCK_RECAL_OK;
// Else (recalibration failed)
}else{
// Reset frequency syncthesizer (ref.: Errata Note 01)
ResetFreqSynth();
// Indicate PLL out of LOCK
lock_status = LOCK_NOK;
}
}
// Return LOCK status to application
return (lock_status);*/
}
/****************************************************************************/
/* This routine puts the CC1000 into TX mode (from RX). When switching to */
/* TX from PD, use WakeupCC1000ToTX first */
/****************************************************************************/
void SetupCC1000TX(char TXCurrent)
{
unsigned char i,j;
//char lock_status;
WriteToCC1000Register(CC1000_PA_POW,0x00); // Turn off PA to avoid frequency splatter
WriteToCC1000Register(CC1000_MAIN,0xE1); // Switch into TX, switch to freq. reg B
WriteToCC1000Register(CC1000_PLL,TX_PLL); // Use TX refdiv setting
WriteToCC1000Register(CC1000_CURRENT,TXCurrent); // Program VCO current for TX
// Wait 250us before monitoring LOCK
for (i=0;i<4;i++) { for(j=0;j<205;j++);}
// Wait for lock
//for(i=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(i>0); i--);
/*for(i=LOCK_TIMEOUT,j=0; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(i>0); j++)
{
if (j==255){i--;}
}
/*
// If PLL in lock
if ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x01){
// Indicate PLL in LOCK
lock_status = LOCK_OK;
// Else (PLL out of LOCK)
}else{
// If recalibration ok
if(CalibrateCC1000()){
// Indicate PLL in LOCK
lock_status = LOCK_RECAL_OK;
// Else (recalibration failed)
}else{
// Reset frequency syncthesizer (ref.: Errata Note 01)
ResetFreqSynth();
// Indicate PLL out of LOCK
lock_status = LOCK_NOK;
}
}
// Increase output power
*/
WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); // Restore PA setting
// Return LOCK status to application
//return (lock_status);*/
}
/****************************************************************************/
/* This routine puts the CC1000 into power down mode. Use WakeUpCC1000ToRX */
/* followed by SetupCC1000RX or WakeupCC1000ToTX followed by SetupCC1000TX */
/* to wake up from power down */
/****************************************************************************/
void SetupCC1000PD(void)
{
WriteToCC1000Register(CC1000_MAIN,0x3F); // Put CC1000 into power-down
WriteToCC1000Register(CC1000_PA_POW,0x00); // Turn off PA to minimise current draw
}
/****************************************************************************/
/* This routine wakes the CC1000 up from PD mode to RX mode, call */
/* SetupCC1000RX after this routine is finished. */
/****************************************************************************/
/*
void WakeUpCC1000ToRX(char RXCurrent)
{
int i;
WriteToCC1000Register(CC1000_MAIN,0x3B); // Turn on xtal oscillator core
WriteToCC1000Register(CC1000_CURRENT,RXCurrent); // Program VCO current for RX
WriteToCC1000Register(CC1000_PLL,RX_PLL); // Use RX refdiv setting
// Insert wait routine here, must wait for xtal oscillator to stabilise,
// typically takes 2-5ms.
for (i=0;i<8192;i++);
WriteToCC1000Register(CC1000_MAIN,0x39); // Turn on bias generator
// Wait for 250us, insert wait loop here
for (i=0;i<820;i++);
WriteToCC1000Register(CC1000_MAIN,0x31); // Turn on frequency synthesiser
}
/****************************************************************************/
/* This routine wakes the CC1000 up from PD mode to TX mode, call */
/* SetupCC1000TX after this routine is finished. */
/****************************************************************************/
void WakeUpCC1000ToTX(char TXCurrent)
{
unsigned char i,j;
WriteToCC1000Register(CC1000_MAIN,0xFB); // Turn on xtal oscillator core
WriteToCC1000Register(CC1000_CURRENT,TXCurrent); // Program VCO current for TX
WriteToCC1000Register(CC1000_PLL,TX_PLL); // Use TX refdiv setting
// Insert wait routine here, must wait for xtal oscillator to stabilise,
// typically takes 2-5ms.
for (i=0;i<64;i++) { for(j=0;j<255;j++);}
WriteToCC1000Register(CC1000_MAIN,0xF9); // Turn on bias generator
// Wait for 250us, insert wait loop here
for (i=0;i<4;i++) { for(j=0;j<205;j++);}
WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); // Turn on PA
WriteToCC1000Register(CC1000_MAIN,0xF1); // Turn on frequency synthesiser
}
/****************************************************************************/
/* This routine locks the averaging filter of the CC1000 */
/****************************************************************************/
/*
void AverageManualLockCC1000(void)
{
WriteToCC1000Register(CC1000_MODEM1,0x19);
}
/****************************************************************************/
/* This routine unlocks the averaging filter of the CC1000 */
/****************************************************************************/
/*
void AverageFreeRunCC1000(void)
{
WriteToCC1000Register(CC1000_MODEM1,0x09);
}
/****************************************************************************/
/* This routine sets up the averaging filter of the CC1000 for automatic */
/* lock. This can be used in polled receivers. */
/****************************************************************************/
/*
void AverageAutoLockCC1000(void)
{
WriteToCC1000Register(CC1000_MODEM1,0x01);
}
/****************************************************************************/
/* This routine reads the current calibration values from the CC1000 */
/****************************************************************************/
/*
void ReadCurrentCalibration(char *val1, char *val2)
{
*val1=ReadFromCC1000Register(CC1000_TEST0);
*val2=ReadFromCC1000Register(CC1000_TEST2);
}
/****************************************************************************/
/* This routine overrides the current calibration of the CC1000 */
/****************************************************************************/
/*
void OverrideCurrentCalibration(char val1, char val2)
{
WriteToCC1000Register(CC1000_TEST5,(val1&0x0F)|0x10);
WriteToCC1000Register(CC1000_TEST6,(val2&0x1F)|0x20);
}
/****************************************************************************/
/* This routine stops override of the CC1000 calibration values */
/****************************************************************************/
/*
void StopOverridingCalibration(void)
{
WriteToCC1000Register(CC1000_TEST5,0x00);
WriteToCC1000Register(CC1000_TEST6,0x00);
}
/****************************************************************************/
/* This CC1000 frequency synthesizer */
/****************************************************************************/
/*
void ResetFreqSynth(void)
{
char modem1_value;
modem1_value = ReadFromCC1000Register(CC1000_MODEM1)&~0x01;
WriteToCC1000Register(CC1000_MODEM1,modem1_value);
WriteToCC1000Register(CC1000_MODEM1,modem1_value|0x01);
}
/****************************************************************************/
//================================================================================
// This routine handles setup needed when changing states
void ZmienStan(void)
{
switch (NastepnyStan) {
case ODBIOR:
if (Stan==NADAWANIE) {
MCUCR = 0x03; /* INT on rising edge */
PORTD&=~(1<<DIO);
DDRD&=~(1<<DIO); /* Set DIO as input */
SetupCC1000RX(RX_CURRENT);
//PORTB|=(1<<0);//(****)
}
Stan=ODBIOR;
PORTB|=(1<<7);//SET_RXLED(ON);
PORTB&=~(1<<3);//SET_TXLED(OFF);
PORTB&=~(1<<5);
PORTB|=(1<<2); // READY=1; // HW Handshake : Not Ready
LicznikBitow=0;
LicznikBajtow=0;
break;
case NADAWANIE:
if (Stan!=NADAWANIE) {
//PORTB&=~(1<<0);//(****)
//CLI();
//GIMSK=0x00;
//MCUCR = 0x00;
MCUCR = 0x02;
//GIMSK=0x40; /* INT on falling edge */
//SEI();
DDRD|=(1<<DIO); /* Set DIO as output */
SetupCC1000TX(TX_CURRENT);
}
Stan=NADAWANIE;
PORTB&=~(1<<7);//SET_RXLED(OFF);
PORTB|=(1<<3); //SET_TXLED(ON);
PORTB&=~(1<<5);
//PORTB|=(1<<2); // READY=1; // HW Handshake : Not Ready
//UCR&=0x7F;//RXCIE=0; // Disable UART Interrupts
LiczbaBajtowDoWyslania=LicznikBuforaTX; // Number of bytes to send
BuforTX[DLUGOSC_PREAMBULY+3]=LiczbaBajtowDoWyslania-ROZMIAR_NAGLOWKA-DLUGOSC_PREAMBULY;
//BuforTX[DLUGOSC_PREAMBULY+3]=1; // (****)
LicznikBuforaTX=0;
LicznikBitow=0;
RejestrDanych=BuforTX[LicznikBuforaTX++];
//k_nad=0;
//while (k_nad==0);
break;
case BEZCZYNNY:
if (Stan==NADAWANIE) {
MCUCR = 0x03; /* INT on rising edge */
PORTD&=~(1<<DIO);
DDRD&=~(1<<DIO); /* Set DIO as input */
SetupCC1000RX(RX_CURRENT);
//PORTB|=(1<<0);//(****)
}
Stan=BEZCZYNNY;
PORTB&=~(1<<7);//SET_RXLED(OFF);
PORTB&=~(1<<3); //SET_TXLED(OFF);
PORTB|=(1<<5);
PORTB&=~(1<<2);// READY=0; // HW Handshake : Ready
//UCR|=0x80;//RCIE=1; // Enable UART Interrupts
LicznikBuforaTX=ROZMIAR_NAGLOWKA+DLUGOSC_PREAMBULY;
LiczbaPreambul=0;
BladPreambuly=0;
PreambulaZnaleziona=0;
//ZNACZNIK1Found=FALSZ;
break;
}
}
/*
void inicjalizacja(void)
{
unsigned char i;
DDRB = 0xff;
PORTB&=~(1<<CTS); // CTS=0
PORTB|=(1<<RTS);
DDRB&=~(1<<RTS);
CLI();
UCR = 0x00; //disable while setting baud rate
UBRR = 0x54; //set baud rate
UCR = 0x48; //enable
MCUCR = 0x03;
GIMSK = 0x00;
TIMSK = 0x00;
SEI(); //re-enable interrupts
}
*/
//================================================================================
void programujRejestryCC1000(char CURRENT,char PLL)
{
WriteToCC1000Register(CC1000_FREQ_2A,0x42);
WriteToCC1000Register(CC1000_FREQ_1A,0x20);
WriteToCC1000Register(CC1000_FREQ_0A,0x00);
WriteToCC1000Register(CC1000_FREQ_2B,0x42);
WriteToCC1000Register(CC1000_FREQ_1B,0x18);
WriteToCC1000Register(CC1000_FREQ_0B,0xE4);
WriteToCC1000Register(CC1000_FSEP1, 0x02);
WriteToCC1000Register(CC1000_FSEP0, 0x80);
WriteToCC1000Register(CC1000_CURRENT,CURRENT);
WriteToCC1000Register(CC1000_FRONT_END,0x12);
WriteToCC1000Register(CC1000_PA_POW, PA_VALUE);
WriteToCC1000Register(CC1000_PLL, PLL);
WriteToCC1000Register(CC1000_LOCK, 0x10);
WriteToCC1000Register(CC1000_CAL, 0x26);
WriteToCC1000Register(CC1000_MODEM2, 0x8E);
WriteToCC1000Register(CC1000_MODEM1, 0x69);
WriteToCC1000Register(CC1000_MODEM0, 0x27);
WriteToCC1000Register(CC1000_MATCH, 0x70);
WriteToCC1000Register(CC1000_FSCTRL, 0x01);
WriteToCC1000Register(0x1C,0x00);
WriteToCC1000Register(0x42,0x25);
}
void ObslugaPrzerwania_int0(void)
{
/* This function must execute as fast as possible. Therefore, as much processing as
possible is left to the main program */
switch (Stan) {
case NADAWANIE:
/* Write data to CC1000 */
if ((RejestrDanych&0x80)==0){PORTD&=~(1<<DIO);} else {PORTD|=(1<<DIO);}; //DIO=ShiftRegMSB;
RejestrDanych=RejestrDanych<<1;
LicznikBitow++;
if (LicznikBitow==1) {
if (LicznikBuforaTX>LiczbaBajtowDoWyslania) {
NastepnyStan=BEZCZYNNY;
//k_nad=1;
break;
}
}
if (LicznikBitow==8) {
LicznikBitow=0;
RejestrDanych=BuforTX[LicznikBuforaTX++];
}
break;
case ODBIOR:
/* Read data from CC1000 */
RejestrDanych=RejestrDanych<<1;
if ((PIND&(1<<DIO))==0){RejestrDanych|=0x01;} else {RejestrDanych&=0xFE;}//ShiftRegLSB=~DIO;
LicznikBitow++;
/* Byte received? */
if (LicznikBitow==8) {
LicznikBitow=0;
/* The three first bytes must be handled in a special manner */
switch (LicznikBajtow) {
case 0 : // First byte (second part of SOF)
if (RejestrDanych!=ZNACZNIK2)
NastepnyStan=BEZCZYNNY;
break;
case 1 : // Second byte is address
// Addressing not implemented
break;
case 2 : // Third byte is packet size, store this
LiczbaBajtowDoOdebrania=RejestrDanych;
if (LiczbaBajtowDoOdebrania>ROZMIAR_BUFORA_TX){ // If invalid length, ignore message
LiczbaBajtowDoOdebrania=0;}
break;
default : // Rest of the packet is data, store it in the receive buffer
BuforRX[LicznikZapisuBuforaRX]=RejestrDanych;
// Increase counter, wrap around when we've reached end of buffer
// LicznikZapisuBuforaRX=(LicznikZapisuBuforaRX+1)%ROZMIAR_BUFORA_RX;
LicznikZapisuBuforaRX++;
LicznikZapisuBuforaRX&=0x1F;
}
if (LicznikBajtow>=LiczbaBajtowDoOdebrania+2) {
//UnlockAverage=1;
NastepnyStan=BEZCZYNNY;
}
LicznikBajtow++;
}
break;
case BEZCZYNNY:
/* Read data from CC1000 */
RejestrDanych=RejestrDanych<<1;
if ((PIND&(1<<DIO))==0){RejestrDanych|=0x01;} else {RejestrDanych&=0xFE;} //ShiftRegLSB=~DIO; // Polarity must be inverted if using high-side LO
LicznikBitow++;
/* If preamble has been found */
if (PreambulaZnaleziona==1) {
/* Look for SOF/unique identifier */
if (RejestrDanych==ZNACZNIK1) {
// If SOF found, go into RX mode
NastepnyStan=ODBIOR;
}
/* Are we still receiving the preamble? */
else if ((RejestrDanych==0x55)||(RejestrDanych==0xAA)) {
; /* If so, do nothing */
}
/* If we are not receiving a correct preamble, declare an error */
else if (BladPreambuly==0) {
BladPreambuly++;
}
if (BladPreambuly>0)
/* Increase the error counter regardless of bits read if */
/* we have found en error */
BladPreambuly++;
/* Once an error condition has occurred, a correct SOF must be */
/* found within 9 bits (we increment by 2 at the first bit), */
/* otherwise we abort and start looking for the preamble again */
if (BladPreambuly>10) {
PreambulaZnaleziona=0;
// UnlockAverage=1;
}
}
/* If preamble has not been found */
else {
/* If valid preamble, increase counter */
if ((RejestrDanych==0x55)||(RejestrDanych==0xAA)) {
LiczbaPreambul++;
//PORTB^=(1<<6);
}
/* If not, reset counter */
else {
LiczbaPreambul=0;
}
/* If preamble requirement has been reached, declare that preamble */
/* has been found */
if (LiczbaPreambul>=BITY_PREAMBULY_WYMAGANE) {
PreambulaZnaleziona=1;
// LockAverage=1;
BladPreambuly=0;
}
}
break;
default:
// If something goes haywire, get back into a known state
NastepnyStan=BEZCZYNNY;
break;
}
//INTF=0;
}
//================================================================================
void putchar(char ch)
{
while(!(USR & (1<<UDRE))); /*TXIF==0 Wait for buffer to be empty */
UDR=ch;
}
//================================================================================
/*
#pragma interrupt_handler uart0_rx_isr:8
void uart0_rx_isr(void)
{
BuforTX[LicznikBuforaTX++]=UDR;
TCCR0 = 0x00; //stop timer
TCNT0 = 0x00; //set count
TCCR0 = 0x05; //start timer
//uart has received a character in UDR
}
*/
void main(void)
{
char dummy;
unsigned char i,j;
DDRB=0xFF;
//DDRD=0xFF;
PORTD=0x00;
DDRD|=(1<<PALE);
DDRD|=(1<<PDATA);
DDRD|=(1<<PCLK);
UCR = 0x00; //disable while setting baud rate
UBRR = 0x14; //set baud rate 3.2768MHz, 9600baud
UCR = 0x18; //enable
TCCR0 = 0x00; //stop timer
TCNT0 = 0x95; //set count
//TCCR0 = 0x05; //start timer
PORTD|=(1<<PALE); //PALE=1//PALE=1;
LicznikOdczytuBuforaRX=0;
LicznikZapisuBuforaRX=0;
SetupCC1000PD();
ResetCC1000();
for (i=0;i<64;i++) { for(j=0;j<255;j++);}
programujRejestryCC1000(TX_CURRENT,TX_PLL);
WakeUpCC1000ToTX(TX_CURRENT);
SetupCC1000TX(TX_CURRENT);
//MCUCR = 0x02; /* INT on falling edge */
//DDRD|=(1<<DIO); /* Set DIO as output */
CalibrateCC1000();
// Calibration data is stored in the chip indexed by the selected frequency register
programujRejestryCC1000(RX_CURRENT,RX_PLL);
SetupCC1000RX(RX_CURRENT);
//MCUCR = 0x03; /* INT on rising edge */
//DDRD&=~(1<<DIO); // Set DIO as input
CalibrateCC1000();
PORTB|=(1<<4);
// Now the CC1000 is calibrated for both RX and TX, we do not need to recalibrate
// unless the frequency is changed, the temperature changes by 40 degrees C
// or if the supply voltage changes by more than 0.5V
// Force update
Stan=NADAWANIE;
NastepnyStan=BEZCZYNNY;
PrzygotowanieBuforaTX();
// Set all buttons to light, if we want to turn them off, we set them as inputs to avoid
// the output being shorted to VDD if a button is pressed
/*
AWAKE=0;
SYNC=0;
*/
GIMSK = 0x40;
SEI();
while(1) {
/* If state change, handle it */
//PORTB^=(1<<6);
if (Stan!=NastepnyStan)
ZmienStan();
/* If data in receive buffer, write it to the serial port */
if (LicznikOdczytuBuforaRX!=LicznikZapisuBuforaRX) {
putchar(BuforRX[LicznikOdczytuBuforaRX]);
// Increase read index, wrap around when reached end of buffer
//LicznikOdczytuBuforaRX=(LicznikOdczytuBuforaRX+1)%ROZMIAR_BUFORA_RX;
LicznikOdczytuBuforaRX++;
LicznikOdczytuBuforaRX&=0x1F;
}
if ((USR & (1<<RXC))!=0) { //RCIF==1
// UART receive interrupt. PC has sent data to us.
//PORTB^=(1<<5);
if (Stan==BEZCZYNNY) { // Only handle data if idle
TCCR0 = 0x00; //stop timer
TCNT0 = 0x95; //set count
TCCR0 = 0x05; //start timer
BuforTX[LicznikBuforaTX++]=UDR;
// IMPORTANT : We may have another interrupt or two occur before we can change mode
// Therefore, leave safety margin!
if (LicznikBuforaTX>=(ROZMIAR_BUFORA_TX-3)) { // Change mode early to have safety margin
PORTB|=(1<<2); // READY=1; // HW Handshake : Not Ready
NastepnyStan=NADAWANIE;
}
//PORTB&=~(1<<5);
}
}
if ((TIFR&0x02)!=0) { //TMR2IF==1
// Timer 2 interrupt. TX timer has timed out.
TCCR0 = 0x00; //TMR2ON=0; // Turn off timer 2
NastepnyStan=NADAWANIE;
TIFR|=(1<<TOV0);//TMR2IF=0;
}
}
}