From: Manfred Steiner Date: Thu, 15 Aug 2024 05:02:13 +0000 (+0200) Subject: cc1101New -> cc1101 X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=8e990d00ac1c2c366b1d7dd7d1ee704038cb2df7;p=nano-x-base.git cc1101New -> cc1101 --- diff --git a/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.cpp b/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.cpp deleted file mode 100644 index 4f00e6d..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* - - This library was originally copyright of Michael at elechouse.com but permision was - granted by Wilson Shen on 2016-10-23 for me (Simon Monk) to uodate the code for Arduino 1.0+ - and release the code on github under the MIT license. - - -Wilson Shen 23 October 2016 at 02:08 -To: Simon Monk -Thanks for your email. -You are free to put it in github and to do and change. - -On Oct 22, 2016 10:07 PM, "Simon Monk" wrote: - Hi, - - I'm Simon Monk, I'm currently writing the Electronics Cookbook for O'Reilly. I use your - ELECHOUSE_CC1101 library in a 'recipe'. Your library is by far the easiest to use of - the libraries for this device, but the .h and .cpp file both reference WProgram.h which - as replaced by Arduino.h in Arduino 1.0. - - Rather than have to talk my readers through applying a fix to your library, I'd like - your permission to put the modified lib into Github and add an example from the book. - I would of course provide a link to your website in the book and mention that you can buy - the modules there. If its ok, I'd give the code an MIT OS license, to clarify its use. - - Thanks for a great library, - - Kind Regards, - - Simon Monk. - -*/ -#include "ELECHOUSE_CC1101.h" - -#ifdef ELECHOUSE -// #include - - -/****************************************************************/ -#define WRITE_BURST 0x40 //write burst -#define READ_SINGLE 0x80 //read single -#define READ_BURST 0xC0 //read burst -#define BYTES_IN_RXFIFO 0x7F //byte number in RXfifo - -/****************************************************************/ -byte PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60}; - -/**************************************************************** -*FUNCTION NAME:SpiInit -*FUNCTION :spi communication initialization -*INPUT :none -*OUTPUT :none -****************************************************************/ -void ELECHOUSE_CC1101::SpiInit(void) -{ - // initialize the SPI pins - pinMode(SCK_PIN, OUTPUT); - pinMode(MOSI_PIN, OUTPUT); - pinMode(MISO_PIN, INPUT); - pinMode(SS_PIN, OUTPUT); - - // enable SPI Master, MSB, SPI mode 0, FOSC/4 - SpiMode(0); -} -/**************************************************************** -*FUNCTION NAME:SpiMode -*FUNCTION :set spi mode -*INPUT : config mode - (0< sync transmitted - while (digitalRead(GDO0)); // Wait for GDO0 to be cleared -> end of packet - SpiStrobe(CC1101_SFTX); //flush TXfifo -} - -/**************************************************************** -*FUNCTION NAME:SetReceive -*FUNCTION :set CC1101 to receive state -*INPUT :none -*OUTPUT :none -****************************************************************/ -void ELECHOUSE_CC1101::SetReceive(void) -{ - SpiStrobe(CC1101_SRX); -} - -/**************************************************************** -*FUNCTION NAME:CheckReceiveFlag -*FUNCTION :check receive data or not -*INPUT :none -*OUTPUT :flag: 0 no data; 1 receive data -****************************************************************/ -byte ELECHOUSE_CC1101::CheckReceiveFlag(void) -{ - if(digitalRead(GDO0)) //receive data - { - while (digitalRead(GDO0)); - return 1; - } - else // no data - { - return 0; - } -} - - -/**************************************************************** -*FUNCTION NAME:ReceiveData -*FUNCTION :read data received from RXfifo -*INPUT :rxBuffer: buffer to store data -*OUTPUT :size of data received -****************************************************************/ -byte ELECHOUSE_CC1101::ReceiveData(byte *rxBuffer) -{ - byte size; - byte status[2]; - - if(SpiReadStatus(CC1101_RXBYTES) & BYTES_IN_RXFIFO) - { - size=SpiReadReg(CC1101_RXFIFO); - SpiReadBurstReg(CC1101_RXFIFO,rxBuffer,size); - SpiReadBurstReg(CC1101_RXFIFO,status,2); - SpiStrobe(CC1101_SFRX); - return size; - } - else - { - SpiStrobe(CC1101_SFRX); - return 0; - } - -} - -ELECHOUSE_CC1101 ELECHOUSE_cc1101; - - -#endif - diff --git a/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.h b/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.h deleted file mode 100644 index e8e609b..0000000 --- a/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - - This library was originally copyright of Michael at elechouse.com but permision was - granted by Wilson Shen on 2016-10-23 for me (Simon Monk) to uodate the code for Arduino 1.0+ - and release the code on github under the MIT license. - - -Wilson Shen 23 October 2016 at 02:08 -To: Simon Monk -Thanks for your email. -You are free to put it in github and to do and change. - -On Oct 22, 2016 10:07 PM, "Simon Monk" wrote: - Hi, - - I'm Simon Monk, I'm currently writing the Electronics Cookbook for O'Reilly. I use your - ELECHOUSE_CC1101 library in a 'recipe'. Your library is by far the easiest to use of - the libraries for this device, but the .h and .cpp file both reference WProgram.h which - as replaced by Arduino.h in Arduino 1.0. - - Rather than have to talk my readers through applying a fix to your library, I'd like - your permission to put the modified lib into Github and add an example from the book. - I would of course provide a link to your website in the book and mention that you can buy - the modules there. If its ok, I'd give the code an MIT OS license, to clarify its use. - - Thanks for a great library, - - Kind Regards, - - Simon Monk. - - -*/ -//#define ELECHOUSE -#ifdef ELECHOUSE - -#ifndef ELECHOUSE_CC1101_h -#define ELECHOUSE_CC1101_h - -// #include "Arduino.h" -#include -#define byte uint8_t - -// 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 - -//*************************************** pins **************************************************// -#define SCK_PIN 13 -#define MISO_PIN 12 -#define MOSI_PIN 11 -#define SS_PIN 10 -#define GDO0 2 -#define GDO2 9 -//************************************* class **************************************************// -class ELECHOUSE_CC1101 -{ - private: - void SpiInit(void); - void SpiMode(byte config); - byte SpiTransfer(byte value); - void GDO_Set (void); - void Reset (void); - void SpiWriteReg(byte addr, byte value); - void SpiWriteBurstReg(byte addr, byte *buffer, byte num); - void SpiStrobe(byte strobe); - byte SpiReadReg(byte addr); - void SpiReadBurstReg(byte addr, byte *buffer, byte num); - byte SpiReadStatus(byte addr); - void RegConfigSettings(byte f); - public: - void Init(void); - void Init(byte f); - void SendData(byte *txBuffer, byte size); - void SetReceive(void); - byte CheckReceiveFlag(void); - byte ReceiveData(byte *rxBuffer); -}; - -extern ELECHOUSE_CC1101 ELECHOUSE_cc1101; - -#endif - -#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/main.cpp b/software/nano-644/test_2024-07-23/src/main.cpp index 75a1113..befbb74 100644 --- a/software/nano-644/test_2024-07-23/src/main.cpp +++ b/software/nano-644/test_2024-07-23/src/main.cpp @@ -24,7 +24,6 @@ #include "units/modbus.hpp" #include "units/rtc8563.hpp" #include "units/cc1101.hpp" -#include "units/cc1101new.hpp" extern "C" { void __cxa_pure_virtual () {} @@ -127,10 +126,6 @@ extern "C" { 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) { @@ -186,7 +181,7 @@ int main () { #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 @@ -306,9 +301,6 @@ ISR (TIMER2_COMPA_vect) { // every 100us i2cSparkfun.tick1ms(); cc1101Send.tick1ms(); cc1101Receive.tick1ms(); - cc1101NewSend.tick1ms(); - cc1101NewReceive.tick1ms(); - cc1101NewTest.tick1ms(); #ifdef __AVR_ATmega644P__ if (timerFlashRedLed > 0) { if (--timerFlashRedLed < 128) { diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101.cpp b/software/nano-644/test_2024-07-23/src/units/cc1101.cpp index 31d335d..b3eb1d8 100644 --- a/software/nano-644/test_2024-07-23/src/units/cc1101.cpp +++ b/software/nano-644/test_2024-07-23/src/units/cc1101.cpp @@ -17,6 +17,8 @@ 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("?"); } @@ -28,44 +30,217 @@ // 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< "), 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<> 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 diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101.hpp b/software/nano-644/test_2024-07-23/src/units/cc1101.hpp index 84c6bb2..3603d4d 100644 --- a/software/nano-644/test_2024-07-23/src/units/cc1101.hpp +++ b/software/nano-644/test_2024-07-23/src/units/cc1101.hpp @@ -7,11 +7,32 @@ 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); @@ -21,10 +42,18 @@ class Cc1101 : public TestUnit { 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 (); @@ -32,28 +61,87 @@ class Cc1101 : public TestUnit { 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, @@ -78,124 +166,97 @@ class Cc1101 : public TestUnit { 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; + + }; diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp b/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp deleted file mode 100644 index cf1db42..0000000 --- a/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp +++ /dev/null @@ -1,663 +0,0 @@ -#include -#include -#include -#include - -#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< "), 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 - - diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp b/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp deleted file mode 100644 index 516baa6..0000000 --- a/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp +++ /dev/null @@ -1,263 +0,0 @@ -#ifndef CC1101NEW_HPP -#define CC1101NEW_HPP - -#include -#include "../main.hpp" -#include - -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