*/ Gert van den Berg 7 Oktober 2006 - 21 November 2006 /* defines.h Verklarings vir CCS weergawe van CC1000 software Gert van den Berg 7 Oktober 2006 - 21 November 2006 */ // Algemene stuff - los meestal uit. Niks hier om te stel nie.... ////////////////////////////////////////////////////////////////// // Einde van niks om te stel ////////////////////////////////////////////////////////////////// // Stel config van CC1000 bordtjie ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // Los weer uit. Niks om te stel as bordjie onverandered is nie... // Pin declerations // Pins om CC1000 op te stel #define PDATA PORTB.F5 ///[[ Setup data ========= tris pin zameniti ============ #define PCLK PORTB.F3 /////[[ Setup clock #define PALE PORTB.F4 // Pin wat moet laag wees as adress gestuur word, hoog andersins // Pins vir data transfer #define DIO PORTB.F2 // Data IO pin ========= tris pin zameniti ============ #define DCLK PORTB.F1 // Data Clock Data Clock PORTC.F3 //#define SET_DATA_INPUT PORTB.F7=1 //#define SET_DATA_OUTPUT PORTB.F7=0 #define RSSI PORTA.F0 // ANALOG INPUT #define CH_OUT PORTB.F2 // av filter // CC1000 register address definitions #define CC1000_MAIN 0x00 #define CC1000_FREQ2A 0x01 #define CC1000_FREQ1A 0x02 #define CC1000_FREQ0A 0x03 #define CC1000_FREQ2B 0x04 #define CC1000_FREQ1B 0x05 #define CC1000_FREQ0B 0x06 #define CC1000_FSEP1 0x07 #define CC1000_FSEP0 0x08 #define CC1000_CURRENT 0x09 #define CC1000_FRONT_END 0x0A #define CC1000_POWER 0x0B #define CC1000_PLL 0x0C #define CC1000_LOCK 0x0D #define CC1000_CALIBRATE 0x0E #define CC1000_MODEM2 0x0F #define CC1000_MODEM1 0x10 #define CC1000_MODEM0 0x11 #define CC1000_MATCH 0x12 #define CC1000_FSCTRL 0x13 #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 // CC1000 State definitions #define STATE_RX 1 #define STATE_TX 2 #define STATE_NONE 3 ////////////////////////////////////////////////////////////////// // Begin hier stel ////////////////////////////////////////////////////////////////// ////////Change following regs to change cc1000 constants ////////according to SmartRF #define PA_POWER 0xFF #define DEF_PLL 0x48 // Defualt value #define RX_PLL 0x48 #define TX_PLL 0x48 #define DEF_CURRENT 0x44 // Defualt value #define RX_CURRENT 0x44 #define TX_CURRENT 0x81 // Frekwensie register waardes // Freq A: Vir RX #define FREQA2 0x41 #define FREQA1 0xF8 #define FREQA0 0x00 // Freq B: Vir TX #define FREQB2 0x41 #define FREQB1 0xFC #define FREQB0 0x9C /*#define FREQA2 0x42 #define FREQA1 0x24 #define FREQA0 0x9C // Freq B: Vir TX #define FREQB2 0x42 #define FREQB1 0x20 #define FREQB0 0x00 */ // Software level konstantes #define PREAMBLE 0xAA // Other settings // -------------- // Toestand waarvoor kode compile word #define STATE_DEFAULT STATE_TX // Default value - kan nogsteeds uit kode geswitch word // Debugging options //#define SHOWCODES 0 // Wys debug LEDs op PORTB #define SERIAL_DEBUG 0 // Wys debug info op Serie - Buffered serial nodig // Sit my serie kode aan en af #define USE_SERIAL_BUFFER 1 // Operating modes - kan onder gekies word watter een compile gaan word #define MODE_RUN 0 // Vir "production use" #define MODE_SERIALTEST 2 // Toets CC1000 met serial data. Byte op 'n slag #define MODE_LOCALSERIALTEST 3 // Toets serial kode plaaslik. Geen RF betrokke nie // Kies watter mode se kode word compile #define OPER_MODE MODE_RUN // Select mode here // Buffer sizes // CC1000 #define CCTX_BUFFSIZE 10 #define CCRX_BUFFSIZE 10 // Serial #if USE_SERIAL_BUFFER == 1 #define SERTX_BUFFSIZE 10 #define SERRX_BUFFSIZE 10 #endif // Stel packet size op #if OPER_MODE != MODE_SERIALTEST // vir ander modes // Verander na maksimum pakkiegrootte sonder pramble in BITS. Veelvoud van 8 #define BYTE_MODE_LENGTH 24 #endif #if OPER_MODE == MODE_SERIALTEST #define BYTE_MODE_LENGTH 16 // moenie vernader nie! #endif /* definicija komandi #define LEVA_STOPA PORTF.F1=0 #define DESNA_STOPA PORTF.F2=0 #define SMER_PUMPA_NAPRED PORTF.F3=0 #define SMER_PUMPA_NAZAD PORTF.F4=0 #define POVECANJE_GAS PORTF.F5=0 #define SMANJIVANJE_GAS PORTF.F6=0 #define SIRENA PORTF.F6=0 #define SIRENA_ON 0x01 #define SIRENA_OFF 0x02 */ /* Comments oor SmartRF studio: ---------------------------- Settings gebruik om register waardes uit te werk: Freq = 433.302 Mhz Top is set to RX, bottom to TX. Gekies volgens mode Optimal Freq = off RX Mode: Low LO Freq Seperation = 64KHz Data Rate: 2400 Baud Encoding Manchester, Fast Power: 10dBm Lock: Continious RSSI aan RX / TX Vir RX / TX is: Main = 11 / E1 Freq_A = 42:24:9c FReq_B = 42:20:00 FSEP = 02:80 Current = 44 / 81 FRONT_END = 12 PA_POW = FF PLL = 48 LOCK = 10 CAL = 26 MODEM2 = 8E MODEM1 = 69 MODEM0 = 27 MATCH = 70 FSCTRL = 01 PRESCALER = 00 */ //////////////////////////////////////////////////////////////////////// // Forward declarations of functions //////////////////////////////////////////////////////////////////////// //#inline void ShowCode(int8 code); void SetupPic(); void SetupCC1000(); void ConfigureCC1000(); void WriteCC1000Reg(unsigned short addr, unsigned short data); void WriteToCC1000RegisterWord(unsigned addranddata); unsigned short ReadCC1000Reg(unsigned short addr); void ResetCC1000(); unsigned short CalibrateCC1000(); unsigned short SetupCC1000TX(); unsigned short SetupCC1000RX(); void SetupCC1000PD(); void WakeCC1000TX(); void WakeCC1000RX(); void ChangeState(unsigned short state); unsigned short GetCC1000(); void PutCC1000(unsigned short data_to_put); /*****************************************************************************/ volatile unsigned short TxBuff[7]; //Transmit buffer volatile char TxW=0; //Write "pointer" for transmit buffer volatile char TxR=0; //Read "pointer" for transmit buffer volatile unsigned tim; unsigned acc,tmp; //unsigned short int data[6] = {2,3,0,5,0,10}; unsigned short C1, C2; //////////////////////////////////////////////////////////////////////// // Global variables //////////////////////////////////////////////////////////////////////// unsigned short CC1000_STATE; // Toestand van CC1000 // Transmission buffers unsigned short CCTX_BUFFER[CCTX_BUFFSIZE]; // CC1000 unsigned short CCTX_BUFFCOUNT; // Recieve buffers unsigned short CCRX_BUFFER[CCRX_BUFFSIZE]; unsigned short CCRX_BUFFCOUNT; unsigned short ByteModeBits; // Amount of bits remaining in ByteMode //unsigned short kyk, kyk2; // kyk: Is gecal vir TX?; kyk2: Is gecal vir RX? unsigned short temp; char LogicEqual(char a, char b) { //looks complicated, byt generates fast assembler code if(a) { if(b) { return 1; }else { return 0; } } else { if(b) { return 0; } else { return 1; } } } /*****************************************************************************/ /*****************************************************************************/ void crc() { unsigned short i,j; acc = 0xFFFF; for (i=0; i<4; i++) { acc = acc ^ TxBuff[i]; for (j=1; j<= 8; j++) { tmp = acc & 0x0001; acc = acc >> 1; if (tmp == 1) acc = acc ^ 0xA001; } } C1 = (acc & 0xFF); C2 = (acc & 0xFF00) >> 8; TxBuff[4]=C1; TxBuff[5]=C2; // return acc; } /******************************************************************************/ void CC1000PP_send(char bit) { if(bit) { DIO=1; } else { DIO=0; } while((DCLK)==0);//wait for clock high state while((DCLK)!=0); //wait for clock low state } /******************************************************************************/ void CC1000PP_send_byte(char my_byte) { char my_bit=1; //my_bit=00000001b while(1) { CC1000PP_send(my_byte & my_bit); if(my_bit==128) break; //if(my_bit=10000000b) break; my_bit <<= 1; //00000001 -> 00000010 -> ... -> 10000000 } } /****************************************************************************/ char CC1000PP_receive(void) { char ret; while((DCLK)==0); //wait for clock high state // while((DCLK_PIN & (1<0;i--) { delay_ms(1); if ((portc.f0==0)||(portc.f1==0)||(portc.f2==0)||(portc.f3==0)||(portc.f4==0)|| (portc.f5==0)||(portc.f6==0)||(portc.f7==0)||(porth.f0==0)||(porth.f1==0)|| (porth.f2==0)||(porth.f3==0)||(porth.f4==0)||(porte.f0==0)||(porte.f1==0)||(porte.f2==0)|| (porte.f3==0)||(porte.f4==0)||(porte.f5==0)||(porte.f6==0)||(porte.f7==0) )break; } // //TxBuff[1]=0x11; /// TxBuff[3]=0; // crc(); // tx_send(); // // portb.f6=!portb.f6; // // } /* for(i=1000;i>0;i--) { delay_ms(1); if((portc.f0=0)||(portc.f1=0)||(portc.f2=0)||(portc.f3=0)||(portc.f4=0)|| (portc.f5=0)||(portc.f6=0)||(portc.f7=0)||(porth.f0=0)||(porth.f1=0)|| (porth.f2=0)||(porth.f3=0)||(porte.f0=0)||(porte.f1=0)||(porte.f2=0)|| (porte.f3=0)||(porte.f4=0)||(porte.f5=0)||(porte.f6=0)||(porte.f7=0) )break; */ //||((porta&0x0f)!=0x0f))break; portb.f6=0; // delay_ms(500); // while(((portc&0x0f)!=0x0f) ||((porta&0x0f)!=0x0f)) while ((portc.f0==0)||(portc.f1==0)||(portc.f2==0)||(portc.f3==0)||(portc.f4==0)|| (portc.f5==0)||(portc.f6==0)||(portc.f7==0)||(porth.f0==0)||(porth.f1==0)|| (porth.f2==0)||(porth.f3==0)||(porth.f4==0)||(porte.f0==0)||(porte.f1==0)||(porte.f2==0)|| (porte.f3==0)||(porte.f4==0)||(porte.f5==0)||(porte.f6==0)||(porte.f7==0) ) { portb.f6=!portb.f6; TxBuff[0]=0x0F; TxBuff[1]=~porte; TxBuff[2]=~porth; TxBuff[3]=~portc; crc(); tx_send(); if(portb.f7=1) { TxBuff[0]=0; TxBuff[1]=0; TxBuff[2]=0; TxBuff[3]=0; crc(); tx_send(); break; } } // portd.f6=!portd.f6; //||((porta&0x0f)!=0x0f))break; // portd.f6=!portd.f6; } /////////////////////// izmeri napon baterije /////////////////////// /////////////////////////////////////////////////////////////////////////// } void SetupPic() { ADCON1 = 0x0f;// Stel INT as input //CMCON=0x07; LATC = 0x00; TRISC = 0xff; PORTC = 0; LATE = 0x00; TRISE = 0xff; PORTE = 0; LATF = 0x00; TRISF = 0x00; PORTF = 0; LATH = 0x00; TRISH = 0x3f; PORTH = 0; LATA = 0x00; TRISA = 0x00; // LATA = 0x00; PORTA = 0; LATB = 0x00; TRISB=0x82; PORTB = 0; LATD = 0x00; TRISD = 0x00; trisd.f4 = 1; PORTD = 0; /* while(1) { delay_ms(500); portb.f0=1; delay_ms(500); portb.f0=0; } */ // LATH = 0x00; // TRISH = 0xff; // PORTH = 0; /////////////////////////////////////////////////////////////////////////// /* while(1) { delay_ms(500); portb.f0=!portb.f0; delay_ms(500); portb.f1=!portb.f1; delay_ms(500); portb.f2=!portb.f2; delay_ms(500); portb.f3=!portb.f3; delay_ms(500); portb.f4=!portb.f4; delay_ms(500); portb.f5=!portb.f5; delay_ms(500); portb.f6=!portb.f6; delay_ms(500); portb.f7=!portb.f7; } */ PALE=1; PCLK=1; DIO=1; ////////////////////////////////////////////////////////////////////////// } ///////// Function to do initial CC1000 setup /////// void SetupCC1000() { SetupCC1000PD(); ResetCC1000(); delay_ms(30); ConfigureCC1000(); WakeCC1000TX(); // while(1) // { // delay_ms(500); // portb=~portb; // } /* while(1) { delay_ms(500); portd.f6=!portd.f6; } */ while(!CalibrateCC1000()); // TODO: check delay_ms(25); // CalibrateCC1000(); // TODO: check WakeCC1000RX(); while(!CalibrateCC1000()); // TODO: check delay_ms(25); // CalibrateCC1000(); // TODO: check // Set to TX or RX... ChangeState(STATE_DEFAULT); // porte=ReadCC1000Reg(CC1000_FRONT_END); // INTCON = 0x10; CCTX_BUFFCOUNT = 0; CCRX_BUFFCOUNT = 0; } ///////// Routine to setup CC1000 //////////////////// void ConfigureCC1000() { // portc=ReadCC1000Reg(CC1000_FRONT_END); // Frequency A WriteCC1000Reg(CC1000_FREQ2A, FREQA2); WriteCC1000Reg(CC1000_FREQ1A, FREQA1); WriteCC1000Reg(CC1000_FREQ0A, FREQA0); // Frequency B WriteCC1000Reg(CC1000_FREQ2B, FREQB2); WriteCC1000Reg(CC1000_FREQ1B, FREQB1); WriteCC1000Reg(CC1000_FREQ0B, FREQB0); // Frequency seperation WriteCC1000Reg(CC1000_FSEP1, 0x02); WriteCC1000Reg(CC1000_FSEP0, 0x80); // 8F vir 65kHz; 80 vir 64KHz // Ander settings WriteCC1000Reg(CC1000_CURRENT, DEF_CURRENT); WriteCC1000Reg(CC1000_FRONT_END, 0x12); WriteCC1000Reg(CC1000_POWER, PA_POWER); WriteCC1000Reg(CC1000_PLL, DEF_PLL); WriteCC1000Reg(CC1000_LOCK, 0x10); WriteCC1000Reg(CC1000_CALIBRATE, 0x26); WriteCC1000Reg(CC1000_MODEM2, 0x8E); WriteCC1000Reg(CC1000_MODEM1, 0x6F);//69 vir Fast , 6F vir accurate WriteCC1000Reg(CC1000_MODEM0, 0x27); WriteCC1000Reg(CC1000_MATCH, 0x70); WriteCC1000Reg(CC1000_FSCTRL, 0x01); WriteCC1000Reg(CC1000_PRESCALER, 0x00); } //// Stuur 'n adress na CC1000 \\\\ void SendAddress(char write, unsigned short address) // write = 1 vir write { unsigned short Byte1; // byte wat gestuur word char Send; // bit om volgende te stuur unsigned short BitCounter; PCLK=1; // Moet so begin PALE=1; delay_us(10); // Net ingeval.... PALE=0; // Address is being sent PCLK=1; // Address is being sent // Stel byte op om te stuur Byte1=(address<<1)+write; // maak plek vir R/W bit // Stuur byte for (BitCounter=0;BitCounter<8;BitCounter++) { PCLK=1; Send = (Byte1 & 0x80) >> 7; // Eerste bit van Byte1 PDATA=Send; delay_us(10); Byte1<<=1; PCLK=0; delay_us(25); } // Maak klaar PCLK=1; // Moet so eindig delay_us(25); PALE=1; // Address is no longer being sent } ///////// Routine to write a configuration word /// // word lyk so: // |address |RW|data | // |7 bit | 1|8 bit | // | 16 bit | void WriteCC1000Reg(unsigned short addr, unsigned short data) { unsigned short Byte1; char Send = 0; unsigned short BitCounter; // Send address bits SendAddress(1,addr); ///load configuration byte for transmission Byte1=data; // Send data bits for (BitCounter=0;BitCounter<8;BitCounter++) { PCLK=1; Send = (Byte1 & 0x80) >> 7; PDATA=Send; delay_us(10); // if (BitCounter < 7) Byte1<<=1; PCLK=0; delay_us(25); } PCLK=1; } ///////// Routine to read a configuration //////// unsigned short ReadCC1000Reg(unsigned short addr) { unsigned short Byte1; unsigned short BitCounter; // Send address bits SendAddress(0, addr); // Receive data bits //set_tris_c(TRISC|0x10); // 0001 0000 TRISB.F5 = 1; // Set up PDATA as an input // PORTB.F7 = 1; for (BitCounter=0;BitCounter<8;BitCounter++) { PCLK=0; delay_us(25); Byte1<<= 1; Byte1=Byte1 + PDATA; PCLK=1; delay_us(25); } TRISB.F5 = 0; // Set up PDATA as an input // PORTB.F7 = 0; //set_tris_c(TRISC&0xEF); // 1110 1111 // TRISC4 = 0; // Set up PDATA as an output again return Byte1; } ///////// Resets the CC1000 /////////////////////// void ResetCC1000() { WriteCC1000Reg(CC1000_MAIN, 0x0E); WriteCC1000Reg(CC1000_MAIN, 0x1F); WriteCC1000Reg(CC1000_POWER, 0x00); } ///////// Routine to calibrate CC1000 for TX or RX // unsigned short CalibrateCC1000() { unsigned short kyk; unsigned TimeOut; WriteCC1000Reg(CC1000_POWER, 0x00); // Calibrate: Normal start // Normal time // Single // Started WriteCC1000Reg(CC1000_CALIBRATE, 0xA6); // 1010 0110 ////////// Monitor calibration //////////////////////// TimeOut = 0x0F00; while (TimeOut > 0) { delay_us(1); if ((ReadCC1000Reg(CC1000_CALIBRATE)&0x08)!=0) break; TimeOut--; } ///Finish calibration WriteCC1000Reg(CC1000_CALIBRATE, 0x26); // Stop calibration when done WriteCC1000Reg(CC1000_POWER, PA_POWER); ////////// Monitor lock //////////////////////////////// TimeOut = 0x0200; while (TimeOut > 0) { delay_us(1); if (((ReadCC1000Reg(CC1000_LOCK)&0x01)) !=0) // Kyk of gelock break; TimeOut--; } return (ReadCC1000Reg(CC1000_LOCK)&0x01); // Of gelock is of nie } ///////// Routine to set CC1000 up correctly for TX ////// unsigned short SetupCC1000TX() { // int16 i; unsigned TimeOut; unsigned short LockStat; WriteCC1000Reg(CC1000_POWER, 0x00); WriteCC1000Reg(CC1000_MAIN, 0xE1); WriteCC1000Reg(CC1000_PLL, TX_PLL); WriteCC1000Reg(CC1000_CURRENT, TX_CURRENT); // for (i=0; i<0x1000; i ++); // delay delay_ms(25); TimeOut = 0x0200; while (TimeOut > 0) { if (((ReadCC1000Reg(CC1000_LOCK)&0x01)) ) // As gelock break; TimeOut--; } if (((ReadCC1000Reg(CC1000_LOCK)&0x01)) ) // As gelock LockStat = 1; else if (CalibrateCC1000()) LockStat = 2; else LockStat = 0; WriteCC1000Reg(CC1000_POWER, PA_POWER); return LockStat; // 0 as nie gelock, 1 as dadelik, 2 as gecalibrate } ///////// Routine to set CC1000 up correctly for RX ////// unsigned short SetupCC1000RX() { unsigned TimeOut; unsigned short LockStat; // int16 i; WriteCC1000Reg(CC1000_MAIN, 0x11); WriteCC1000Reg(CC1000_PLL, RX_PLL); WriteCC1000Reg(CC1000_CURRENT, RX_CURRENT); // for (i=0; i<0x1000; i ++); // delay delay_ms(10); TimeOut = 0x0200; while (TimeOut > 0) { if (((ReadCC1000Reg(CC1000_LOCK)&0x01)) ) // As gelock break; // Hou op wag TimeOut--; } if (((ReadCC1000Reg(CC1000_LOCK)&0x01)) ) // As gelock LockStat = 1; else if (CalibrateCC1000()) LockStat = 2; else LockStat = 0; return LockStat; // 0 as nie gelock, 1 as dadelik, 2 as gecalibrate } ///////// Routine to set CC1000 in PD /////////// void SetupCC1000PD() { WriteCC1000Reg(CC1000_MAIN, 0x3F); WriteCC1000Reg(CC1000_POWER, 0x00); } ///////// Routine to bring CC1000 out of PD mode for transmit void WakeCC1000TX() { // int16 i; WriteCC1000Reg(CC1000_MAIN, 0xFB); WriteCC1000Reg(CC1000_PLL, TX_PLL); WriteCC1000Reg(CC1000_CURRENT, TX_CURRENT); // for (i = 0x200; i>0; i--); // delay delay_ms(25); WriteCC1000Reg(CC1000_MAIN, 0xF9); // for (i = 0x30; i>0; i--); // delay delay_ms(32); WriteCC1000Reg(CC1000_POWER, PA_POWER); WriteCC1000Reg(CC1000_MAIN, 0xF1); } ///////// Routine to bring CC1000 out of PD mode for RX void WakeCC1000RX() { // int16 i; WriteCC1000Reg(CC1000_MAIN, 0x3B); WriteCC1000Reg(CC1000_PLL, RX_PLL); WriteCC1000Reg(CC1000_CURRENT, RX_CURRENT); // for (i = 0x200; i>0; i--); // delay delay_ms(20); WriteCC1000Reg(CC1000_MAIN, 0x39); // for (i = 0x30; i>0; i--); // delay delay_ms(30); WriteCC1000Reg(CC1000_MAIN, 0x31); } ///////// Routine to change the state of the CC1000 void ChangeState(unsigned short state) { unsigned short korektor=1; switch (state) { case STATE_TX: while(korektor!=SetupCC1000TX()); delay_ms(2); TRISB.F2=0; CC1000_STATE = STATE_TX; break; case STATE_RX: while(korektor!=SetupCC1000RX()); delay_ms(2); TRISB.F2=1; CC1000_STATE = STATE_RX; break; default: ; } }