From 84a72cd129f7447644bb8d1ff56b83c7367003af Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Wed, 7 Aug 2024 20:05:46 +0200 Subject: [PATCH] ... --- software/nano-644/test_2024-07-23/Makefile | 2 +- .../src/adafruit/ELECHOUSE_CC1101.cpp | 420 ++++++++++++++++++ .../src/adafruit/ELECHOUSE_CC1101.h | 195 ++++++++ .../nano-644/test_2024-07-23/src/main.cpp | 20 +- .../test_2024-07-23/src/units/cc1011.cpp | 406 +++++++++++++++++ .../test_2024-07-23/src/units/cc1101.hpp | 173 ++++++++ .../test_2024-07-23/src/units/i2c.hpp | 14 +- 7 files changed, 1212 insertions(+), 18 deletions(-) create mode 100644 software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.cpp create mode 100644 software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.h create mode 100644 software/nano-644/test_2024-07-23/src/units/cc1011.cpp create mode 100644 software/nano-644/test_2024-07-23/src/units/cc1101.hpp diff --git a/software/nano-644/test_2024-07-23/Makefile b/software/nano-644/test_2024-07-23/Makefile index dcb4370..be31a04 100644 --- a/software/nano-644/test_2024-07-23/Makefile +++ b/software/nano-644/test_2024-07-23/Makefile @@ -17,7 +17,7 @@ CC= avr-g++ CFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -c LFLAGS= -Wall -mmcu=$(DEVICE) -Os -DF_CPU=12000000 -Wl,-u,vfprintf -lprintf_flt -lm -CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -c +CFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -c -c LFLAGS_SIM= -Wall -mmcu=$(DEVICE) -Og -DF_CPU=12000000 -g -Wl,-u,vfprintf -lprintf_flt -lm 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 new file mode 100644 index 0000000..4f00e6d --- /dev/null +++ b/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.cpp @@ -0,0 +1,420 @@ +/* + + 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 new file mode 100644 index 0000000..e8e609b --- /dev/null +++ b/software/nano-644/test_2024-07-23/src/adafruit/ELECHOUSE_CC1101.h @@ -0,0 +1,195 @@ +/* + + 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 4b6b734..78fe57b 100644 --- a/software/nano-644/test_2024-07-23/src/main.cpp +++ b/software/nano-644/test_2024-07-23/src/main.cpp @@ -23,19 +23,17 @@ #include "units/uart1.hpp" #include "units/modbus.hpp" #include "units/rtc8563.hpp" +#include "units/cc1101.hpp" extern "C" { - void __cxa_pure_virtual () { - } - - int __cxa_guard_acquire(uint8_t *g) { - return 0; - } - + void __cxa_pure_virtual () {} + int __cxa_guard_acquire(uint8_t *g) { return 0; } void __cxa_guard_release(uint8_t *g) {} - void __cxa_guard_abort(uint8_t *g) {} - + void __gxx_personality_sj0 () {} + void __cxa_rethrow () {} + void __cxa_begin_catch () {} + void __cxa_end_catch () {} int uart_putchar(char c, FILE *stream) { if (c == '\n') { @@ -99,6 +97,7 @@ extern "C" { I2c i2cMaster(I2c::Master); I2c i2cSlave(I2c::Slave); Rtc8563 rtc8563; + Cc1101 cc1101; } @@ -155,7 +154,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 + &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101 }; #endif @@ -273,6 +272,7 @@ ISR (TIMER2_COMPA_vect) { // every 100us i2cMaster.tick1ms(); i2cSlave.tick1ms(); i2cSparkfun.tick1ms(); + cc1101.tick1ms(); } timer500ms++; diff --git a/software/nano-644/test_2024-07-23/src/units/cc1011.cpp b/software/nano-644/test_2024-07-23/src/units/cc1011.cpp new file mode 100644 index 0000000..962043d --- /dev/null +++ b/software/nano-644/test_2024-07-23/src/units/cc1011.cpp @@ -0,0 +1,406 @@ +#include +#include +#include +#include + +#include "cc1101.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 PortExp::init () {} + void PortExp::cleanup () {} + void PortExp::setChipEnable () {} + void PortExp::clearChipEnable () {} + +#endif + + +#ifdef __AVR_ATmega644P__ + + // Nano-644 + // -------------------------------------------------------- + // PA4 ... nCS + // 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 + CC1101_PKTCTRL0, 0x05, // whitening off; normal mode, CRC enabled, variable packet length + CC1101_ADDR, 0x00, // address used for packet filtration. + CC1101_PKTLEN, 0x3D // 61 bytes max length +}; + + +const uint8_t PMEM_CC1101_PA_TABLE[8] PROGMEM = { 0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 }; + + void Cc1101::triggerOn () { + PORTB |= (1 << PB0); + } + + void Cc1101::triggerOff () { + PORTB &= ~(1 << PB0); + } + + void Cc1101::init () { + // trigger for debugging + PORTB &= ~(1 << PB0); + DDRB |= ( 1 << PB0); + + PRR &= (1 << PRSPI); + PORTA |= (1 << PA4); + DDRA |= (1 << PA4); // SPI nCS + // 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); + } + + void Cc1101::cleanup () { + // trigger for debugging + PORTB &= ~(1 << PB0); + DDRB &= ~( 1 << PB0); + + SPCR = 0; + 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); + } + + void Cc1101::setChipEnableHigh () { + PORTA |= (1 << PA4); + } + + bool Cc1101::isMisoHigh () { + return (PINB & (1 << PB6)) != 0; + } + + bool Cc1101::isGd0High () { + return (PINA & (1 << PA5)) != 0; + } + +#endif + +uint8_t Cc1101::sendSpiByte (uint8_t b) { + SPDR = b; + while (!(SPSR & (1< 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); + if (ok && status[0] & BYTES_IN_RXFIFO) { + ok &= readRegister(CC1101_RXFIFO, &length); + if (ok && length > 0 && length <= maxBufferSize) { + ok &= readRegisters(CC1101_RXFIFO, buffer, length); + ok &= readRegisters(CC1101_RXFIFO, status, 2); + ok &= strobe(CC1101_SFRX); + if (ok) { + *receivedLength = length; + return ok; + } + } + } + strobe(CC1101_SFRX); + *receivedLength = 0; + return false; +} + +bool Cc1101::initModem () { + bool ok = true; + SPCR = 0; + + setChipEnableLow(); + _delay_us(20); + setChipEnableHigh(); + _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; +} + +int8_t Cc1101::run (uint8_t subtest) { + if (subtest == 0) { + printf_P(PSTR("\n => init CC1101 ... ")); + if (!initModem()) { + printf_P(PSTR("E1")); + return -1; + } + 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")); + } + } else { + printf_P(PSTR("E3")); + } + return 0; + + } 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("?")); + } + } + + return 0; + + } else if (subtest == 2) { + do { + uint8_t status; + printf_P(PSTR("\n => status: ")); + triggerOn(); + if (readStatus(CC1101_MARCSTATE, &status)) { + printf_P(PSTR("0x%02x"), status); + } else { + printf_P(PSTR("E4")); + } + triggerOff(); + } while (wait(2000) == EOF); + } + + return -1; +} + 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 new file mode 100644 index 0000000..64dd578 --- /dev/null +++ b/software/nano-644/test_2024-07-23/src/units/cc1101.hpp @@ -0,0 +1,173 @@ +#ifndef CC1101_HPP +#define CC1101_HPP + +#include +#include "../main.hpp" +#include + +class Cc1101 : public TestUnit { + public: + typedef enum { MHZ915, MHZ433, MHZ868 } InitFrequency; + + public: + Cc1101 () {}; + virtual void init (); + virtual void cleanup (); + virtual int8_t run (uint8_t subtest); + virtual PGM_P getName () { return PSTR("CC-1101"); } + + public: + void tick1ms () { if (timer > 0) timer--; }; + + private: + void triggerOn(); + void triggerOff(); + bool initModem (); + bool initModemConfig (InitFrequency f); + void setChipEnableLow (); + void setChipEnableHigh (); + bool isMisoHigh (); + bool isGd0High (); + bool waitForMisoLow (); + bool waitForGD0High (); + bool waitForGD0Low (); + uint8_t sendSpiByte (uint8_t b); + 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 sendData (uint8_t *buffer, uint8_t length); + bool setReceive (); + bool receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize); + //bool isReceiveFlagSet (); + + private: + uint8_t timer; + + public: + + + private: + + + #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 + +}; + +#endif \ No newline at end of file diff --git a/software/nano-644/test_2024-07-23/src/units/i2c.hpp b/software/nano-644/test_2024-07-23/src/units/i2c.hpp index f039366..2148cc0 100644 --- a/software/nano-644/test_2024-07-23/src/units/i2c.hpp +++ b/software/nano-644/test_2024-07-23/src/units/i2c.hpp @@ -31,13 +31,13 @@ class I2c : public TestUnit { virtual int8_t run (uint8_t subtest); virtual PGM_P getName (); void handleTwiIrq (); - uint16_t startRead (uint8_t address); - uint16_t startWrite (uint8_t address); - void stop (); - uint16_t writeByte (uint8_t data); - uint16_t writeData (uint8_t size, const uint8_t *data); - uint16_t readData (uint8_t size, uint8_t *data); - int32_t compensateBm280T (int32_t adcT); + // uint16_t startRead (uint8_t address); + // uint16_t startWrite (uint8_t address); + // void stop (); + // uint16_t writeByte (uint8_t data); + // uint16_t writeData (uint8_t size, const uint8_t *data); + // uint16_t readData (uint8_t size, uint8_t *data); + // int32_t compensateBm280T (int32_t adcT); }; #endif \ No newline at end of file -- 2.39.5