+++ /dev/null
-/*\r
-\r
- This library was originally copyright of Michael at elechouse.com but permision was\r
- granted by Wilson Shen on 2016-10-23 for me (Simon Monk) to uodate the code for Arduino 1.0+\r
- and release the code on github under the MIT license.\r
-\r
-\r
-Wilson Shen <elechouse@elechouse.com> 23 October 2016 at 02:08\r
-To: Simon Monk \r
-Thanks for your email.\r
-You are free to put it in github and to do and change.\r
-\r
-On Oct 22, 2016 10:07 PM, "Simon Monk" <srmonk@gmail.com> wrote:\r
- Hi,\r
-\r
- I'm Simon Monk, I'm currently writing the Electronics Cookbook for O'Reilly. I use your \r
- ELECHOUSE_CC1101 library in a 'recipe'. Your library is by far the easiest to use of \r
- the libraries for this device, but the .h and .cpp file both reference WProgram.h which \r
- as replaced by Arduino.h in Arduino 1.0.\r
-\r
- Rather than have to talk my readers through applying a fix to your library, I'd like \r
- your permission to put the modified lib into Github and add an example from the book. \r
- I would of course provide a link to your website in the book and mention that you can buy \r
- the modules there. If its ok, I'd give the code an MIT OS license, to clarify its use.\r
-\r
- Thanks for a great library,\r
-\r
- Kind Regards,\r
-\r
- Simon Monk.\r
- \r
-*/\r
-#include "ELECHOUSE_CC1101.h"\r
-\r
-#ifdef ELECHOUSE \r
-// #include <Arduino.h>\r
-\r
-\r
-/****************************************************************/\r
-#define WRITE_BURST 0x40 //write burst\r
-#define READ_SINGLE 0x80 //read single\r
-#define READ_BURST 0xC0 //read burst\r
-#define BYTES_IN_RXFIFO 0x7F //byte number in RXfifo\r
-\r
-/****************************************************************/\r
-byte PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiInit\r
-*FUNCTION :spi communication initialization\r
-*INPUT :none\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SpiInit(void)\r
-{\r
- // initialize the SPI pins\r
- pinMode(SCK_PIN, OUTPUT);\r
- pinMode(MOSI_PIN, OUTPUT);\r
- pinMode(MISO_PIN, INPUT);\r
- pinMode(SS_PIN, OUTPUT);\r
-\r
- // enable SPI Master, MSB, SPI mode 0, FOSC/4\r
- SpiMode(0);\r
-}\r
-/****************************************************************\r
-*FUNCTION NAME:SpiMode\r
-*FUNCTION :set spi mode\r
-*INPUT : config mode\r
- (0<<CPOL) | (0 << CPHA) 0\r
- (0<<CPOL) | (1 << CPHA) 1\r
- (1<<CPOL) | (0 << CPHA) 2\r
- (1<<CPOL) | (1 << CPHA) 3\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SpiMode(byte config)\r
-{\r
- byte tmp;\r
-\r
- // enable SPI master with configuration byte specified\r
- SPCR = 0;\r
- SPCR = (config & 0x7F) | (1<<SPE) | (1<<MSTR);\r
- tmp = SPSR;\r
- tmp = SPDR;\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiTransfer\r
-*FUNCTION :spi transfer\r
-*INPUT :value: data to send\r
-*OUTPUT :data to receive\r
-****************************************************************/\r
-byte ELECHOUSE_CC1101::SpiTransfer(byte value)\r
-{\r
- SPDR = value;\r
- while (!(SPSR & (1<<SPIF))) ;\r
- return SPDR;\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME: GDO_Set()\r
-*FUNCTION : set GDO0,GDO2 pin\r
-*INPUT : none\r
-*OUTPUT : none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::GDO_Set (void)\r
-{\r
- pinMode(GDO0, INPUT);\r
- pinMode(GDO2, INPUT);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:Reset\r
-*FUNCTION :CC1101 reset //details refer datasheet of CC1101/CC1100//\r
-*INPUT :none\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::Reset (void)\r
-{\r
- digitalWrite(SS_PIN, LOW);\r
- delay(1);\r
- digitalWrite(SS_PIN, HIGH);\r
- delay(1);\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(CC1101_SRES);\r
- while(digitalRead(MISO_PIN));\r
- digitalWrite(SS_PIN, HIGH);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:Init\r
-*FUNCTION :CC1101 initialization\r
-*INPUT :none\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::Init(void)\r
-{\r
- SpiInit(); //spi initialization\r
- GDO_Set(); //GDO set\r
- digitalWrite(SS_PIN, HIGH);\r
- digitalWrite(SCK_PIN, HIGH);\r
- digitalWrite(MOSI_PIN, LOW);\r
- Reset(); //CC1101 reset\r
- RegConfigSettings(F_433); //CC1101 register config\r
- SpiWriteBurstReg(CC1101_PATABLE,PaTabel,8); //CC1101 PATABLE config\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:Init\r
-*FUNCTION :CC1101 initialization\r
-*INPUT :none\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::Init(byte f)\r
-{\r
- SpiInit(); //spi initialization\r
- GDO_Set(); //GDO set\r
- digitalWrite(SS_PIN, HIGH);\r
- digitalWrite(SCK_PIN, HIGH);\r
- digitalWrite(MOSI_PIN, LOW);\r
- Reset(); //CC1101 reset\r
- RegConfigSettings(f); //CC1101 register config\r
- SpiWriteBurstReg(CC1101_PATABLE,PaTabel,8); //CC1101 PATABLE config\r
-}\r
-\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiWriteReg\r
-*FUNCTION :CC1101 write data to register\r
-*INPUT :addr: register address; value: register value\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SpiWriteReg(byte addr, byte value)\r
-{\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(addr);\r
- SpiTransfer(value);\r
- digitalWrite(SS_PIN, HIGH);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiWriteBurstReg\r
-*FUNCTION :CC1101 write burst data to register\r
-*INPUT :addr: register address; buffer:register value array; num:number to write\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SpiWriteBurstReg(byte addr, byte *buffer, byte num)\r
-{\r
- byte i, temp;\r
-\r
- temp = addr | WRITE_BURST;\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(temp);\r
- for (i = 0; i < num; i++)\r
- {\r
- SpiTransfer(buffer[i]);\r
- }\r
- digitalWrite(SS_PIN, HIGH);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiStrobe\r
-*FUNCTION :CC1101 Strobe\r
-*INPUT :strobe: command; //refer define in CC1101.h//\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SpiStrobe(byte strobe)\r
-{\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(strobe);\r
- digitalWrite(SS_PIN, HIGH);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiReadReg\r
-*FUNCTION :CC1101 read data from register\r
-*INPUT :addr: register address\r
-*OUTPUT :register value\r
-****************************************************************/\r
-byte ELECHOUSE_CC1101::SpiReadReg(byte addr) \r
-{\r
- byte temp, value;\r
-\r
- temp = addr|READ_SINGLE;\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(temp);\r
- value=SpiTransfer(0);\r
- digitalWrite(SS_PIN, HIGH);\r
-\r
- return value;\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiReadBurstReg\r
-*FUNCTION :CC1101 read burst data from register\r
-*INPUT :addr: register address; buffer:array to store register value; num: number to read\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SpiReadBurstReg(byte addr, byte *buffer, byte num)\r
-{\r
- byte i,temp;\r
-\r
- temp = addr | READ_BURST;\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(temp);\r
- for(i=0;i<num;i++)\r
- {\r
- buffer[i]=SpiTransfer(0);\r
- }\r
- digitalWrite(SS_PIN, HIGH);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SpiReadStatus\r
-*FUNCTION :CC1101 read status register\r
-*INPUT :addr: register address\r
-*OUTPUT :status value\r
-****************************************************************/\r
-byte ELECHOUSE_CC1101::SpiReadStatus(byte addr) \r
-{\r
- byte value,temp;\r
-\r
- temp = addr | READ_BURST;\r
- digitalWrite(SS_PIN, LOW);\r
- while(digitalRead(MISO_PIN));\r
- SpiTransfer(temp);\r
- value=SpiTransfer(0);\r
- digitalWrite(SS_PIN, HIGH);\r
-\r
- return value;\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:RegConfigSettings\r
-*FUNCTION :CC1101 register config //details refer datasheet of CC1101/CC1100//\r
-*INPUT :none\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::RegConfigSettings(byte f) \r
-{\r
- SpiWriteReg(CC1101_FSCTRL1, 0x08);\r
- SpiWriteReg(CC1101_FSCTRL0, 0x00);\r
- \r
- switch(f)\r
- {\r
- case F_868:\r
- SpiWriteReg(CC1101_FREQ2, F2_868);\r
- SpiWriteReg(CC1101_FREQ1, F1_868);\r
- SpiWriteReg(CC1101_FREQ0, F0_868);\r
- break;\r
- case F_915:\r
- SpiWriteReg(CC1101_FREQ2, F2_915);\r
- SpiWriteReg(CC1101_FREQ1, F1_915);\r
- SpiWriteReg(CC1101_FREQ0, F0_915);\r
- break;\r
- case F_433:\r
- SpiWriteReg(CC1101_FREQ2, F2_433);\r
- SpiWriteReg(CC1101_FREQ1, F1_433);\r
- SpiWriteReg(CC1101_FREQ0, F0_433);\r
- break;\r
- default: // F must be set\r
- break;\r
- }\r
- \r
- SpiWriteReg(CC1101_MDMCFG4, 0x5B);\r
- SpiWriteReg(CC1101_MDMCFG3, 0xF8);\r
- SpiWriteReg(CC1101_MDMCFG2, 0x03);\r
- SpiWriteReg(CC1101_MDMCFG1, 0x22);\r
- SpiWriteReg(CC1101_MDMCFG0, 0xF8);\r
- SpiWriteReg(CC1101_CHANNR, 0x00);\r
- SpiWriteReg(CC1101_DEVIATN, 0x47);\r
- SpiWriteReg(CC1101_FREND1, 0xB6);\r
- SpiWriteReg(CC1101_FREND0, 0x10);\r
- SpiWriteReg(CC1101_MCSM0 , 0x18);\r
- SpiWriteReg(CC1101_FOCCFG, 0x1D);\r
- SpiWriteReg(CC1101_BSCFG, 0x1C);\r
- SpiWriteReg(CC1101_AGCCTRL2, 0xC7);\r
- SpiWriteReg(CC1101_AGCCTRL1, 0x00);\r
- SpiWriteReg(CC1101_AGCCTRL0, 0xB2);\r
- SpiWriteReg(CC1101_FSCAL3, 0xEA);\r
- SpiWriteReg(CC1101_FSCAL2, 0x2A);\r
- SpiWriteReg(CC1101_FSCAL1, 0x00);\r
- SpiWriteReg(CC1101_FSCAL0, 0x11);\r
- SpiWriteReg(CC1101_FSTEST, 0x59);\r
- SpiWriteReg(CC1101_TEST2, 0x81);\r
- SpiWriteReg(CC1101_TEST1, 0x35);\r
- SpiWriteReg(CC1101_TEST0, 0x09);\r
- SpiWriteReg(CC1101_IOCFG2, 0x0B); //serial clock.synchronous to the data in synchronous serial mode\r
- SpiWriteReg(CC1101_IOCFG0, 0x06); //asserts when sync word has been sent/received, and de-asserts at the end of the packet \r
- SpiWriteReg(CC1101_PKTCTRL1, 0x04); //two status bytes will be appended to the payload of the packet,including RSSI LQI and CRC OK\r
- //No address check\r
- SpiWriteReg(CC1101_PKTCTRL0, 0x05); //whitening off;CRC Enable��variable length packets, packet length configured by the first byte after sync word\r
- SpiWriteReg(CC1101_ADDR, 0x00); //address used for packet filtration.\r
- SpiWriteReg(CC1101_PKTLEN, 0x3D); //61 bytes max length\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SendData\r
-*FUNCTION :use CC1101 send data\r
-*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SendData(byte *txBuffer,byte size)\r
-{\r
- SpiWriteReg(CC1101_TXFIFO,size);\r
- SpiWriteBurstReg(CC1101_TXFIFO,txBuffer,size); //write data to send\r
- SpiStrobe(CC1101_STX); //start send \r
- while (!digitalRead(GDO0)); // Wait for GDO0 to be set -> sync transmitted \r
- while (digitalRead(GDO0)); // Wait for GDO0 to be cleared -> end of packet\r
- SpiStrobe(CC1101_SFTX); //flush TXfifo\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:SetReceive\r
-*FUNCTION :set CC1101 to receive state\r
-*INPUT :none\r
-*OUTPUT :none\r
-****************************************************************/\r
-void ELECHOUSE_CC1101::SetReceive(void)\r
-{\r
- SpiStrobe(CC1101_SRX);\r
-}\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:CheckReceiveFlag\r
-*FUNCTION :check receive data or not\r
-*INPUT :none\r
-*OUTPUT :flag: 0 no data; 1 receive data \r
-****************************************************************/\r
-byte ELECHOUSE_CC1101::CheckReceiveFlag(void)\r
-{\r
- if(digitalRead(GDO0)) //receive data\r
- {\r
- while (digitalRead(GDO0));\r
- return 1;\r
- }\r
- else // no data\r
- {\r
- return 0;\r
- }\r
-}\r
-\r
-\r
-/****************************************************************\r
-*FUNCTION NAME:ReceiveData\r
-*FUNCTION :read data received from RXfifo\r
-*INPUT :rxBuffer: buffer to store data\r
-*OUTPUT :size of data received\r
-****************************************************************/\r
-byte ELECHOUSE_CC1101::ReceiveData(byte *rxBuffer)\r
-{\r
- byte size;\r
- byte status[2];\r
-\r
- if(SpiReadStatus(CC1101_RXBYTES) & BYTES_IN_RXFIFO)\r
- {\r
- size=SpiReadReg(CC1101_RXFIFO);\r
- SpiReadBurstReg(CC1101_RXFIFO,rxBuffer,size);\r
- SpiReadBurstReg(CC1101_RXFIFO,status,2);\r
- SpiStrobe(CC1101_SFRX);\r
- return size;\r
- }\r
- else\r
- {\r
- SpiStrobe(CC1101_SFRX);\r
- return 0;\r
- }\r
- \r
-}\r
-\r
-ELECHOUSE_CC1101 ELECHOUSE_cc1101;\r
-\r
-\r
-#endif\r
-\r
+++ /dev/null
-/*\r
-\r
- This library was originally copyright of Michael at elechouse.com but permision was\r
- granted by Wilson Shen on 2016-10-23 for me (Simon Monk) to uodate the code for Arduino 1.0+\r
- and release the code on github under the MIT license.\r
-\r
-\r
-Wilson Shen <elechouse@elechouse.com> 23 October 2016 at 02:08\r
-To: Simon Monk <srmonk@gmail.com>\r
-Thanks for your email.\r
-You are free to put it in github and to do and change.\r
-\r
-On Oct 22, 2016 10:07 PM, "Simon Monk" <srmonk@gmail.com> wrote:\r
- Hi,\r
-\r
- I'm Simon Monk, I'm currently writing the Electronics Cookbook for O'Reilly. I use your \r
- ELECHOUSE_CC1101 library in a 'recipe'. Your library is by far the easiest to use of \r
- the libraries for this device, but the .h and .cpp file both reference WProgram.h which \r
- as replaced by Arduino.h in Arduino 1.0.\r
-\r
- Rather than have to talk my readers through applying a fix to your library, I'd like \r
- your permission to put the modified lib into Github and add an example from the book. \r
- I would of course provide a link to your website in the book and mention that you can buy \r
- the modules there. If its ok, I'd give the code an MIT OS license, to clarify its use.\r
-\r
- Thanks for a great library,\r
-\r
- Kind Regards,\r
-\r
- Simon Monk.\r
-\r
-\r
-*/\r
-//#define ELECHOUSE\r
-#ifdef ELECHOUSE \r
-\r
-#ifndef ELECHOUSE_CC1101_h\r
-#define ELECHOUSE_CC1101_h\r
-\r
-// #include "Arduino.h"\r
-#include <stdint.h>\r
-#define byte uint8_t\r
-\r
-// Init constants\r
-#define F_915 0x00\r
-#define F_433 0x01\r
-#define F_868 0x02\r
-\r
-// Register values for different frequencies\r
-// Carrier frequency = 868 MHz\r
-#define F2_868 0x21 \r
-#define F1_868 0x62 \r
-#define F0_868 0x76 \r
-// Carrier frequency = 902 MHz\r
-#define F2_915 0x22 \r
-#define F1_915 0xB1 \r
-#define F0_915 0x3B \r
-// Carrier frequency = 433 MHz\r
-#define F2_433 0x10 \r
-#define F1_433 0xA7 \r
-#define F0_433 0x62 \r
-\r
-\r
-\r
-\r
-\r
-//***************************************CC1101 define**************************************************//\r
-// CC1101 CONFIG REGSITER\r
-#define CC1101_IOCFG2 0x00 // GDO2 output pin configuration\r
-#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration\r
-#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration\r
-#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds\r
-#define CC1101_SYNC1 0x04 // Sync word, high INT8U\r
-#define CC1101_SYNC0 0x05 // Sync word, low INT8U\r
-#define CC1101_PKTLEN 0x06 // Packet length\r
-#define CC1101_PKTCTRL1 0x07 // Packet automation control\r
-#define CC1101_PKTCTRL0 0x08 // Packet automation control\r
-#define CC1101_ADDR 0x09 // Device address\r
-#define CC1101_CHANNR 0x0A // Channel number\r
-#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control\r
-#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control\r
-#define CC1101_FREQ2 0x0D // Frequency control word, high INT8U\r
-#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U\r
-#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U\r
-#define CC1101_MDMCFG4 0x10 // Modem configuration\r
-#define CC1101_MDMCFG3 0x11 // Modem configuration\r
-#define CC1101_MDMCFG2 0x12 // Modem configuration\r
-#define CC1101_MDMCFG1 0x13 // Modem configuration\r
-#define CC1101_MDMCFG0 0x14 // Modem configuration\r
-#define CC1101_DEVIATN 0x15 // Modem deviation setting\r
-#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration\r
-#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration\r
-#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration\r
-#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration\r
-#define CC1101_BSCFG 0x1A // Bit Synchronization configuration\r
-#define CC1101_AGCCTRL2 0x1B // AGC control\r
-#define CC1101_AGCCTRL1 0x1C // AGC control\r
-#define CC1101_AGCCTRL0 0x1D // AGC control\r
-#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout\r
-#define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout\r
-#define CC1101_WORCTRL 0x20 // Wake On Radio control\r
-#define CC1101_FREND1 0x21 // Front end RX configuration\r
-#define CC1101_FREND0 0x22 // Front end TX configuration\r
-#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration\r
-#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration\r
-#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration\r
-#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration\r
-#define CC1101_RCCTRL1 0x27 // RC oscillator configuration\r
-#define CC1101_RCCTRL0 0x28 // RC oscillator configuration\r
-#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control\r
-#define CC1101_PTEST 0x2A // Production test\r
-#define CC1101_AGCTEST 0x2B // AGC test\r
-#define CC1101_TEST2 0x2C // Various test settings\r
-#define CC1101_TEST1 0x2D // Various test settings\r
-#define CC1101_TEST0 0x2E // Various test settings\r
-\r
-//CC1101 Strobe commands\r
-#define CC1101_SRES 0x30 // Reset chip.\r
-#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).\r
- // If in RX/TX: Go to a wait state where only the synthesizer is\r
- // running (for quick RX / TX turnaround).\r
-#define CC1101_SXOFF 0x32 // Turn off crystal oscillator.\r
-#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off\r
- // (enables quick start).\r
-#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and\r
- // MCSM0.FS_AUTOCAL=1.\r
-#define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if\r
- // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:\r
- // Only go to TX if channel is clear.\r
-#define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit\r
- // Wake-On-Radio mode if applicable.\r
-#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer\r
-#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)\r
-#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high.\r
-#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer.\r
-#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer.\r
-#define CC1101_SWORRST 0x3C // Reset real time clock.\r
-#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two\r
- // INT8Us for simpler software.\r
-//CC1101 STATUS REGSITER\r
-#define CC1101_PARTNUM 0x30\r
-#define CC1101_VERSION 0x31\r
-#define CC1101_FREQEST 0x32\r
-#define CC1101_LQI 0x33\r
-#define CC1101_RSSI 0x34\r
-#define CC1101_MARCSTATE 0x35\r
-#define CC1101_WORTIME1 0x36\r
-#define CC1101_WORTIME0 0x37\r
-#define CC1101_PKTSTATUS 0x38\r
-#define CC1101_VCO_VC_DAC 0x39\r
-#define CC1101_TXBYTES 0x3A\r
-#define CC1101_RXBYTES 0x3B\r
-\r
-//CC1101 PATABLE,TXFIFO,RXFIFO\r
-#define CC1101_PATABLE 0x3E\r
-#define CC1101_TXFIFO 0x3F\r
-#define CC1101_RXFIFO 0x3F\r
-\r
-//*************************************** pins **************************************************//\r
-#define SCK_PIN 13\r
-#define MISO_PIN 12\r
-#define MOSI_PIN 11\r
-#define SS_PIN 10\r
-#define GDO0 2\r
-#define GDO2 9\r
-//************************************* class **************************************************//\r
-class ELECHOUSE_CC1101\r
-{\r
- private:\r
- void SpiInit(void);\r
- void SpiMode(byte config);\r
- byte SpiTransfer(byte value);\r
- void GDO_Set (void);\r
- void Reset (void);\r
- void SpiWriteReg(byte addr, byte value);\r
- void SpiWriteBurstReg(byte addr, byte *buffer, byte num);\r
- void SpiStrobe(byte strobe);\r
- byte SpiReadReg(byte addr);\r
- void SpiReadBurstReg(byte addr, byte *buffer, byte num);\r
- byte SpiReadStatus(byte addr);\r
- void RegConfigSettings(byte f);\r
- public:\r
- void Init(void);\r
- void Init(byte f);\r
- void SendData(byte *txBuffer, byte size);\r
- void SetReceive(void);\r
- byte CheckReceiveFlag(void);\r
- byte ReceiveData(byte *rxBuffer);\r
-};\r
-\r
-extern ELECHOUSE_CC1101 ELECHOUSE_cc1101;\r
-\r
-#endif\r
-\r
-#endif
\ No newline at end of file
#include "units/modbus.hpp"
#include "units/rtc8563.hpp"
#include "units/cc1101.hpp"
-#include "units/cc1101new.hpp"
extern "C" {
void __cxa_pure_virtual () {}
Rtc8563 rtc8563;
Cc1101 cc1101Send(Cc1101::Send);
Cc1101 cc1101Receive(Cc1101::Receive);
- Cc1101New cc1101NewSend(Cc1101New::Send);
- Cc1101New cc1101NewReceive(Cc1101New::Receive);
- Cc1101New cc1101NewTest(Cc1101New::Test);
-
}
void setTimer (uint32_t ms) {
#ifdef __AVR_ATmega644P__
TestUnit *unit[] = {
&led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp, &lcd, &uart1, &modbus, &ieee485,
- &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101Send, &cc1101Receive, &cc1101NewSend, &cc1101NewReceive, &cc1101NewTest
+ &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101Send, &cc1101Receive
};
#endif
i2cSparkfun.tick1ms();
cc1101Send.tick1ms();
cc1101Receive.tick1ms();
- cc1101NewSend.tick1ms();
- cc1101NewReceive.tick1ms();
- cc1101NewTest.tick1ms();
#ifdef __AVR_ATmega644P__
if (timerFlashRedLed > 0) {
if (--timerFlashRedLed < 128) {
void Cc1101::init () {}
void Cc1101::cleanup () {}
+ void Cc1101::setChipEnableLow () {}
+ void Cc1101::setChipEnableHigh () {}
int8_t Cc1101::run (uint8_t subtest) { return -1; }
PGM_P Cc1101::getName () { return PSTR("?"); }
// Nano-644
// --------------------------------------------------------
// PA4 ... nCS
+ // PB4 ... nSS (not used, but must be high, otherwise AVR SPI master not working)
// PB5 ... MOSI
// PB6 ... MISO
// PB7 ... SCK
-const uint8_t PMEM_CC1101_INIT[] PROGMEM = {
- CC1101_MDMCFG4, 0x5B, // modem config 4 -> ADC decimation rate, symbol rate exponent
- CC1101_MDMCFG3, 0xF8, // modem config 3 -> symbol rate mantissa
- CC1101_MDMCFG2, 0x03, // modem config 2 -> DC blocking filter, modulation type, manchaster enoding, sync-mode,
- CC1101_MDMCFG1, 0x22, // modem config 1 -> forw error correction, min number of preamble bytes, channel spacing exponent
- CC1101_MDMCFG0, 0xF8, // modem config 0 -> channel spacing mantissa
- CC1101_CHANNR, 0x00, // channel number
- CC1101_DEVIATN, 0x47, // modem deviation setting
- CC1101_FREND1, 0xB6, // front end RX configuration
- CC1101_FREND0, 0x10, // front end TX configuration
- CC1101_MCSM0 , 0x18, // Main Radio Control State Machine Configuration
- CC1101_FOCCFG, 0x1D, // Frequency Offset Compensation Configuration
- CC1101_BSCFG, 0x1C, // Bit Synchronization Configuration
- CC1101_AGCCTRL2, 0xC7, // AGC Control
- CC1101_AGCCTRL1, 0x00, // AGC Control
- CC1101_AGCCTRL0, 0xB2, // AGC Control
- CC1101_FSCAL3, 0xEA, // Frequency Synthesizer Calibration
- CC1101_FSCAL2, 0x2A, // Frequency Synthesizer Calibration
- CC1101_FSCAL1, 0x00, // Frequency Synthesizer Calibration
- CC1101_FSCAL0, 0x11, // Frequency Synthesizer Calibration
- CC1101_FSTEST, 0x59, // Frequency Synthesizer Calibration Control
- CC1101_TEST2, 0x81, // Various Test Settings
- CC1101_TEST1, 0x35, // Various Test Settings
- CC1101_TEST0, 0x09, // Various Test Settings
- CC1101_IOCFG2, 0x0B, // GDO2 Output Pin Configuration -> Serial Clock. Synchronous to the data in synchronous serial mode.
- CC1101_IOCFG0, 0x06, // GDO0 Output Pin Configuration -> Asserts when sync word has been sent / received, and de-asserts at the end of the packet.
- CC1101_PKTCTRL1, 0x04, // Packet Automation Control
- CC1101_PKTCTRL0, 0x05, // serial clock.synchronous to the data in synchronous serial mode
- CC1101_ADDR, 0x00, // asserts when sync word has been sent/received, and de-asserts at the end of the packet
- CC1101_PKTLEN, 0x3D // two status bytes will be appended to the payload of the packet,including RSSI LQI and CRC OK
-};
-
-
-const uint8_t PMEM_CC1101_PA_TABLE[8] PROGMEM = { 0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 };
+ int8_t Cc1101::runSend (uint8_t subtest) {
+ if (subtest == 0) {
+ bool ok = true;
+ GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET;
+ ok &= writeRegister(0x02, cfg0);
+ return ok;
+ } else if (subtest > 1) {
+ return -1;
+ }
+
+ uint16_t cnt = 0;
+ do {
+ MainRadioControlState state = UNKNOWN;
+ uint8_t data[PACKET_LENGTH];
+ printf_P(PSTR("\n [%04x]: state="), cnt++);
+ if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
+ printf_P(PSTR("E1"));
+ } else {
+ printf_P(PSTR("0x%02x"), state);
+ }
+ printf_P(PSTR(" --> send %d bytes (HEX:"), sizeof(data));
+ for (uint8_t i = 0; i < sizeof(data); i++) {
+ data[i] = uint8_t((cnt + i) & 0xff);
+ printf_P(PSTR(" %02X"), data[i]);
+ }
+ printf_P(PSTR("] -> "));
+
+ if (!sendData(data, sizeof(data))) {
+ flashRedLed(100);
+ printf_P(PSTR("E1"));
+ continue;
+ }
+ flashGreenLed(100);
+ printf_P(PSTR("OK"));
+ } while (wait(2000) == EOF);
+
+ return 0;
+ }
+
+ int8_t Cc1101::runReceive (uint8_t subtest) {
+ if (subtest == 0) {
+ bool ok = true;
+ GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET;
+ ok &= writeRegister(0x02, cfg0);
+ return ok;
+ } else if (subtest > 1) {
+ return -1;
+ }
+
+ int key = EOF;
+ uint16_t cnt = 0;
+ MainRadioControlState state;
+ while (key == EOF) {
+ printf_P(PSTR("\n [%04x] => start ... "), cnt++);
+ strobe(SRX);
+ do {
+ state = UNKNOWN;
+ if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
+ printf_P(PSTR("E1"));
+ _delay_ms(500);
+ break;
+ }
+ if (wait(0) != EOF) {
+ printf_P(PSTR("cancelled"));
+ _delay_ms(500);
+ break;
+ }
+ if (state == IDLE) {
+ printf_P(PSTR("? (IDLE)"));
+ _delay_ms(500);
+ break;
+ }
+
+ } while (state != RX && state != RXFIFO_OVERFLOW);
+
+ if (state != RX && state != RXFIFO_OVERFLOW) {
+ continue;
+ }
+ printf_P(PSTR("OK, receive ... "));
+
+ uint8_t length;
+ uint8_t lastLength = 0xff;
+ do {
+ uint8_t data[PACKET_LENGTH];
+ if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
+ printf_P(PSTR("E2"));
+ _delay_ms(500);
+ continue;
+ }
+ if (wait(0) != EOF) {
+ printf_P(PSTR("cancelled"));
+ _delay_ms(500);
+ return -1;
+ }
+ if (!readStatusRegister(RXBYTES, (uint8_t *)&length)) {
+ printf_P(PSTR("E2"));
+ _delay_ms(500);
+ continue;
+ }
+ if (lastLength != length) {
+ lastLength = length;
+ }
+ if (length >= PACKET_LENGTH) {
+ if (receiveData(data, &length, sizeof(data))) {
+ if (length > 0) {
+ flashGreenLed(100);
+ printf_P(PSTR(" -> "));
+ if (status.receivePacketStatusValid) {
+ printf_P(PSTR(" RSSI=%d, LQI=%d, CRC "), status.receivedPacketStatus.value.rssi, status.receivedPacketStatus.value.lqi);
+ if (status.receivedPacketStatus.value.crcOk) {
+ printf_P(PSTR("OK, "));
+ } else {
+ printf_P(PSTR("ERROR, "));
+ }
+ }
+ printf_P(PSTR("%d data bytes (HEX): "), length);
+ for (uint8_t i = 0; i < length; i++) {
+ printf_P(PSTR(" %02X"), data[i]);
+ }
+ printf_P(PSTR(" ... "));
+ }
+ }
+ }
+
+ } while (state == RX || state == RXFIFO_OVERFLOW);
+
+ printf_P(PSTR("done (state=0x%02x)"), state);
+ }
+ return -1;
+ }
+
+ int8_t Cc1101::runTest (uint8_t subtest) {
+ if (subtest > 0) {
+ return -1;
+ }
+ while (wait(0) == EOF) {}
+ return -1;
+ }
+
+
+ int8_t Cc1101::run (uint8_t subtest) {
+ switch (mode) {
+ case Send: return runSend(subtest);
+ case Receive: return runReceive(subtest);
+ case Test: return runTest(subtest);
+ default: return -1;
+ }
+ }
+
+ // --------------------------------------------------------
+
+ const Cc1101::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = {
+ /* 0x00: iocfg2 0x0b (----) */ { Cc1101::CHIP_NOT_READY, 0, 0 }, // GDO2
+ /* 0x01: iocfg1 0x2e (----) */ { Cc1101::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO
+ /* 0x02: iocfg0 0x06 (----) */ { Cc1101::SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET, 0, 0 }, // GDO0 -> PA5
+ /* 0x03: fifothr 0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0)
+ /* 0x04: sync1 0x7a (0xd3) */ 0x7a,
+ /* 0x05: sync0 0x0e (0x91) */ 0x0e,
+ /* 0x06: pktlen 0x14 (0x3d) */ PACKET_LENGTH,
+ /* 0x07: pktctrl1 0x04 (----) */ { Cc1101::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
+ /* 0x08: pktctrl0 0x05 (----) */ { Cc1101::FIXED, 1, 0, Cc1101::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0)
+ /* 0x09: addr 0x00 (----) */ 0x00,
+ /* 0x0a: channr 0x00 (----) */ 0x00,
+ /* 0x0b: fsctrl1 0x06 (0x08) */ { 6, 0, 0 }, // frqu_if=6, (bit5=0), (bit76=0b00)
+ /* 0x0c: fsctrl0 0x00 (----) */ { 0 }, // freqoff = 0
+ /* 0x0d: frequ2 0x21 (----) */ 0x21,
+ /* 0x0e: frequ1 0x62 (----) */ 0x62,
+ /* 0x0f: frequ0 0x76 (----) */ 0x76,
+ /* 0x10: mdmcfg4 0xca (0x5b) */ { 0x0a, 0, 3 }, // drate_e=0x0a, chanbw_m=0, chanbw_e=3
+ /* 0x11: mdmcfg3 0xf8 (----) */ { 0xf8 }, // drate_m=0xf8
+ /* 0x12: mdmcfg2 0x16 (0x03) */ { Cc1101::SYNC_16_16_CARRIER_SENSE, 0, Cc1101::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0
+ /* 0x13: mdmcfg1 0x22 (----) */ { 2, 0, Cc1101::FOUR, 0 }, // chanspc_e=0b10, bit32=0, num_preamble=0b010, fec_en=0
+ /* 0x14: mdmcfg0 0xf8 (----) */ { 0xf8 }, // chanspc_m = 0x08
+ /* 0x15: deviatn 0x40 (0x47) */ { 0, 0, 4, 0 }, // deviation_m=0, (bit3=0), deviation_e=4, (bit7=0)
+ /* 0x16: mcsm2 0x07 (----) */ { 7, 0, 0, 0 }, // rx_time=7 (NA), rx_time_qual=0, rx_time_rssi=0, (bit76=0b00)
+ /* 0x17: mcsm1 0x30 (----) */ { Cc1101::TXOFF_IDLE, Cc1101::RXOFF_IDLE, Cc1101::RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET, 0 }, // mcsm1 (txoff_mode=0b00, rxoff_mode=0b00, cca_mode=0b11, (bit76=0b00) )
+ /* 0x18: mcsm0 0x18 (----) */ { 0, 0, 2, Cc1101::IDLE_TO_RX_OR_TX, 0 }, // xosc_force_on=0, pin_ctrl_en=0, po_timeout=2 (149-155us), fs_autocal=0b01, (bit76=0b00)
+ /* 0x19: foccfg 0x16 (0x1d) */ 0x16,
+ /* 0x1a: bscfg 0x6c (0x1c) */ 0x6c,
+ /* 0x1b: agcctrl2 0x43 (0xc7) */ 0x43,
+ /* 0x1c: agcctrl1 0x49 (0x00) */ 0x49,
+ /* 0x1d: agcctrl0 0x91 (0xb2) */ 0x91,
+ /* 0x1e: worevt1 0x87 (----) */ 0x87,
+ /* 0x1f: worevt0 0x6b (----) */ 0x6b,
+ /* 0x20: worctrl 0xfb (0xf8) */ 0xfb,
+ /* 0x21: frend1 0x56 (0xb6) */ 0x56,
+ /* 0x22: frend0 0x10 (----) */ 0x10,
+ /* 0x23: fscal3 0xe9 (0xea) */ 0xe9,
+ /* 0x24: fscal2 0x2a (----) */ 0x2a,
+ /* 0x25: fscal1 0x00 (----) */ 0x00,
+ /* 0x26: fscal0 0x1f (0x11) */ 0x1f,
+ /* 0x27: rcctrl1 0x41 (----) */ 0x41,
+ /* 0x28: rcctrl0 0x00 (----) */ 0x00,
+ /* 0x29: fstest 0x59 (----) */ 0x59,
+ /* 0x2a: ptest 0x7f (----) */ 0x7f,
+ /* 0x2b: agctest 0x3f (----) */ 0x3f,
+ /* 0x2c: test2 0x81 (0x88) */ 0x81,
+ /* 0x2d: test1 0x35 (0x31) */ 0x35,
+ /* 0x2e: test0 0x09 (0x0b) */ 0x09
+ };
+
+ uint8_t Cc1101::sendSpiByte (uint8_t b) {
+ SPDR = b;
+ while (!(SPSR & (1<<SPIF))) {}
+ return SPDR;
+ }
void Cc1101::triggerOn () {
PORTB |= (1 << PB0);
PORTB &= ~(1 << PB0);
}
+ void Cc1101::triggerToggle () {
+ PORTB ^= (1 << PB0);
+ }
+
PGM_P Cc1101::getName () {
switch (mode) {
- case Send: return PSTR("CC-1101-Send");
- case Receive: return PSTR("CC-1101-Receive");
- default: return PSTR("CC-1101-?");
+ case Send: return PSTR("CC-1101-New-Send");
+ case Receive: return PSTR("CC-1101-New-Receive");
+ case Test: return PSTR("CC-1101-New-Test");
+ default: return PSTR("CC-1101-New-?");
}
}
void Cc1101::init () {
+
+ printf_P(PSTR("\n sizeof(status)=%d "), sizeof(status));
+
// trigger for debugging
PORTB &= ~(1 << PB0);
DDRB |= ( 1 << PB0);
-
+
PRR &= (1 << PRSPI);
+
+ // nCs
PORTA |= (1 << PA4);
- DDRA |= (1 << PA4); // SPI nCS
+ DDRA |= (1 << PA4);
// PORTB/DDRB must be configured before SPCR !!
+
PORTB |= (1 << PB4); // nSS must be HIGH, otherwise SPI master will not become active!!
DDRB &= ~(1 << PB6); // MISO
DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); // SPI SCK (=PB7) and SPI MOSI (=PB5)
// GDO0
PORTA |= (1 << PA5);
DDRA &= ~(1 << PA5);
+
+ printf_P(PSTR(" reset CC1101 ... "));
+ if (!resetCC1101()) {
+ printf_P(PSTR("fails"));
+ return;
+ }
+ printf_P(PSTR("OK, init register ... "));;
+ if (!initRegister()) {
+ printf_P(PSTR("fails"));
+ return;
+ }
+ printf_P(PSTR("OK"));
}
void Cc1101::cleanup () {
DDRB &= ~( 1 << PB0);
SPCR = 0;
+ PORTB &= ~(1 << PB4);
DDRB &= ~((1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4));
DDRA &= ~((1 << PA5) | (1 << PA4));
PORTA &= ~((1 << PA5) | (1 << PA4));
}
-
-
-
void Cc1101::setChipEnableLow () {
PORTA &= ~(1 << PA4);
}
return (PINA & (1 << PA5)) != 0;
}
-uint8_t Cc1101::sendSpiByte (uint8_t b) {
- SPDR = b;
- while (!(SPSR & (1<<SPIF))) {}
- return SPDR;
-}
-
-bool Cc1101::waitForMisoLow () {
- timer = 10;
- while (isMisoHigh()) {
- if (timer == 0) {
- return false;
+ bool Cc1101::waitForMisoLow () {
+ timer = 10;
+ while (isMisoHigh()) {
+ if (timer == 0) {
+ return false;
+ }
}
+ return true;
}
- return true;
-}
-bool Cc1101::waitForGD0High () {
- timer = 100;
- while (!isGd0High()) {
- if (timer == 0) {
- return false;
+ bool Cc1101::waitForGD0High () {
+ timer = 100;
+ while (!isGd0High()) {
+ if (timer == 0) {
+ return false;
+ }
}
+ return true;
}
- return true;
-}
-bool Cc1101::waitForGD0Low () {
- timer = 100;
- while (isGd0High()) {
- if (timer == 0) {
- return false;
+ bool Cc1101::waitForGD0Low () {
+ timer = 100;
+ while (isGd0High()) {
+ if (timer == 0) {
+ return false;
+ }
}
+ return true;
}
- return true;
-}
+ bool Cc1101::strobe (StrobeCommand_t command) {
+ bool ok = true;
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ sendSpiByte(command & 0x3f);
+ setChipEnableHigh();
+ return ok;
+ }
+ bool Cc1101::writeRegister (uint8_t addr, uint8_t value) {
+ bool ok = true;
+
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ sendSpiByte(addr);
+ status.spiResponse.byte = sendSpiByte(value);
+ status.spiResponseValid = 1;
+ setChipEnableHigh();
+
+ if (debugPrint.print.writeRegister) {
+ printf_P(PSTR("\n [writeRegister(0x%02x, 0x%02x) -> "), addr, value);
+ if (ok && status.receivePacketStatusValid) {
+ printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte);
+ } else {
+ printf_P(PSTR("ERR]"));
+ }
+ }
-bool Cc1101::writeRegister (uint8_t addr, uint8_t value) {
- bool ok = true;
- timer = 10;
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- sendSpiByte(value);
- setChipEnableHigh();
- return ok;
-}
+ return ok;
+ }
-bool Cc1101::writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
- bool ok = true;
+ bool Cc1101::writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
+ bool ok = true;
+ uint8_t l = length;
+ uint8_t *p = buffer;
+
+ addr = (addr & 0x3f) | 0x40; // write burst
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ sendSpiByte(addr);
+ while (length-- > 0) {
+ sendSpiByte(*buffer++);
+ }
+ setChipEnableHigh();
- printf_P(PSTR(" [writeRegisters(0x%02x): "), addr);
- for (uint8_t i = 0; i < length; i++) {
- printf_P(PSTR(" 0x%02x"), buffer[i]);
- }
- printf_P(PSTR("] "));
-
- addr |= WRITE_BURST;
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- while (length-- > 0) {
- sendSpiByte(*buffer++);
- }
- setChipEnableHigh();
- return ok;
-}
-
-bool Cc1101::strobe (uint8_t strobe) {
- bool ok = true;
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(strobe);
- setChipEnableHigh();
- return ok;
-}
-
-
-bool Cc1101::readRegister (uint8_t addr, uint8_t *value) {
- bool ok = true;
-
- addr |= READ_SINGLE;
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- *value = sendSpiByte(0);
- setChipEnableHigh();
- return ok;
-}
-
-bool Cc1101::readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
- bool ok = true;
-
- addr |= READ_BURST;
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- while (length-- > 0) {
- *buffer++ = sendSpiByte(0);
- }
- setChipEnableHigh();
- return ok;
-}
-
-bool Cc1101::readStatus (uint8_t addr, uint8_t *status) {
- return readRegisters(addr, status, 1);
- // bool ok = true;
-
- // addr |= READ_BURST;
- // setChipEnableLow();
- // ok &= waitForMisoLow();
- // sendSpiByte(addr);
- // *status = sendSpiByte(0);
- // setChipEnableHigh();
- // return ok;
-}
-
-bool Cc1101::sendData (uint8_t *buffer, uint8_t length) {
- bool ok = true;
- ok &= writeRegister(CC1101_TXFIFO, length);
- ok &= writeRegisters(CC1101_TXFIFO, buffer, length);
- ok &= strobe(CC1101_STX); // start sending bytes
- ok &= waitForGD0High();
- ok &= waitForGD0Low();
- ok &= strobe(CC1101_SFTX); //flush TXfifo
- return ok;
-}
-
-bool Cc1101::setReceive () {
- return strobe(CC1101_SRX);
-}
-
-// byte CheckReceiveFlag(void)
-// if(digitalRead(GDO0)) //receive data
-// {
-// while (digitalRead(GDO0));
-// return 1;
-// }
-// else // no data
-// {
-// return 0;
-// }
-// }
-
-bool Cc1101::receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize) {
- bool ok = true;
- uint8_t status[2];
- uint8_t length;
-
- ok &= readStatus(CC1101_RXBYTES, status);
-// printf(" 1-%d", ok);
- if (ok && status[0] & BYTES_IN_RXFIFO) {
-// printf(" 2-%d", ok);
- ok &= readRegister(CC1101_RXFIFO, &length);
-// printf(" 3-%d", ok);
- if (ok && length > 0 && length <= maxBufferSize) {
-// printf(" 4-%d", ok);
- ok &= readRegisters(CC1101_RXFIFO, buffer, length);
-// printf(" 5-%d", ok);
- ok &= readRegisters(CC1101_RXFIFO, status, 2);
-// printf(" 6-%d", ok);
- ok &= strobe(CC1101_SFRX);
-// printf(" 7-%d", ok);
- if (ok) {
- *receivedLength = length;
- return ok;
+ if (debugPrint.print.writeRegisters) {
+ printf_P(PSTR("\n [writeRegisters(0x%02x): "), addr & 0x3f);
+ while (l-- > 0) {
+ printf_P(PSTR(" 0x%02x"), *p++);
+ }
+ printf_P(PSTR(" -> "));
+ if (ok && status.receivePacketStatusValid) {
+ printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte);
+ } else {
+ printf_P(PSTR("ERR]"));
}
}
- }
-// printf(" 8-%d", ok);
- strobe(CC1101_SFRX);
- *receivedLength = 0;
- return false;
-}
-
-bool Cc1101::initModem () {
- bool ok = true;
- SPCR = 0;
-
- setChipEnableLow();
- _delay_ms(1); // _delay_us(20); //?
- setChipEnableHigh();
- _delay_ms(1); //_delay_us(30); //?
- setChipEnableLow();
- timer = 10;
- ok &= waitForMisoLow();
- SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz
- SPDR = CC1101_SRES;
- while (!(SPSR & (1<<SPIF))) {}
- ok &= waitForMisoLow();
- setChipEnableHigh();
-
- _delay_ms(5); // ?
- ok &= initModemConfig(MHZ868);
- uint8_t pa_table[8];
- memcpy_P(pa_table, PMEM_CC1101_PA_TABLE, 8);
- ok &= writeRegisters(CC1101_PATABLE, pa_table, 8);
-
- return ok;
-}
-
-
-bool Cc1101::initModemConfig (InitFrequency f) {
- bool ok = true;
-
- ok &= writeRegister(CC1101_FSCTRL1, 0x08); // frequency synthesizer control 1 (RX frequency)
- ok &= writeRegister(CC1101_FSCTRL0, 0x00); // frequency synthesizer control 0 (RX frequency offset)
-
- switch (f) {
- case MHZ868:
- ok &= writeRegister(CC1101_FREQ2, F2_868); // frequency high byte
- ok &= writeRegister(CC1101_FREQ1, F1_868); // frequency middle byte
- ok &= writeRegister(CC1101_FREQ0, F0_868); // frequency low byte
- break;
-
- case MHZ915:
- ok &= writeRegister(CC1101_FREQ2, F2_915); // frequency high byte
- ok &= writeRegister(CC1101_FREQ1, F1_915); // frequency middle byte
- ok &= writeRegister(CC1101_FREQ0, F0_915); // frequency low byte
- break;
-
- // case MHZ433: // not supported by E07-900MM1DS
- // ok &= writeRegister(CC1101_FREQ2, F2_433);
- // ok &= writeRegister(CC1101_FREQ1, F1_433);
- // ok &= writeRegister(CC1101_FREQ0, F0_433);
- // break;
-
- default: return false;
- }
-
- for (uint8_t i = 0; i < sizeof(PMEM_CC1101_INIT); i += 2) {
- uint16_t w = pgm_read_word(PMEM_CC1101_INIT + i);
- ok &= writeRegister(w & 0xff, w >> 8);
+
+ return ok;
}
- return ok;
-}
-int8_t Cc1101::run (uint8_t subtest) {
- if (subtest == 0) {
- printf_P(PSTR("\n => init CC1101 ... "));
- if (!initModem()) {
- printf_P(PSTR("E1"));
- return -1;
+ bool Cc1101::readRegister (uint8_t addr, uint8_t *value) {
+ bool ok = true;
+ addr = (addr & 0x3f) | 0x80;
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ status.spiResponse.byte = sendSpiByte(addr);
+ status.spiResponseValid = 1;
+ *value = sendSpiByte(0);
+ setChipEnableHigh();
+
+ if (debugPrint.print.readRegister) {
+ printf_P(PSTR("\n [readRegister(0x%02x) -> "), addr & 0x3f);
+ if (ok && status.spiResponseValid) {
+ printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.spiResponse.byte);
+ } else {
+ printf_P(PSTR("ERR]"));
+ }
}
- printf_P(PSTR("done, read Version ... "));
- uint8_t status;
- if (readStatus(CC1101_VERSION, &status)) {
- printf_P(PSTR("0x%02x"), status);
- if (status == 0x14) {
- printf_P(PSTR(" -> OK (CC1101 detected)"));
- } else {
- printf_P(PSTR("E2"));
+ return ok;
+ }
+
+ bool Cc1101::readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
+ bool ok = true;
+
+ uint8_t l = length;
+ uint8_t *p = buffer;
+
+ addr |= 0xc0; // read burst
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ sendSpiByte(addr);
+ while (length-- > 0) {
+ *buffer++ = sendSpiByte(0);
+ }
+ setChipEnableHigh();
+
+ if (debugPrint.print.readRegisters) {
+ printf_P(PSTR("\n [readRegisters(0x%02x, ..., %d)] -> "), addr & 0x3f, l);
+ if (ok) {
+ while (l-- > 0) {
+ printf_P(PSTR(" 0x%02x"), *p++);
}
+ printf_P(PSTR("]"));
} else {
- printf_P(PSTR("E3"));
+ printf_P(PSTR("ERR]"));
}
- return 0;
+ }
+
+ return ok;
+ }
- } else if (subtest == 1) {
- uint8_t value;
- for (uint8_t addr = 0; addr <= 0x3d; addr++) {
- printf_P(PSTR("\n reg 0x%02x: "), addr);
- if (readRegister(addr, &value)) {
- printf_P(PSTR("0x%02x: "), value);
- } else {
- printf_P(PSTR("?"));
- }
+ bool Cc1101::readStatusRegister (StatusAddress_t addr, uint8_t *value) {
+ if (addr < 0x30 || addr > 0x3d) {
+ return false;
+ } else {
+ return readRegisters(addr, value, 1);
}
+ }
- return 0;
-
- } else if (subtest == 2 && mode == Send) {
- uint16_t cnt = 0;
- do {
- MainRadioControlState state = UNKNOWN;
- uint8_t data[48];
- printf_P(PSTR("\n [%04x]: state="), cnt++);
- if (!readStatus(CC1101_MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E1"));
- } else {
- printf_P(PSTR("0x%02x"), state);
- }
- for (uint8_t i = 0; i < sizeof(data); i++) {
- data[i] = i;
- }
- printf_P(PSTR(" --> send 48 bytes ... "));
- if (!sendData(data, sizeof(data))) {
- flashRedLed(100);
- printf_P(PSTR("E1"));
- continue;
+ bool Cc1101::sendData (uint8_t *buffer, uint8_t length) {
+ timer = 10;
+ uint8_t ok = true;
+ uint8_t txbytes;
+ uint8_t states[16]; uint8_t statesIndex = 0;
+ // ok &= writeRegister(0x3f, length);
+ ok &= writeRegisters(0x3f, buffer, length);
+ ok &= readStatusRegister(TXBYTES, &txbytes);
+ ok &= (txbytes == 20);
+ if (ok) {
+ ok &= strobe(STX); // start sending bytes
+ // ok &= waitForGD0High(); // wait for start of SYNC
+ if (ok) {
+ uint8_t lastState = 0;
+ uint8_t state;
+ do {
+ ok &= readStatusRegister(MARCSTATE, &state);
+ if (state != lastState && statesIndex < 16) {
+ states[statesIndex++] = state;
+ }
+ lastState = state;
+ } while (ok && state != 0x13 && timer > 0);
+ ok &= state == 0x13; // check if in state TX
}
- flashGreenLed(100);
- printf_P(PSTR("OK -> state="));
- if (!readStatus(CC1101_MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E1"));
- } else {
- printf_P(PSTR("0x%02x"), state);
+ if (ok) {
+ uint8_t lastTxbytes = 20;
+ do {
+ ok &= readStatusRegister(TXBYTES, &txbytes);
+ if (lastTxbytes != txbytes) {
+ lastTxbytes = txbytes;
+ }
+ } while (ok && txbytes > 0 && timer > 0);
+ ok &= txbytes == 0;
}
- } while (wait(2000) == EOF);
- return 0;
-
- // ------------------------------------------------------------------------
-
- } else if (subtest == 2 && mode == Receive) {
- int key = EOF;
- uint16_t cnt = 0;
- MainRadioControlState state;
- while (key == EOF) {
- printf_P(PSTR("\n [%04x] => start ... "), cnt++);
- setReceive();
+ }
+ if (!ok) {
+ strobe(SFTX); // flush TXfifo
+ } else {
+ uint8_t state;
+ uint8_t lastState = 0;
do {
- state = UNKNOWN;
- if (!readStatus(CC1101_MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E1"));
- _delay_ms(500);
- break;
- }
- if (wait(0) != EOF) {
- printf_P(PSTR("cancelled"));
- _delay_ms(500);
- return -1;
+ ok &= readStatusRegister(MARCSTATE, &state);
+ if (lastState != state) {
+ lastState = state;
}
- if (state == IDLE) {
- printf_P(PSTR("? (IDLE)"));
- _delay_ms(500);
- break;
- }
-
- } while (state != RX && state != RXFIFO_OVERFLOW);
+ } while (ok && state != 0x01 && timer > 0);
+ ok &= state == 0x01; // check if in state IDLE
+ }
+ // ok &= waitForGD0Low(); // wait for end of package
- if (state != RX && state != RXFIFO_OVERFLOW) {
- continue;
+ if (ok) {
+ printf_P(PSTR(" States["));
+ for (uint8_t i = 0; i < statesIndex; i++) {
+ printf_P(PSTR(" 0x%02X"), states[i]);
}
+ printf_P(PSTR("] "));
+ }
- printf_P(PSTR("OK, receive ... "));
+ return ok;
+ }
+ bool Cc1101::receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize) {
+ bool ok = true;
+ STATUS_RXBYTES_t status;
+ uint8_t lastLength = 0;
+ uint8_t length = 0;
+ *receivedLength = 0;
+ timer = 50;
+
+ this->status.receivePacketStatusValid = 0;
+ ok &= readStatusRegister(RXBYTES, &status.byte);
+ if (ok && status.rxbytes.num_rxbytes > 0) {
+ length = status.rxbytes.num_rxbytes;
+
do {
- uint8_t length;
- uint8_t data[16];
- if (!readStatus(CC1101_MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E2"));
- _delay_ms(500);
- continue;
- }
- if (wait(0) != EOF) {
- printf_P(PSTR("cancelled"));
- _delay_ms(500);
- continue;
+ _delay_us(400); // 20 Bytes in 4ms -> 200us/Byte -> CC1101 datasheet page 56: "twice that of which RF bytes are recived"
+ lastLength = length;
+ ok &= readStatusRegister(RXBYTES, &status.byte);
+ if (ok) {
+ // printf_P(PSTR(" [rxbytes=%d] "), status.byte);
+ length = status.byte & 0x7f;
}
- if (receiveData(data, &length, sizeof(data))) {
- flashGreenLed(100);
- printf_P(PSTR("OK, %d bytes received: "), length);
- for (uint8_t i = 0; i < length; i++) {
- printf_P(PSTR(" 0x%02x"), data[i]);
+ ok &= timer > 0;
+ } while (ok && lastLength != length);
+
+ if (ok) {
+ uint8_t extraBytesCount = this->status.receivePacketStatusEnabled ? 2 : 0;
+ if ((PACKET_LENGTH + extraBytesCount) != length) {
+ printf_P(PSTR(" ERROR[receive %d bytes, expect %d bytes] "), *receivedLength, PACKET_LENGTH + extraBytesCount);
+ *receivedLength = 0;
+ ok = false;
+ } else {
+ printf_P(PSTR(" OK[receive %d bytes] "), length);
+ *receivedLength = PACKET_LENGTH < maxBufferSize ? length - extraBytesCount : maxBufferSize;
+ ok &= readRegisters(0xff, buffer, *receivedLength);
+ if (!ok) {
+ *receivedLength = 0;
+ } else {
+ length -= *receivedLength;
+ if (length > extraBytesCount) {
+ printf_P(PSTR(" [WARN: buffer to small] "));
+ while (length > extraBytesCount) {
+ uint8_t byte;
+ ok &= readRegister(0xff, &byte);
+ ok = false;
+ length--;
+ }
+ }
+ if (length > 0) {
+ ok &= readRegisters(0xff, this->status.receivedPacketStatus.byte, 2);
+ if (ok) {
+ this->status.receivePacketStatusValid = 1;
+ }
+ }
}
- printf_P(PSTR(" ... "));
}
+ }
+ }
+ ok &= strobe(SFRX);
+
+ return ok;
+ }
- } while (state == RX || state == RXFIFO_OVERFLOW);
- printf_P(PSTR("done (state=0x%02x)"), state);
+ void Cc1101::printRegisters () {
+ const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
+ printf_P(PSTR("\n"));
+ for (uint8_t addr = 0; addr < sizeof(Register_t); addr++) {
+ bool ok = true;
+ uint8_t regValue, value;
+ memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1);
+ ok &= readRegister(addr, &value);
+ if (value != regValue) { printf_P(PSTR(" != 0x%02x"), regValue); }
}
- return 0;
+ uint8_t data[8];
+ for (uint8_t addr = 0x30; addr <= 0x3d; addr++) {
+ readStatusRegister((StatusAddress_t)addr, data);
+ }
+ readRegisters(0x3e, data, 8); // PATABLE
+ }
+
+ bool Cc1101::resetCC1101 () {
+ bool ok = true;
+ setChipEnableLow();
+ _delay_us(10);
+ setChipEnableHigh();
+ _delay_us(50);
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ ok &= strobe(SRES);
+ ok &= waitForMisoLow();
+
+
+ return ok;
+ }
+
+ bool Cc1101::initRegister () {
+ const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
+ bool ok = true;
+ DebugPrint_t tmp = debugPrint.print;
+ debugPrint.byte = 0xff; // print all
+ printRegisters();
+
+ for (uint8_t addr = 0; ok && addr < sizeof(Register_t); addr++) {
+ uint8_t regValue;
+ memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1);
+ ok &= writeRegister(addr, regValue);
+ if ((addr == 0x07) && (regValue & 0x04)) {
+ status.receivePacketStatusEnabled = true;
+ }
+ }
+
+ printRegisters();
+ debugPrint.print = tmp;
+ return ok;
+ }
+
+#endif
- // } else if (subtest == 4) {
- // return 0;
-
- // } else if (subtest == 5) {
- // do {
- // uint8_t status;
- // printf_P(PSTR("\n => status: "));
- // if (readStatus(CC1101_MARCSTATE, &status)) {
- // printf_P(PSTR("0x%02x"), status);
- // } else {
- // printf_P(PSTR("E6"));
- // }
- // } while (wait(2000) == EOF);
- }
-
- return -1;
-}
-#endif
\ No newline at end of file
class Cc1101 : public TestUnit {
public:
- typedef enum { MHZ915, MHZ433, MHZ868 } InitFrequency;
- typedef enum { Send, Receive, Test } Cc1101Mode;
+ #define PACKET_LENGTH 20
public:
- Cc1101 (Cc1101Mode mode) { this->mode = mode; };
+ typedef enum { Test, Send, Receive } Cc1101Mode;
+ typedef enum { _IDLE = 0, _RX = 1, _TX = 2, _FSTXON = 3, _CALIBRATE = 4, _SETTLING = 5, _RXFIFO_OVFL = 6, _TXFIFO_UNFL = 7 } StatusState_t;
+ typedef struct { uint8_t fifoBytes:4; StatusState_t state:3; uint8_t chipNotReady:1; } Status_t;
+ typedef struct { uint8_t rssi:8; uint8_t lqi:7; uint8_t crcOk:1; } ReceivedPacketStatus_t; // CC1101 datasheet page 37
+ union {
+ struct {
+ union {
+ Status_t value;
+ uint8_t byte;
+ } spiResponse;
+ union {
+ ReceivedPacketStatus_t value;
+ uint8_t byte [2];
+ } receivedPacketStatus;
+ uint8_t spiResponseValid: 1;
+ uint8_t receivePacketStatusEnabled:1;
+ uint8_t receivePacketStatusValid:1;
+ };
+ uint32_t dword;
+ } status;
+
+ public:
+ Cc1101 (Cc1101Mode mode) { timer = 0; this->mode = mode; status.dword = 0; }
virtual void init ();
virtual void cleanup ();
virtual int8_t run (uint8_t subtest);
void tick1ms () { if (timer > 0) timer--; };
private:
+ typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SFRX = 0x3a, SFTX = 0x3b, SIDLE = 0x36 } StrobeCommand_t;
+ typedef enum { MARCSTATE = 0x35, TXBYTES = 0x3A, RXBYTES = 0x3B } StatusAddress_t;
+ typedef struct { uint8_t writeRegister:1; uint8_t writeRegisters:1; uint8_t readRegister:1; uint8_t readRegisters:1; } DebugPrint_t;
+
+ private:
+ int8_t runSend (uint8_t subtest);
+ int8_t runReceive (uint8_t subtest);
+ int8_t runTest (uint8_t subtest);
+ uint8_t sendSpiByte (uint8_t b);
void triggerOn();
void triggerOff();
- bool initModem ();
- bool initModemConfig (InitFrequency f);
+ void triggerToggle ();
void setChipEnableLow ();
void setChipEnableHigh ();
bool isMisoHigh ();
bool waitForMisoLow ();
bool waitForGD0High ();
bool waitForGD0Low ();
- uint8_t sendSpiByte (uint8_t b);
+ bool strobe (StrobeCommand_t strobe);
bool writeRegister (uint8_t addr, uint8_t value);
bool writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length);
- bool strobe (uint8_t strobe);
- bool readStatus (uint8_t addr, uint8_t *status);
bool readRegister (uint8_t addr, uint8_t *value);
bool readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length);
+ bool readStatusRegister (StatusAddress_t addr, uint8_t *value);
bool sendData (uint8_t *buffer, uint8_t length);
- bool setReceive ();
bool receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize);
- //bool isReceiveFlagSet ();
+ void printRegisters ();
+
+ bool resetCC1101 ();
+ bool initRegister ();
+
private:
Cc1101Mode mode;
uint8_t timer;
+ union {
+ DebugPrint_t print;
+ uint8_t byte;
+ } debugPrint;
+
public:
+ typedef enum {
+ IOCFG2 = 0x00, IOCFG1 = 0x01, IOCFG0 = 0x02,
+ FIFOTHR = 0x03,
+ SYNC1 = 0x04, SYNC0 = 0x05,
+ PKTLEN = 0x06,
+ PKTCTRL1 = 0x07, PKTCTRL0 = 0x08
+ } RegisterAddress_t;
-
- private:
+ typedef enum {
+ RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x00,
+ RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD_OR_END_OF_PACKAGE_UNTIL_FIFO_EMPTY = 0x01,
+ TX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x02,
+ TX_FIFO_FULL_UNTIL_BELOW_THRESHHOLD = 0x03,
+ RX_FIFO_OVERFLOW_UNTIL_FIFO_FLUSHED = 0x04,
+ TX_FIFO_UNDERFLOW_UNTIL_FIFO_FLUSHED = 0x05,
+ SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET = 0x06,
+ PACKET_RECEIVED_WITH_CRC_OK_UNTIL_FIRST_BYTE_READ_FROM_RXFIFO = 0x07,
+ PREAMBLE_QUALITY_REACHED_UNTIL_REENTER_RX = 0x08,
+ RSSI_LEVEL_BELOW_THRESHOLD = 0x09,
+ LOCK_DETECTOR_OUTPUT = 0x0a,
+ SERIAL_CLOCK = 0x0b,
+ SERIAL_SYNCHRONOUS_DATA_OUTPUT = 0x0c,
+ SERIAL_ASYNC_DATA_OUTPUT = 0x0d,
+ CARRIER_DETECTED_UNTIL_ENTER_IDLE = 0x0e,
+ CRC_OK_UNTIL_REENTER_RX = 0x0f,
+ RX_HARD_DATA_1 = 0x16,
+ RX_HARD_DATA_0 = 0x17,
+ PA_PD = 0x1b,
+ LNA_PD = 0x1c,
+ RX_SYMBOL_TICK = 0x1d,
+ WAKEUP_ON_RECEIVE_EVENT0 = 0x24,
+ WAKEUP_ON_RECEIVE_EVENT1 = 0x25,
+ CLK_256 = 0x26,
+ CLK_32K = 0x27,
+ CHIP_NOT_READY = 0x29,
+ XOSC_STABLE = 0x2b,
+ HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH = 0x2e,
+ HW_TO_0 = 0x2f,
+ CLK_XOSC = 0x30,
+ CLK_XOSC_DIV_1P5 = 0x31,
+ CLK_XOSC_DIV_2 = 0x32,
+ CLK_XOSC_DIV_3 = 0x33,
+ CLK_XOSC_DIV_4 = 0x34,
+ CLK_XOSC_DIV_6 = 0x35,
+ CLK_XOSC_DIV_8 = 0x36,
+ CLK_XOSC_DIV_12 = 0x37,
+ CLK_XOSC_DIV_16 = 0x38,
+ CLK_XOSC_DIV_24 = 0x39,
+ CLK_XOSC_DIV_32 = 0x3a,
+ CLK_XOSC_DIV_48 = 0x3b,
+ CLK_XOSC_DIV_64 = 0x3c,
+ CLK_XOSC_DIV_96 = 0x3d,
+ CLK_XOSC_DIV_128 = 0x3e,
+ CLK_XOSC_DIV_192 = 0x3f
+ } GDOx_CFG_t;
- enum MainRadioControlState {
+ typedef enum {
SLEEP = 0,
IDLE = 1,
XOFF = 2,
RXTX_SETTLING = 21,
TXFIFO_UNDERFLOW = 22,
UNKNOWN = 255
- };
-
-
- #define WRITE_BURST 0x40
- #define READ_SINGLE 0x80
- #define READ_BURST 0xC0
- #define BYTES_IN_RXFIFO 0x7F
-
- // Init constants
- // #define F_915 0x00
- // #define F_433 0x01
- // #define F_868 0x02
-
- // Register values for different frequencies
- // Carrier frequency = 868 MHz
- #define F2_868 0x21
- #define F1_868 0x62
- #define F0_868 0x76
- // Carrier frequency = 902 MHz
- #define F2_915 0x22
- #define F1_915 0xB1
- #define F0_915 0x3B
- // Carrier frequency = 433 MHz
- #define F2_433 0x10
- #define F1_433 0xA7
- #define F0_433 0x62
-
- //***************************************CC1101 define**************************************************//
- // CC1101 CONFIG REGSITER
- #define CC1101_IOCFG2 0x00 // GDO2 output pin configuration
- #define CC1101_IOCFG1 0x01 // GDO1 output pin configuration
- #define CC1101_IOCFG0 0x02 // GDO0 output pin configuration
- #define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
- #define CC1101_SYNC1 0x04 // Sync word, high INT8U
- #define CC1101_SYNC0 0x05 // Sync word, low INT8U
- #define CC1101_PKTLEN 0x06 // Packet length
- #define CC1101_PKTCTRL1 0x07 // Packet automation control
- #define CC1101_PKTCTRL0 0x08 // Packet automation control
- #define CC1101_ADDR 0x09 // Device address
- #define CC1101_CHANNR 0x0A // Channel number
- #define CC1101_FSCTRL1 0x0B // Frequency synthesizer control
- #define CC1101_FSCTRL0 0x0C // Frequency synthesizer control
- #define CC1101_FREQ2 0x0D // Frequency control word, high INT8U
- #define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U
- #define CC1101_FREQ0 0x0F // Frequency control word, low INT8U
- #define CC1101_MDMCFG4 0x10 // Modem configuration
- #define CC1101_MDMCFG3 0x11 // Modem configuration
- #define CC1101_MDMCFG2 0x12 // Modem configuration
- #define CC1101_MDMCFG1 0x13 // Modem configuration
- #define CC1101_MDMCFG0 0x14 // Modem configuration
- #define CC1101_DEVIATN 0x15 // Modem deviation setting
- #define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration
- #define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration
- #define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration
- #define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration
- #define CC1101_BSCFG 0x1A // Bit Synchronization configuration
- #define CC1101_AGCCTRL2 0x1B // AGC control
- #define CC1101_AGCCTRL1 0x1C // AGC control
- #define CC1101_AGCCTRL0 0x1D // AGC control
- #define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout
- #define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout
- #define CC1101_WORCTRL 0x20 // Wake On Radio control
- #define CC1101_FREND1 0x21 // Front end RX configuration
- #define CC1101_FREND0 0x22 // Front end TX configuration
- #define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration
- #define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration
- #define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration
- #define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration
- #define CC1101_RCCTRL1 0x27 // RC oscillator configuration
- #define CC1101_RCCTRL0 0x28 // RC oscillator configuration
- #define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control
- #define CC1101_PTEST 0x2A // Production test
- #define CC1101_AGCTEST 0x2B // AGC test
- #define CC1101_TEST2 0x2C // Various test settings
- #define CC1101_TEST1 0x2D // Various test settings
- #define CC1101_TEST0 0x2E // Various test settings
-
- //CC1101 Strobe commands
- #define CC1101_SRES 0x30 // Reset chip.
- #define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
- // If in RX/TX: Go to a wait state where only the synthesizer is
- // running (for quick RX / TX turnaround).
- #define CC1101_SXOFF 0x32 // Turn off crystal oscillator.
- #define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
- // (enables quick start).
- #define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
- // MCSM0.FS_AUTOCAL=1.
- #define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
- // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
- // Only go to TX if channel is clear.
- #define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
- // Wake-On-Radio mode if applicable.
- #define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
- #define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
- #define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high.
- #define CC1101_SFRX 0x3A // Flush the RX FIFO buffer.
- #define CC1101_SFTX 0x3B // Flush the TX FIFO buffer.
- #define CC1101_SWORRST 0x3C // Reset real time clock.
- #define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two
- // INT8Us for simpler software.
- //CC1101 STATUS REGSITER
- #define CC1101_PARTNUM 0x30
- #define CC1101_VERSION 0x31
- #define CC1101_FREQEST 0x32
- #define CC1101_LQI 0x33
- #define CC1101_RSSI 0x34
- #define CC1101_MARCSTATE 0x35
- #define CC1101_WORTIME1 0x36
- #define CC1101_WORTIME0 0x37
- #define CC1101_PKTSTATUS 0x38
- #define CC1101_VCO_VC_DAC 0x39
- #define CC1101_TXBYTES 0x3A
- #define CC1101_RXBYTES 0x3B
-
- //CC1101 PATABLE,TXFIFO,RXFIFO
- #define CC1101_PATABLE 0x3E
- #define CC1101_TXFIFO 0x3F
- #define CC1101_RXFIFO 0x3F
+ } MainRadioControlState;
+
+ typedef enum { NO_ADDR_CHECK = 0, CHECK_NO_BROADCAST = 1, CHECK_WITH_BROADCAST_0 = 2, CHECK_WITH_BROADCAST_0_AND_255 = 3 } ADR_CHK_t;
+ typedef enum { FIXED = 0, VARIABLE = 1, INFINITE = 2 } LENGTH_CONFIG_t;
+ typedef enum { NORMAL_USE_FIFO = 0, SYNC_SERIAL = 1, RANDOM_TX = 2, ASYNC_SERIAL = 3 } PKT_FORMAT_t;
+ typedef enum { FSK2 = 0, GFSK = 1, ASK_OOK = 3, FSK4 = 4, MSK = 7 } MOD_FORMAT_t;
+ typedef enum { NO_SYNC = 0, SYNC_15_16 = 1, SYNC_16_16 = 2, SYNC_30_32 = 3, CARRIER_SENSE = 4, SYNC_15_16_CARRIER_SENSE = 5, SYNC_16_16_CARRIER_SENSE = 6 , SYNC_30_326_CARRIER_SENSE = 7} SYNC_MODE_t;
+ typedef enum { TWO = 0, THREE = 1, FOUR = 2, SIX = 3, EIGHT = 4, TWELVE = 5, SIXTEEN = 6, TWENTYFOUR = 7 } NUM_PREAMBLE_t;
+ typedef enum { TXOFF_IDLE = 0, TXOFF_FSTXON = 1, STAY_IN_TX = 2, TXOFF_RX = 3 } TXOFF_MODE_t;
+ typedef enum { RXOFF_IDLE = 0, RXOFF_FSTXON = 1, RXOFF_TX = 2, STAY_IN_RX = 3 } RXOFF_MODE_t;
+ typedef enum { ALWAYS = 0, RSSI_BELOW_THRESHOLD = 1, UNLESS_RECEIVE_PACKET = 2, RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET = 3 } CCA_MODE_t;
+ typedef enum { NEVER = 0, IDLE_TO_RX_OR_TX = 1, RX_OR_TX_TO_IDLE = 2, RX_OR_TX_TO_IDLE_EVERY_4_TIME = 3 } FS_AUTOCAL_t;
+
+ typedef struct { GDOx_CFG_t gdo0_cfg:6; uint8_t gdo0_inv:1; uint8_t bit7:1; } IOCFG0_t;
+ typedef struct { GDOx_CFG_t gdo1_cfg:6; uint8_t gdo1_inv:1; uint8_t bit7:1; } IOCFG1_t;
+ typedef struct { GDOx_CFG_t gdo2_cfg:6; uint8_t gdo2_inv:1; uint8_t bit7:1; } IOCFG2_t;
+ typedef struct { uint8_t fifo_thr:4; uint8_t close_in_rx:2; uint8_t adc_retention:1; uint8_t bit7:1; } FIFOTHR_t;
+ typedef struct { ADR_CHK_t adr_chk:2; uint8_t append_status:1; uint8_t crc_autoflush:1; uint8_t bit4:1; uint8_t pqt:3; } PKTCTRL1_t;
+ typedef struct { LENGTH_CONFIG_t length_config:2; uint8_t crc_en:1; uint8_t bit3:1; PKT_FORMAT_t pkt_format:2; uint8_t white_data:1; uint8_t bit7:1; } PKTCTRL0_t;
+ typedef struct { uint8_t frequ_if:5; uint8_t bit5:1; uint8_t bit76:2; } FSCTRL1_t;
+ typedef struct { uint8_t frequoff:8; } FSCTRL0_t;
+ typedef struct { uint8_t drate_e:4; uint8_t chanbw_m:2; uint8_t chanbw_e:2; } MDMCFG4_t;
+ typedef struct { uint8_t drate_m:8; } MDMCFG3_t;
+ typedef struct { SYNC_MODE_t sync_mode:3; uint8_t manchester_en:1; MOD_FORMAT_t mod_format:3; uint8_t dem_dcfilt_off:1; } MDMCFG2_t;
+ typedef struct { uint8_t chanspc_e:2; uint8_t bit32:2; NUM_PREAMBLE_t num_preamble:3; uint8_t fec_en:1; } MDMCFG1_t;
+ typedef struct { uint8_t chanspc_m:8; } MDMCFG0_t;
+ typedef struct { uint8_t deviation_m:3; uint8_t bit3:1; uint8_t deviation_e:3; uint8_t bit7:1; } DEVIATN_t;
+ typedef struct { uint8_t rx_time:3; uint8_t rx_time_qual:1; uint8_t rx_time_rssi:1; uint8_t bit765:3; } MCSM2_t;
+ typedef struct { TXOFF_MODE_t txoff_mode:2; RXOFF_MODE_t rxoff_mode:2; CCA_MODE_t cca_mode:2; uint8_t bit76:2; } MCSM1_t;
+ typedef struct { uint8_t xosc_force_on:1; uint8_t pin_ctrl_en:1; uint8_t po_timeout:2; FS_AUTOCAL_t fs_autocal:2; uint8_t bit76:2; } MCSM0_t;
+
+ typedef union {
+ uint8_t byte;
+ struct {
+ uint8_t num_rxbytes:7;
+ uint8_t rxfifo_overflow:1;
+ } rxbytes;
+ } STATUS_RXBYTES_t;
+
+ typedef struct {
+ IOCFG2_t iocfg2;
+ IOCFG1_t iocfg1;
+ IOCFG0_t iocfg0;
+ FIFOTHR_t fifothr;
+ uint8_t sync1;
+ uint8_t sync0;
+ uint8_t pktlen;
+ PKTCTRL1_t pktctrl1;
+ PKTCTRL0_t pktctrl0;
+ uint8_t addr;
+ uint8_t channr;
+ FSCTRL1_t fsctrl1;
+ FSCTRL0_t fsctrl0;
+ uint8_t frequ2;
+ uint8_t frequ1;
+ uint8_t frequ0;
+ MDMCFG4_t mdmcfg4;
+ MDMCFG3_t mdmcfg3;
+ MDMCFG2_t mdmcfg2;
+ MDMCFG1_t mdmcfg1;
+ MDMCFG0_t mdmcfg0;
+ DEVIATN_t deviatn;
+ MCSM2_t mcsm2;
+ MCSM1_t mcsm1;
+ MCSM0_t mcsm0;
+ uint8_t foccfg;
+ uint8_t bscfg;
+ uint8_t agcctrl2;
+ uint8_t agcctrl1;
+ uint8_t agcctrl0;
+ uint8_t worevt1;
+ uint8_t worevt0;
+ uint8_t worctrl;
+ uint8_t frend1;
+ uint8_t frend0;
+ uint8_t fscal3;
+ uint8_t fscal2;
+ uint8_t fscal1;
+ uint8_t fscal0;
+ uint8_t rcctrl1;
+ uint8_t rcctrl0;
+ uint8_t fstest;
+ uint8_t ptest;
+ uint8_t agctest;
+ uint8_t test2;
+ uint8_t test1;
+ uint8_t test0;
+
+ } Register_t;
+
+
};
+++ /dev/null
-#include <stdio.h>
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include <util/delay.h>
-
-#include "cc1101new.hpp"
-#include "../main.hpp"
-
-// 868MHz Modem E07-900MM1DS (chipset CC1101)
-// https://jlcpcb.com/partdetail/Chengdu_Ebyte_ElecTech-E07900MM10S/C5844212
-
-#ifdef __AVR_ATmega328P__
-
- // Arduino-Nano-5V
- // ------------------------------------
- // not available
-
- void Cc1101New::init () {}
- void Cc1101New::cleanup () {}
- void Cc1101New::setChipEnableLow () {}
- void Cc1101New::setChipEnableHigh () {}
- int8_t Cc1101New::run (uint8_t subtest) { return -1; }
- PGM_P Cc1101New::getName () { return PSTR("?"); }
-
-#endif
-
-
-#ifdef __AVR_ATmega644P__
-
- // Nano-644
- // --------------------------------------------------------
- // PA4 ... nCS
- // PB4 ... nSS (not used, but must be high, otherwise AVR SPI master not working)
- // PB5 ... MOSI
- // PB6 ... MISO
- // PB7 ... SCK
-
- int8_t Cc1101New::runSend (uint8_t subtest) {
- if (subtest == 0) {
- bool ok = true;
- GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET;
- ok &= writeRegister(0x02, cfg0);
- return ok;
- } else if (subtest > 1) {
- return -1;
- }
-
- uint16_t cnt = 0;
- do {
- MainRadioControlState state = UNKNOWN;
- uint8_t data[PACKET_LENGTH];
- printf_P(PSTR("\n [%04x]: state="), cnt++);
- if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E1"));
- } else {
- printf_P(PSTR("0x%02x"), state);
- }
- printf_P(PSTR(" --> send %d bytes (HEX:"), sizeof(data));
- for (uint8_t i = 0; i < sizeof(data); i++) {
- data[i] = uint8_t((cnt + i) & 0xff);
- printf_P(PSTR(" %02X"), data[i]);
- }
- printf_P(PSTR("] -> "));
-
- if (!sendData(data, sizeof(data))) {
- flashRedLed(100);
- printf_P(PSTR("E1"));
- continue;
- }
- flashGreenLed(100);
- printf_P(PSTR("OK"));
- } while (wait(2000) == EOF);
-
- return 0;
- }
-
- int8_t Cc1101New::runReceive (uint8_t subtest) {
- if (subtest == 0) {
- bool ok = true;
- GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET;
- ok &= writeRegister(0x02, cfg0);
- return ok;
- } else if (subtest > 1) {
- return -1;
- }
-
- int key = EOF;
- uint16_t cnt = 0;
- MainRadioControlState state;
- while (key == EOF) {
- printf_P(PSTR("\n [%04x] => start ... "), cnt++);
- strobe(SRX);
- do {
- state = UNKNOWN;
- if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E1"));
- _delay_ms(500);
- break;
- }
- if (wait(0) != EOF) {
- printf_P(PSTR("cancelled"));
- _delay_ms(500);
- break;
- }
- if (state == IDLE) {
- printf_P(PSTR("? (IDLE)"));
- _delay_ms(500);
- break;
- }
-
- } while (state != RX && state != RXFIFO_OVERFLOW);
-
- if (state != RX && state != RXFIFO_OVERFLOW) {
- continue;
- }
- printf_P(PSTR("OK, receive ... "));
-
- uint8_t length;
- uint8_t lastLength = 0xff;
- do {
- uint8_t data[PACKET_LENGTH];
- if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E2"));
- _delay_ms(500);
- continue;
- }
- if (wait(0) != EOF) {
- printf_P(PSTR("cancelled"));
- _delay_ms(500);
- return -1;
- }
- if (!readStatusRegister(RXBYTES, (uint8_t *)&length)) {
- printf_P(PSTR("E2"));
- _delay_ms(500);
- continue;
- }
- if (lastLength != length) {
- lastLength = length;
- }
- if (length >= PACKET_LENGTH) {
- if (receiveData(data, &length, sizeof(data))) {
- if (length > 0) {
- flashGreenLed(100);
- printf_P(PSTR(" -> "));
- if (status.receivePacketStatusValid) {
- printf_P(PSTR(" RSSI=%d, LQI=%d, CRC "), status.receivedPacketStatus.value.rssi, status.receivedPacketStatus.value.lqi);
- if (status.receivedPacketStatus.value.crcOk) {
- printf_P(PSTR("OK, "));
- } else {
- printf_P(PSTR("ERROR, "));
- }
- }
- printf_P(PSTR("%d data bytes (HEX): "), length);
- for (uint8_t i = 0; i < length; i++) {
- printf_P(PSTR(" %02X"), data[i]);
- }
- printf_P(PSTR(" ... "));
- }
- }
- }
-
- } while (state == RX || state == RXFIFO_OVERFLOW);
-
- printf_P(PSTR("done (state=0x%02x)"), state);
- }
- return -1;
- }
-
- int8_t Cc1101New::runTest (uint8_t subtest) {
- if (subtest > 0) {
- return -1;
- }
- while (wait(0) == EOF) {}
- return -1;
- }
-
-
- int8_t Cc1101New::run (uint8_t subtest) {
- switch (mode) {
- case Send: return runSend(subtest);
- case Receive: return runReceive(subtest);
- case Test: return runTest(subtest);
- default: return -1;
- }
- }
-
- // --------------------------------------------------------
-
- const Cc1101New::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = {
- /* 0x00: iocfg2 0x0b (----) */ { Cc1101New::CHIP_NOT_READY, 0, 0 }, // GDO2
- /* 0x01: iocfg1 0x2e (----) */ { Cc1101New::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO
- /* 0x02: iocfg0 0x06 (----) */ { Cc1101New::SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET, 0, 0 }, // GDO0 -> PA5
- /* 0x03: fifothr 0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0)
- /* 0x04: sync1 0x7a (0xd3) */ 0x7a,
- /* 0x05: sync0 0x0e (0x91) */ 0x0e,
- /* 0x06: pktlen 0x14 (0x3d) */ PACKET_LENGTH,
- /* 0x07: pktctrl1 0x04 (----) */ { Cc1101New::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
- /* 0x08: pktctrl0 0x05 (----) */ { Cc1101New::FIXED, 1, 0, Cc1101New::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0)
- /* 0x09: addr 0x00 (----) */ 0x00,
- /* 0x0a: channr 0x00 (----) */ 0x00,
- /* 0x0b: fsctrl1 0x06 (0x08) */ { 6, 0, 0 }, // frqu_if=6, (bit5=0), (bit76=0b00)
- /* 0x0c: fsctrl0 0x00 (----) */ { 0 }, // freqoff = 0
- /* 0x0d: frequ2 0x21 (----) */ 0x21,
- /* 0x0e: frequ1 0x62 (----) */ 0x62,
- /* 0x0f: frequ0 0x76 (----) */ 0x76,
- /* 0x10: mdmcfg4 0xca (0x5b) */ { 0x0a, 0, 3 }, // drate_e=0x0a, chanbw_m=0, chanbw_e=3
- /* 0x11: mdmcfg3 0xf8 (----) */ { 0xf8 }, // drate_m=0xf8
- /* 0x12: mdmcfg2 0x16 (0x03) */ { Cc1101New::SYNC_16_16_CARRIER_SENSE, 0, Cc1101New::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0
- /* 0x13: mdmcfg1 0x22 (----) */ { 2, 0, Cc1101New::FOUR, 0 }, // chanspc_e=0b10, bit32=0, num_preamble=0b010, fec_en=0
- /* 0x14: mdmcfg0 0xf8 (----) */ { 0xf8 }, // chanspc_m = 0x08
- /* 0x15: deviatn 0x40 (0x47) */ { 0, 0, 4, 0 }, // deviation_m=0, (bit3=0), deviation_e=4, (bit7=0)
- /* 0x16: mcsm2 0x07 (----) */ { 7, 0, 0, 0 }, // rx_time=7 (NA), rx_time_qual=0, rx_time_rssi=0, (bit76=0b00)
- /* 0x17: mcsm1 0x30 (----) */ { Cc1101New::TXOFF_IDLE, Cc1101New::RXOFF_IDLE, Cc1101New::RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET, 0 }, // mcsm1 (txoff_mode=0b00, rxoff_mode=0b00, cca_mode=0b11, (bit76=0b00) )
- /* 0x18: mcsm0 0x18 (----) */ { 0, 0, 2, Cc1101New::IDLE_TO_RX_OR_TX, 0 }, // xosc_force_on=0, pin_ctrl_en=0, po_timeout=2 (149-155us), fs_autocal=0b01, (bit76=0b00)
- /* 0x19: foccfg 0x16 (0x1d) */ 0x16,
- /* 0x1a: bscfg 0x6c (0x1c) */ 0x6c,
- /* 0x1b: agcctrl2 0x43 (0xc7) */ 0x43,
- /* 0x1c: agcctrl1 0x49 (0x00) */ 0x49,
- /* 0x1d: agcctrl0 0x91 (0xb2) */ 0x91,
- /* 0x1e: worevt1 0x87 (----) */ 0x87,
- /* 0x1f: worevt0 0x6b (----) */ 0x6b,
- /* 0x20: worctrl 0xfb (0xf8) */ 0xfb,
- /* 0x21: frend1 0x56 (0xb6) */ 0x56,
- /* 0x22: frend0 0x10 (----) */ 0x10,
- /* 0x23: fscal3 0xe9 (0xea) */ 0xe9,
- /* 0x24: fscal2 0x2a (----) */ 0x2a,
- /* 0x25: fscal1 0x00 (----) */ 0x00,
- /* 0x26: fscal0 0x1f (0x11) */ 0x1f,
- /* 0x27: rcctrl1 0x41 (----) */ 0x41,
- /* 0x28: rcctrl0 0x00 (----) */ 0x00,
- /* 0x29: fstest 0x59 (----) */ 0x59,
- /* 0x2a: ptest 0x7f (----) */ 0x7f,
- /* 0x2b: agctest 0x3f (----) */ 0x3f,
- /* 0x2c: test2 0x81 (0x88) */ 0x81,
- /* 0x2d: test1 0x35 (0x31) */ 0x35,
- /* 0x2e: test0 0x09 (0x0b) */ 0x09
- };
-
- uint8_t Cc1101New::sendSpiByte (uint8_t b) {
- SPDR = b;
- while (!(SPSR & (1<<SPIF))) {}
- return SPDR;
- }
-
- void Cc1101New::triggerOn () {
- PORTB |= (1 << PB0);
- }
-
- void Cc1101New::triggerOff () {
- PORTB &= ~(1 << PB0);
- }
-
- void Cc1101New::triggerToggle () {
- PORTB ^= (1 << PB0);
- }
-
- PGM_P Cc1101New::getName () {
- switch (mode) {
- case Send: return PSTR("CC-1101-New-Send");
- case Receive: return PSTR("CC-1101-New-Receive");
- case Test: return PSTR("CC-1101-New-Test");
- default: return PSTR("CC-1101-New-?");
- }
- }
-
- void Cc1101New::init () {
-
- printf_P(PSTR("\n sizeof(status)=%d "), sizeof(status));
-
- // trigger for debugging
- PORTB &= ~(1 << PB0);
- DDRB |= ( 1 << PB0);
-
- PRR &= (1 << PRSPI);
-
- // nCs
- PORTA |= (1 << PA4);
- DDRA |= (1 << PA4);
- // PORTB/DDRB must be configured before SPCR !!
-
- PORTB |= (1 << PB4); // nSS must be HIGH, otherwise SPI master will not become active!!
- DDRB &= ~(1 << PB6); // MISO
- DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); // SPI SCK (=PB7) and SPI MOSI (=PB5)
-
- // SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=12MHz/128=93,75kHz
- SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz
-
- // GDO0
- PORTA |= (1 << PA5);
- DDRA &= ~(1 << PA5);
-
- printf_P(PSTR(" reset CC1101 ... "));
- if (!resetCC1101()) {
- printf_P(PSTR("fails"));
- return;
- }
- printf_P(PSTR("OK, init register ... "));;
- if (!initRegister()) {
- printf_P(PSTR("fails"));
- return;
- }
- printf_P(PSTR("OK"));
- }
-
- void Cc1101New::cleanup () {
- // trigger for debugging
- PORTB &= ~(1 << PB0);
- DDRB &= ~( 1 << PB0);
-
- SPCR = 0;
- PORTB &= ~(1 << PB4);
- DDRB &= ~((1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4));
- DDRA &= ~((1 << PA5) | (1 << PA4));
- PORTA &= ~((1 << PA5) | (1 << PA4));
- }
-
- void Cc1101New::setChipEnableLow () {
- PORTA &= ~(1 << PA4);
- }
-
- void Cc1101New::setChipEnableHigh () {
- PORTA |= (1 << PA4);
- }
-
- bool Cc1101New::isMisoHigh () {
- return (PINB & (1 << PB6)) != 0;
- }
-
- bool Cc1101New::isGd0High () {
- return (PINA & (1 << PA5)) != 0;
- }
-
- bool Cc1101New::waitForMisoLow () {
- timer = 10;
- while (isMisoHigh()) {
- if (timer == 0) {
- return false;
- }
- }
- return true;
- }
-
- bool Cc1101New::waitForGD0High () {
- timer = 100;
- while (!isGd0High()) {
- if (timer == 0) {
- return false;
- }
- }
- return true;
- }
-
- bool Cc1101New::waitForGD0Low () {
- timer = 100;
- while (isGd0High()) {
- if (timer == 0) {
- return false;
- }
- }
- return true;
- }
-
- bool Cc1101New::strobe (StrobeCommand_t command) {
- bool ok = true;
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(command & 0x3f);
- setChipEnableHigh();
- return ok;
- }
-
- bool Cc1101New::writeRegister (uint8_t addr, uint8_t value) {
- bool ok = true;
-
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- status.spiResponse.byte = sendSpiByte(value);
- status.spiResponseValid = 1;
- setChipEnableHigh();
-
- if (debugPrint.print.writeRegister) {
- printf_P(PSTR("\n [writeRegister(0x%02x, 0x%02x) -> "), addr, value);
- if (ok && status.receivePacketStatusValid) {
- printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte);
- } else {
- printf_P(PSTR("ERR]"));
- }
- }
-
- return ok;
- }
-
- bool Cc1101New::writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
- bool ok = true;
- uint8_t l = length;
- uint8_t *p = buffer;
-
- addr = (addr & 0x3f) | 0x40; // write burst
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- while (length-- > 0) {
- sendSpiByte(*buffer++);
- }
- setChipEnableHigh();
-
- if (debugPrint.print.writeRegisters) {
- printf_P(PSTR("\n [writeRegisters(0x%02x): "), addr & 0x3f);
- while (l-- > 0) {
- printf_P(PSTR(" 0x%02x"), *p++);
- }
- printf_P(PSTR(" -> "));
- if (ok && status.receivePacketStatusValid) {
- printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte);
- } else {
- printf_P(PSTR("ERR]"));
- }
- }
-
- return ok;
- }
-
-
- bool Cc1101New::readRegister (uint8_t addr, uint8_t *value) {
- bool ok = true;
- addr = (addr & 0x3f) | 0x80;
- setChipEnableLow();
- ok &= waitForMisoLow();
- status.spiResponse.byte = sendSpiByte(addr);
- status.spiResponseValid = 1;
- *value = sendSpiByte(0);
- setChipEnableHigh();
-
- if (debugPrint.print.readRegister) {
- printf_P(PSTR("\n [readRegister(0x%02x) -> "), addr & 0x3f);
- if (ok && status.spiResponseValid) {
- printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.spiResponse.byte);
- } else {
- printf_P(PSTR("ERR]"));
- }
- }
- return ok;
- }
-
- bool Cc1101New::readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
- bool ok = true;
-
- uint8_t l = length;
- uint8_t *p = buffer;
-
- addr |= 0xc0; // read burst
- setChipEnableLow();
- ok &= waitForMisoLow();
- sendSpiByte(addr);
- while (length-- > 0) {
- *buffer++ = sendSpiByte(0);
- }
- setChipEnableHigh();
-
- if (debugPrint.print.readRegisters) {
- printf_P(PSTR("\n [readRegisters(0x%02x, ..., %d)] -> "), addr & 0x3f, l);
- if (ok) {
- while (l-- > 0) {
- printf_P(PSTR(" 0x%02x"), *p++);
- }
- printf_P(PSTR("]"));
- } else {
- printf_P(PSTR("ERR]"));
- }
- }
-
- return ok;
- }
-
- bool Cc1101New::readStatusRegister (StatusAddress_t addr, uint8_t *value) {
- if (addr < 0x30 || addr > 0x3d) {
- return false;
- } else {
- return readRegisters(addr, value, 1);
- }
- }
-
- bool Cc1101New::sendData (uint8_t *buffer, uint8_t length) {
- timer = 10;
- uint8_t ok = true;
- uint8_t txbytes;
- uint8_t states[16]; uint8_t statesIndex = 0;
- // ok &= writeRegister(0x3f, length);
- ok &= writeRegisters(0x3f, buffer, length);
- ok &= readStatusRegister(TXBYTES, &txbytes);
- ok &= (txbytes == 20);
- if (ok) {
- ok &= strobe(STX); // start sending bytes
- // ok &= waitForGD0High(); // wait for start of SYNC
- if (ok) {
- uint8_t lastState = 0;
- uint8_t state;
- do {
- ok &= readStatusRegister(MARCSTATE, &state);
- if (state != lastState && statesIndex < 16) {
- states[statesIndex++] = state;
- }
- lastState = state;
- } while (ok && state != 0x13 && timer > 0);
- ok &= state == 0x13; // check if in state TX
- }
- if (ok) {
- uint8_t lastTxbytes = 20;
- do {
- ok &= readStatusRegister(TXBYTES, &txbytes);
- if (lastTxbytes != txbytes) {
- lastTxbytes = txbytes;
- }
- } while (ok && txbytes > 0 && timer > 0);
- ok &= txbytes == 0;
- }
- }
- if (!ok) {
- strobe(SFTX); // flush TXfifo
- } else {
- uint8_t state;
- uint8_t lastState = 0;
- do {
- ok &= readStatusRegister(MARCSTATE, &state);
- if (lastState != state) {
- lastState = state;
- }
- } while (ok && state != 0x01 && timer > 0);
- ok &= state == 0x01; // check if in state IDLE
- }
- // ok &= waitForGD0Low(); // wait for end of package
-
- if (ok) {
- printf_P(PSTR(" States["));
- for (uint8_t i = 0; i < statesIndex; i++) {
- printf_P(PSTR(" 0x%02X"), states[i]);
- }
- printf_P(PSTR("] "));
- }
-
- return ok;
- }
-
- bool Cc1101New::receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize) {
- bool ok = true;
- STATUS_RXBYTES_t status;
- uint8_t lastLength = 0;
- uint8_t length = 0;
- *receivedLength = 0;
- timer = 50;
-
- this->status.receivePacketStatusValid = 0;
- ok &= readStatusRegister(RXBYTES, &status.byte);
- if (ok && status.rxbytes.num_rxbytes > 0) {
- length = status.rxbytes.num_rxbytes;
-
- do {
- _delay_us(400); // 20 Bytes in 4ms -> 200us/Byte -> CC1101 datasheet page 56: "twice that of which RF bytes are recived"
- lastLength = length;
- ok &= readStatusRegister(RXBYTES, &status.byte);
- if (ok) {
- // printf_P(PSTR(" [rxbytes=%d] "), status.byte);
- length = status.byte & 0x7f;
- }
- ok &= timer > 0;
- } while (ok && lastLength != length);
-
- if (ok) {
- uint8_t extraBytesCount = this->status.receivePacketStatusEnabled ? 2 : 0;
- if ((PACKET_LENGTH + extraBytesCount) != length) {
- printf_P(PSTR(" ERROR[receive %d bytes, expect %d bytes] "), *receivedLength, PACKET_LENGTH + extraBytesCount);
- *receivedLength = 0;
- ok = false;
- } else {
- printf_P(PSTR(" OK[receive %d bytes] "), length);
- *receivedLength = PACKET_LENGTH < maxBufferSize ? length - extraBytesCount : maxBufferSize;
- ok &= readRegisters(0xff, buffer, *receivedLength);
- if (!ok) {
- *receivedLength = 0;
- } else {
- length -= *receivedLength;
- if (length > extraBytesCount) {
- printf_P(PSTR(" [WARN: buffer to small] "));
- while (length > extraBytesCount) {
- uint8_t byte;
- ok &= readRegister(0xff, &byte);
- ok = false;
- length--;
- }
- }
- if (length > 0) {
- ok &= readRegisters(0xff, this->status.receivedPacketStatus.byte, 2);
- if (ok) {
- this->status.receivePacketStatusValid = 1;
- }
- }
- }
- }
- }
- }
- ok &= strobe(SFRX);
-
- return ok;
- }
-
-
- void Cc1101New::printRegisters () {
- const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
- printf_P(PSTR("\n"));
- for (uint8_t addr = 0; addr < sizeof(Register_t); addr++) {
- bool ok = true;
- uint8_t regValue, value;
- memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1);
- ok &= readRegister(addr, &value);
- if (value != regValue) { printf_P(PSTR(" != 0x%02x"), regValue); }
- }
- uint8_t data[8];
- for (uint8_t addr = 0x30; addr <= 0x3d; addr++) {
- readStatusRegister((StatusAddress_t)addr, data);
- }
- readRegisters(0x3e, data, 8); // PATABLE
- }
-
- bool Cc1101New::resetCC1101 () {
- bool ok = true;
- setChipEnableLow();
- _delay_us(10);
- setChipEnableHigh();
- _delay_us(50);
- setChipEnableLow();
- ok &= waitForMisoLow();
- ok &= strobe(SRES);
- ok &= waitForMisoLow();
-
-
- return ok;
- }
-
- bool Cc1101New::initRegister () {
- const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
- bool ok = true;
- DebugPrint_t tmp = debugPrint.print;
- debugPrint.byte = 0xff; // print all
- printRegisters();
-
- for (uint8_t addr = 0; ok && addr < sizeof(Register_t); addr++) {
- uint8_t regValue;
- memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1);
- ok &= writeRegister(addr, regValue);
- if ((addr == 0x07) && (regValue & 0x04)) {
- status.receivePacketStatusEnabled = true;
- }
- }
-
- printRegisters();
- debugPrint.print = tmp;
- return ok;
- }
-
-#endif
-
-
+++ /dev/null
-#ifndef CC1101NEW_HPP
-#define CC1101NEW_HPP
-
-#include <stdint.h>
-#include "../main.hpp"
-#include <avr/pgmspace.h>
-
-class Cc1101New : public TestUnit {
- public:
- #define PACKET_LENGTH 20
-
- public:
- typedef enum { Test, Send, Receive } Cc1101Mode;
- typedef enum { _IDLE = 0, _RX = 1, _TX = 2, _FSTXON = 3, _CALIBRATE = 4, _SETTLING = 5, _RXFIFO_OVFL = 6, _TXFIFO_UNFL = 7 } StatusState_t;
- typedef struct { uint8_t fifoBytes:4; StatusState_t state:3; uint8_t chipNotReady:1; } Status_t;
- typedef struct { uint8_t rssi:8; uint8_t lqi:7; uint8_t crcOk:1; } ReceivedPacketStatus_t; // CC1101 datasheet page 37
- union {
- struct {
- union {
- Status_t value;
- uint8_t byte;
- } spiResponse;
- union {
- ReceivedPacketStatus_t value;
- uint8_t byte [2];
- } receivedPacketStatus;
- uint8_t spiResponseValid: 1;
- uint8_t receivePacketStatusEnabled:1;
- uint8_t receivePacketStatusValid:1;
- };
- uint32_t dword;
- } status;
-
- public:
- Cc1101New (Cc1101Mode mode) { timer = 0; this->mode = mode; status.dword = 0; }
- virtual void init ();
- virtual void cleanup ();
- virtual int8_t run (uint8_t subtest);
- virtual PGM_P getName ();
-
- public:
- void tick1ms () { if (timer > 0) timer--; };
-
- private:
- typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SFRX = 0x3a, SFTX = 0x3b, SIDLE = 0x36 } StrobeCommand_t;
- typedef enum { MARCSTATE = 0x35, TXBYTES = 0x3A, RXBYTES = 0x3B } StatusAddress_t;
- typedef struct { uint8_t writeRegister:1; uint8_t writeRegisters:1; uint8_t readRegister:1; uint8_t readRegisters:1; } DebugPrint_t;
-
- private:
- int8_t runSend (uint8_t subtest);
- int8_t runReceive (uint8_t subtest);
- int8_t runTest (uint8_t subtest);
- uint8_t sendSpiByte (uint8_t b);
- void triggerOn();
- void triggerOff();
- void triggerToggle ();
- void setChipEnableLow ();
- void setChipEnableHigh ();
- bool isMisoHigh ();
- bool isGd0High ();
- bool waitForMisoLow ();
- bool waitForGD0High ();
- bool waitForGD0Low ();
- bool strobe (StrobeCommand_t strobe);
- bool writeRegister (uint8_t addr, uint8_t value);
- bool writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length);
- bool readRegister (uint8_t addr, uint8_t *value);
- bool readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length);
- bool readStatusRegister (StatusAddress_t addr, uint8_t *value);
- bool sendData (uint8_t *buffer, uint8_t length);
- bool receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize);
- void printRegisters ();
-
- bool resetCC1101 ();
- bool initRegister ();
-
-
- private:
- Cc1101Mode mode;
- uint8_t timer;
- union {
- DebugPrint_t print;
- uint8_t byte;
- } debugPrint;
-
-
- public:
- typedef enum {
- IOCFG2 = 0x00, IOCFG1 = 0x01, IOCFG0 = 0x02,
- FIFOTHR = 0x03,
- SYNC1 = 0x04, SYNC0 = 0x05,
- PKTLEN = 0x06,
- PKTCTRL1 = 0x07, PKTCTRL0 = 0x08
- } RegisterAddress_t;
-
- typedef enum {
- RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x00,
- RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD_OR_END_OF_PACKAGE_UNTIL_FIFO_EMPTY = 0x01,
- TX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x02,
- TX_FIFO_FULL_UNTIL_BELOW_THRESHHOLD = 0x03,
- RX_FIFO_OVERFLOW_UNTIL_FIFO_FLUSHED = 0x04,
- TX_FIFO_UNDERFLOW_UNTIL_FIFO_FLUSHED = 0x05,
- SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET = 0x06,
- PACKET_RECEIVED_WITH_CRC_OK_UNTIL_FIRST_BYTE_READ_FROM_RXFIFO = 0x07,
- PREAMBLE_QUALITY_REACHED_UNTIL_REENTER_RX = 0x08,
- RSSI_LEVEL_BELOW_THRESHOLD = 0x09,
- LOCK_DETECTOR_OUTPUT = 0x0a,
- SERIAL_CLOCK = 0x0b,
- SERIAL_SYNCHRONOUS_DATA_OUTPUT = 0x0c,
- SERIAL_ASYNC_DATA_OUTPUT = 0x0d,
- CARRIER_DETECTED_UNTIL_ENTER_IDLE = 0x0e,
- CRC_OK_UNTIL_REENTER_RX = 0x0f,
- RX_HARD_DATA_1 = 0x16,
- RX_HARD_DATA_0 = 0x17,
- PA_PD = 0x1b,
- LNA_PD = 0x1c,
- RX_SYMBOL_TICK = 0x1d,
- WAKEUP_ON_RECEIVE_EVENT0 = 0x24,
- WAKEUP_ON_RECEIVE_EVENT1 = 0x25,
- CLK_256 = 0x26,
- CLK_32K = 0x27,
- CHIP_NOT_READY = 0x29,
- XOSC_STABLE = 0x2b,
- HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH = 0x2e,
- HW_TO_0 = 0x2f,
- CLK_XOSC = 0x30,
- CLK_XOSC_DIV_1P5 = 0x31,
- CLK_XOSC_DIV_2 = 0x32,
- CLK_XOSC_DIV_3 = 0x33,
- CLK_XOSC_DIV_4 = 0x34,
- CLK_XOSC_DIV_6 = 0x35,
- CLK_XOSC_DIV_8 = 0x36,
- CLK_XOSC_DIV_12 = 0x37,
- CLK_XOSC_DIV_16 = 0x38,
- CLK_XOSC_DIV_24 = 0x39,
- CLK_XOSC_DIV_32 = 0x3a,
- CLK_XOSC_DIV_48 = 0x3b,
- CLK_XOSC_DIV_64 = 0x3c,
- CLK_XOSC_DIV_96 = 0x3d,
- CLK_XOSC_DIV_128 = 0x3e,
- CLK_XOSC_DIV_192 = 0x3f
- } GDOx_CFG_t;
-
- typedef enum {
- SLEEP = 0,
- IDLE = 1,
- XOFF = 2,
- MANCAL_VCOON = 3,
- MANCAL_REGON = 4,
- MANCAL = 5,
- FS_WAKEUP_VCOON = 6,
- FS_WAKEUP_REGON = 7,
- CALIBRATE_START = 8,
- SETTLING_BWBOOST = 9,
- SETTLING_FS_LOCK = 10,
- SETTLIN_IFADCON = 11,
- CALIBRATE_END = 12,
- RX = 13,
- RX_END = 14,
- RX_RST = 15,
- TXRX_SETTLING = 16,
- RXFIFO_OVERFLOW = 17,
- FXTXON = 18,
- TX = 19,
- TX_END = 20,
- RXTX_SETTLING = 21,
- TXFIFO_UNDERFLOW = 22,
- UNKNOWN = 255
- } MainRadioControlState;
-
- typedef enum { NO_ADDR_CHECK = 0, CHECK_NO_BROADCAST = 1, CHECK_WITH_BROADCAST_0 = 2, CHECK_WITH_BROADCAST_0_AND_255 = 3 } ADR_CHK_t;
- typedef enum { FIXED = 0, VARIABLE = 1, INFINITE = 2 } LENGTH_CONFIG_t;
- typedef enum { NORMAL_USE_FIFO = 0, SYNC_SERIAL = 1, RANDOM_TX = 2, ASYNC_SERIAL = 3 } PKT_FORMAT_t;
- typedef enum { FSK2 = 0, GFSK = 1, ASK_OOK = 3, FSK4 = 4, MSK = 7 } MOD_FORMAT_t;
- typedef enum { NO_SYNC = 0, SYNC_15_16 = 1, SYNC_16_16 = 2, SYNC_30_32 = 3, CARRIER_SENSE = 4, SYNC_15_16_CARRIER_SENSE = 5, SYNC_16_16_CARRIER_SENSE = 6 , SYNC_30_326_CARRIER_SENSE = 7} SYNC_MODE_t;
- typedef enum { TWO = 0, THREE = 1, FOUR = 2, SIX = 3, EIGHT = 4, TWELVE = 5, SIXTEEN = 6, TWENTYFOUR = 7 } NUM_PREAMBLE_t;
- typedef enum { TXOFF_IDLE = 0, TXOFF_FSTXON = 1, STAY_IN_TX = 2, TXOFF_RX = 3 } TXOFF_MODE_t;
- typedef enum { RXOFF_IDLE = 0, RXOFF_FSTXON = 1, RXOFF_TX = 2, STAY_IN_RX = 3 } RXOFF_MODE_t;
- typedef enum { ALWAYS = 0, RSSI_BELOW_THRESHOLD = 1, UNLESS_RECEIVE_PACKET = 2, RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET = 3 } CCA_MODE_t;
- typedef enum { NEVER = 0, IDLE_TO_RX_OR_TX = 1, RX_OR_TX_TO_IDLE = 2, RX_OR_TX_TO_IDLE_EVERY_4_TIME = 3 } FS_AUTOCAL_t;
-
- typedef struct { GDOx_CFG_t gdo0_cfg:6; uint8_t gdo0_inv:1; uint8_t bit7:1; } IOCFG0_t;
- typedef struct { GDOx_CFG_t gdo1_cfg:6; uint8_t gdo1_inv:1; uint8_t bit7:1; } IOCFG1_t;
- typedef struct { GDOx_CFG_t gdo2_cfg:6; uint8_t gdo2_inv:1; uint8_t bit7:1; } IOCFG2_t;
- typedef struct { uint8_t fifo_thr:4; uint8_t close_in_rx:2; uint8_t adc_retention:1; uint8_t bit7:1; } FIFOTHR_t;
- typedef struct { ADR_CHK_t adr_chk:2; uint8_t append_status:1; uint8_t crc_autoflush:1; uint8_t bit4:1; uint8_t pqt:3; } PKTCTRL1_t;
- typedef struct { LENGTH_CONFIG_t length_config:2; uint8_t crc_en:1; uint8_t bit3:1; PKT_FORMAT_t pkt_format:2; uint8_t white_data:1; uint8_t bit7:1; } PKTCTRL0_t;
- typedef struct { uint8_t frequ_if:5; uint8_t bit5:1; uint8_t bit76:2; } FSCTRL1_t;
- typedef struct { uint8_t frequoff:8; } FSCTRL0_t;
- typedef struct { uint8_t drate_e:4; uint8_t chanbw_m:2; uint8_t chanbw_e:2; } MDMCFG4_t;
- typedef struct { uint8_t drate_m:8; } MDMCFG3_t;
- typedef struct { SYNC_MODE_t sync_mode:3; uint8_t manchester_en:1; MOD_FORMAT_t mod_format:3; uint8_t dem_dcfilt_off:1; } MDMCFG2_t;
- typedef struct { uint8_t chanspc_e:2; uint8_t bit32:2; NUM_PREAMBLE_t num_preamble:3; uint8_t fec_en:1; } MDMCFG1_t;
- typedef struct { uint8_t chanspc_m:8; } MDMCFG0_t;
- typedef struct { uint8_t deviation_m:3; uint8_t bit3:1; uint8_t deviation_e:3; uint8_t bit7:1; } DEVIATN_t;
- typedef struct { uint8_t rx_time:3; uint8_t rx_time_qual:1; uint8_t rx_time_rssi:1; uint8_t bit765:3; } MCSM2_t;
- typedef struct { TXOFF_MODE_t txoff_mode:2; RXOFF_MODE_t rxoff_mode:2; CCA_MODE_t cca_mode:2; uint8_t bit76:2; } MCSM1_t;
- typedef struct { uint8_t xosc_force_on:1; uint8_t pin_ctrl_en:1; uint8_t po_timeout:2; FS_AUTOCAL_t fs_autocal:2; uint8_t bit76:2; } MCSM0_t;
-
- typedef union {
- uint8_t byte;
- struct {
- uint8_t num_rxbytes:7;
- uint8_t rxfifo_overflow:1;
- } rxbytes;
- } STATUS_RXBYTES_t;
-
- typedef struct {
- IOCFG2_t iocfg2;
- IOCFG1_t iocfg1;
- IOCFG0_t iocfg0;
- FIFOTHR_t fifothr;
- uint8_t sync1;
- uint8_t sync0;
- uint8_t pktlen;
- PKTCTRL1_t pktctrl1;
- PKTCTRL0_t pktctrl0;
- uint8_t addr;
- uint8_t channr;
- FSCTRL1_t fsctrl1;
- FSCTRL0_t fsctrl0;
- uint8_t frequ2;
- uint8_t frequ1;
- uint8_t frequ0;
- MDMCFG4_t mdmcfg4;
- MDMCFG3_t mdmcfg3;
- MDMCFG2_t mdmcfg2;
- MDMCFG1_t mdmcfg1;
- MDMCFG0_t mdmcfg0;
- DEVIATN_t deviatn;
- MCSM2_t mcsm2;
- MCSM1_t mcsm1;
- MCSM0_t mcsm0;
- uint8_t foccfg;
- uint8_t bscfg;
- uint8_t agcctrl2;
- uint8_t agcctrl1;
- uint8_t agcctrl0;
- uint8_t worevt1;
- uint8_t worevt0;
- uint8_t worctrl;
- uint8_t frend1;
- uint8_t frend0;
- uint8_t fscal3;
- uint8_t fscal2;
- uint8_t fscal1;
- uint8_t fscal0;
- uint8_t rcctrl1;
- uint8_t rcctrl0;
- uint8_t fstest;
- uint8_t ptest;
- uint8_t agctest;
- uint8_t test2;
- uint8_t test1;
- uint8_t test0;
-
- } Register_t;
-
-
-
-};
-
-#endif
\ No newline at end of file