diff --git a/SIGNALESP/SIGNALESP.ino b/SIGNALESP/SIGNALESP.ino index ea44ba6..0ed0e4d 100644 --- a/SIGNALESP/SIGNALESP.ino +++ b/SIGNALESP/SIGNALESP.ino @@ -5,16 +5,18 @@ #define VERSION_1 0x33 #define VERSION_2 0x1d +#define CMP_CC1101 #define PIN_RECEIVE 2 #define PIN_LED 16 #define PIN_SEND 0 #define BAUDRATE 115200 -#define FIFO_LENGTH 200 -#define DEBUG 1 +#define FIFO_LENGTH 200 +#define DEBUG 1 #define ETHERNET_PRINT +#include #include #include //Local DNS Server used for redirecting all requests to the configuration portal #include //Local WebServer used to serve the configuration portal @@ -32,16 +34,15 @@ SimpleFIFO FiFo; //store FIFO_LENGTH # ints SignalDetectorClass musterDec; -#include - +#ifdef CMP_CC1101 + #include "cc1101.h" +#endif #define pulseMin 90 volatile bool blinkLED = false; String cmdstring = ""; volatile unsigned long lastTime = micros(); - - #define digitalLow(P) digitalWrite(P,LOW) #define digitalHigh(P) digitalWrite(P,HIGH) #define isHigh(P) (digitalRead(P) == HIGH) @@ -52,21 +53,19 @@ extern "C" { #include "user_interface.h" } - os_timer_t cronTimer; - +bool hasCC1101 = false; // EEProm Addresscommands -#define addr_init 0 -#define addr_features 1 #define EE_MAGIC_OFFSET 0 +#define addr_features EE_MAGIC_OFFSET+2 #define MAX_SRV_CLIENTS 2 -//void handleInterrupt(); +void handleInterrupt(); void enableReceive(); void disableReceive(); void serialEvent(); @@ -82,6 +81,7 @@ void getPing(); void configCMD(); void storeFunctions(const int8_t ms = 1, int8_t mu = 1, int8_t mc = 1); void getFunctions(bool *ms, bool *mu, bool *mc); +uint8_t rssiCallback() { return 0; }; // Dummy return if no rssi value can be retrieved from receiver @@ -109,13 +109,36 @@ bool startWPS() { void setup() { //ESP.wdtEnable(2000); + Serial.begin(115200); + while (!Serial) - { - delay(90); - } + delay(90); + + Serial.println("\n\n"); + + pinMode(PIN_RECEIVE, INPUT); + pinMode(PIN_LED, OUTPUT); + +#ifdef CMP_CC1101 + cc1101::setup(); +#endif + + initEEPROM(); + +#ifdef CMP_CC1101 + cc1101::CCinit(); + hasCC1101 = cc1101::checkCC1101(); + + if (hasCC1101) { + DBG_PRINTLN("CC1101 found"); +// musterDec.setRSSICallback(&cc1101::getRSSI); // Provide the RSSI Callback + }// else +// musterDec.setRSSICallback(&rssiCallback); // Provide the RSSI Callback +#endif + #ifdef DEBUG - Serial.printf("\nTry connecting to WiFi with SSID '%s'\n", WiFi.SSID().c_str()); + Serial.printf("\nTry connecting to WiFi with SSID '%s'\n", WiFi.SSID().c_str()); #endif WiFi.mode(WIFI_STA); WiFi.begin(WiFi.SSID().c_str(), WiFi.psk().c_str()); // reading data from EPROM, @@ -154,8 +177,6 @@ void setup() { #endif } - - WiFiManager wifiManager; wifiManager.setBreakAfterConfig(true); //reset settings - for testing @@ -179,29 +200,6 @@ void setup() { Serial.println("local ip"); Serial.println(WiFi.localIP()); - - - //pinMode(PIN_RECEIVE, INPUT); - //pinMode(PIN_SEND, OUTPUT); - //pinMode(PIN_LED, OUTPUT); - - initEEPROM(); - //musterDec.MSenabled = musterDec.MUenabled = musterDec.MCenabled = true; - /* - if (EEPROM.read(addr_init) == 0xB) - { - #ifdef DEBUG - Serial.println("Reading values fom eeprom"); - #endif - getFunctions(&musterDec.MSenabled, &musterDec.MUenabled, &musterDec.MCenabled); - } - else { - EEPROM.write(addr_init, 0xB); - storeFunctions(1, 1, 1); // Init EEPROM with all flags enabled - #ifdef DEBUG - Serial.println("Init eeprom to defaults after flash"); - #endif - }*/ Server.begin(); // telnet server Server.setNoDelay(true); @@ -209,7 +207,13 @@ void setup() { os_timer_setfn(&cronTimer, cronjob, NULL); os_timer_arm(&cronTimer, 31, true); - enableReceive(); + if (!hasCC1101 || cc1101::regCheck()) { + enableReceive(); + DBG_PRINTLN(F("receiver enabled")); + } else { + DBG_PRINTLN(F("cc1101 is not correctly set. Please do a factory reset via command e")); + } + cmdstring.reserve(40); } @@ -244,6 +248,27 @@ void loop() { if (state) blinkLED = true; //LED blinken, wenn Meldung dekodiert yield(); } + + if (Serial.available()) { + int16_t sDuration = 620; + + switch(Serial.read()) { + case 'b': + FiFo.enqueue(sDuration); + for (uint8_t i=0; i<55; i++) { + FiFo.enqueue(-sDuration*2); + FiFo.enqueue(sDuration); + } + FiFo.enqueue(-sDuration); + break; + case 'c': + Serial.println("currentMode: 0x" + String(cc1101::currentMode(), HEX)); + break; + case 'd': + dumpEEPROM(); + break; + } + } } @@ -267,25 +292,35 @@ void ICACHE_RAM_ATTR handleInterrupt() { } FiFo.enqueue(sDuration); } // else => trash - } void enableReceive() { - attachInterrupt(PIN_RECEIVE, handleInterrupt, CHANGE); + attachInterrupt(PIN_RECEIVE, handleInterrupt, CHANGE); + + #ifdef CMP_CC1101 + if (hasCC1101) + cc1101::setReceiveMode(); + Serial.println("receiver enabled!"); + #endif } void disableReceive() { - detachInterrupt(PIN_RECEIVE); + detachInterrupt(PIN_RECEIVE); + + #ifdef CMP_CC1101 + if (hasCC1101) + cc1101::setIdleMode(); + Serial.println("receiver disabled!"); + #endif } - - - //============================== IT_Send ========================================= //================================= RAW Send ====================================== void send_raw(const uint8_t startpos, const uint16_t endpos, const int16_t *buckets, String *source = &cmdstring) { + pinMode(PIN_SEND, OUTPUT); + uint8_t index = 0; unsigned long stoptime = micros(); bool isLow; @@ -313,11 +348,10 @@ void send_raw(const uint8_t startpos, const uint16_t endpos, const int16_t *buck } //SM;R=2;C=400;D=AFAFAF; - - - void send_mc(const uint8_t startpos, const uint8_t endpos, const int16_t clock) { + pinMode(PIN_SEND, OUTPUT); + int8_t b; char c; //digitalHigh(PIN_SEND); @@ -376,6 +410,8 @@ struct s_sendcmd { void send_cmd() { + pinMode(PIN_SEND, OUTPUT); + #define combined 0 #define manchester 1 #define raw 2 @@ -458,6 +494,11 @@ void send_cmd() } } +#ifdef CMP_CC1101 + if (hasCC1101) + cc1101::setTransmitMode(); +#endif + for (uint8_t i = 0; i read EEPROM + reg = cmdstringPos2int(1); + MSG_PRINT(F("EEPROM ")); + printHex2(reg); + if (cmdstring.charAt(3) == 'n') { + MSG_PRINT(F(" :")); + for (uint8_t i = 0; i < 16; i++) { + MSG_PRINT(" "); + printHex2(EEPROM.read(reg + i)); + } + } else { + MSG_PRINT(F(" = ")); + printHex2(EEPROM.read(reg)); + } + MSG_PRINTLN(""); + } else if (cmdstring.charAt(0) == cmd_patable && isHexadecimalDigit(cmdstring.charAt(1)) && isHexadecimalDigit(cmdstring.charAt(2)) && hasCC1101) { + val = cmdstringPos2int(1); + cc1101::writeCCpatable(val); + MSG_PRINT(F("Write ")); + printHex2(val); + MSG_PRINTLN(F(" to PATABLE done")); + EEPROM.commit(); + } else if (cmdstring.charAt(0) == cmd_ccFactoryReset && hasCC1101) { + cc1101::ccFactoryReset(); + cc1101::CCinit(); + EEPROM.commit(); + } else if (cmdstring.charAt(0) == cmd_write) { // write EEPROM und CC11001 register + if (cmdstring.charAt(1) == 'S' && cmdstring.charAt(2) == '3' && hasCC1101) { // WS Command Strobes + cc1101::commandStrobes(); + } else if (isHexadecimalDigit(cmdstring.charAt(1)) && isHexadecimalDigit(cmdstring.charAt(2)) && isHexadecimalDigit(cmdstring.charAt(3)) && isHexadecimalDigit(cmdstring.charAt(4))) { + reg = cmdstringPos2int(1); + val = cmdstringPos2int(3); + if (hasCC1101) { + cc1101::writeCCreg(reg, val); + EEPROM.commit(); + } + } +#endif } else { - MSG_PRINTLN(F("Unsupported command")); + MSG_PRINT(F("Unsupported command")); + MSG_PRINTLN(" -> 0x" + String(cmdstring.charAt(0), HEX) + " " + cmdstring); } } @@ -616,8 +707,12 @@ void configCMD() } else if (cmdstring.charAt(1) == 'D') { // Disable *bptr = false; - } - else { +#ifdef CMP_CC1101 + } else if (isHexadecimalDigit(cmdstring.charAt(1)) && isHexadecimalDigit(cmdstring.charAt(2)) && hasCC1101) { + uint8_t reg = cmdstringPos2int(1); + cc1101::readCCreg(reg); +#endif + } else { return; } storeFunctions(musterDec.MSenabled, musterDec.MUenabled, musterDec.MCenabled); @@ -715,54 +810,68 @@ void storeFunctions(const int8_t ms, int8_t mu, int8_t mc) { mu = mu << 1; mc = mc << 2; - EEPROM.begin(512); //Max bytes of eeprom to use - yield(); - - int8_t dat = ms | mu | mc; EEPROM.write(addr_features, dat); - EEPROM.commit(); - EEPROM.end(); } void getFunctions(bool *ms, bool *mu, bool *mc) { - EEPROM.begin(512); //Max bytes of eeprom to use - yield(); int8_t dat = EEPROM.read(addr_features); - EEPROM.end(); - *ms = bool(dat &(1 << 0)); *mu = bool(dat &(1 << 1)); *mc = bool(dat &(1 << 2)); - - } +void dumpEEPROM() { + Serial.println("\ndump EEPROM:"); + for (uint8_t i=0; i<56; i++) { + String temp=String(EEPROM.read(i), HEX); + Serial.print((temp.length() == 1 ? "0" : "") + temp + " "); + if ((i & 0x0F) == 0x0F) + Serial.println(""); + } + Serial.println(""); +} -void initEEPROM(void) { +void initEEPROM() { EEPROM.begin(512); //Max bytes of eeprom to use - yield(); + if (EEPROM.read(EE_MAGIC_OFFSET) == VERSION_1 && EEPROM.read(EE_MAGIC_OFFSET + 1) == VERSION_2) { DBG_PRINTLN("Reading values fom eeprom"); - } - else { - storeFunctions(1, 1, 1); // Init EEPROM with all flags enabled + } else { + DBG_PRINTLN("Init eeprom to defaults after flash"); + EEPROM.write(EE_MAGIC_OFFSET, VERSION_1); + EEPROM.write(EE_MAGIC_OFFSET + 1, VERSION_2); storeFunctions(1, 1, 1); // Init EEPROM with all flags enabled //hier fehlt evtl ein getFunctions() - DBG_PRINTLN("Init eeprom to defaults after flash"); - EEPROM.write(EE_MAGIC_OFFSET, VERSION_1); - EEPROM.write(EE_MAGIC_OFFSET + 1, VERSION_2); - // if (hasCC1101) { // der ccFactoryReset muss auch durchgefuehrt werden, wenn der cc1101 nicht erkannt wurde - //cc1101::ccFactoryReset(); - EEPROM.write(EE_MAGIC_OFFSET, VERSION_1); - EEPROM.write(EE_MAGIC_OFFSET + 1, VERSION_2); - // if (hascc1101) { // der ccFactoryReset muss auch durchgefuehrt werden, wenn der cc1101 nicht erkannt wurde - //cc1101::ccFactoryReset(); - //} - } - EEPROM.commit(); - EEPROM.end(); +#ifdef CMP_CC1101 + cc1101::ccFactoryReset(); +#endif + + EEPROM.commit(); + } + +#ifdef DEBUG + dumpEEPROM(); +#endif + getFunctions(&musterDec.MSenabled, &musterDec.MUenabled, &musterDec.MCenabled); - +} + +uint8_t cmdstringPos2int(uint8_t pos) { + uint8_t val; + uint8_t hex; + + hex = (uint8_t)cmdstring.charAt(pos); + val = cc1101::hex2int(hex) * 16; + hex = (uint8_t)cmdstring.charAt(pos+1); + val = cc1101::hex2int(hex) + val; + return val; +} + +void printHex2(const byte hex) { // Todo: printf oder scanf nutzen + if (hex < 16) { + MSG_PRINT("0"); + } + MSG_PRINT(hex, HEX); } diff --git a/SIGNALESP/cc1101.h b/SIGNALESP/cc1101.h new file mode 100644 index 0000000..314583a --- /dev/null +++ b/SIGNALESP/cc1101.h @@ -0,0 +1,522 @@ +// cc1101.h + +#ifndef _CC1101_h +#define _CC1101_h + +#if defined(ARDUINO) && ARDUINO >= 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif +#include +#include "output.h" + +#ifdef ESP8266 + #include +#endif + +extern String cmdstring; + + + +namespace cc1101 { +#if defined(ARDUINO_AVR_ICT_BOARDS_ICT_BOARDS_AVR_RADINOCC1101) || defined(ESP8266) +// #define SS 8 + #define PIN_MARK433 4 // LOW -> 433Mhz | HIGH -> 868Mhz + #endif + + #define csPin SS // CSN out + #define mosiPin MOSI // MOSI out + #define misoPin MISO // MISO in + #define sckPin SCK // SCLK out + + #ifndef PIN_SEND + #ifdef ARDUINO_AVR_ICT_BOARDS_ICT_BOARDS_AVR_RADINOCC1101 + #define PIN_SEND 9 // gdo0Pin TX out + #define PIN_RECEIVE 7 + #define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT))))) + #else + #define PIN_LED 9 + #define PIN_SEND 3 // gdo0Pin TX out + #define PIN_RECEIVE 2 + #endif + #endif + + + #define CC1101_CONFIG 0x80 + #define CC1101_STATUS 0xC0 + #define CC1100_WRITE_BURST 0x40 + #define CC1100_READ_BURST 0xC0 + + #define CC1100_FREQ2 0x0D // Frequency control word, high byte + #define CC1100_FREQ1 0x0E // Frequency control word, middle byte + #define CC1100_FREQ0 0x0F // Frequency control word, low byte + #define CC1100_PATABLE 0x3E // 8 byte memory + #define CC1100_IOCFG2 0x00 // GDO2 output configuration + #define CC1100_PKTCTRL0 0x08 // Packet config register + + // Status registers + #define CC1100_RSSI 0x34 // Received signal strength indication + #define CC1100_MARCSTATE 0x35 // Control state machine state + + // Strobe commands + #define CC1101_SRES 0x30 // reset + #define CC1100_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). + #define CC1100_SCAL 0x33 // Calibrate frequency synthesizer and turn it off + #define CC1100_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1 + #define CC1100_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1 + #define CC1100_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer + #define CC1100_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer + #define CC1100_SFTX 0x3B // Flush the TX FIFO buffer. + #define CC1101_SNOP 0x3D // + +#ifdef ESP8266 + #define pinAsInput(pin) pinMode(pin, INPUT) + #define pinAsOutput(pin) pinMode(pin, OUTPUT) + #define pinAsInputPullUp(pin) pinMode(pin, INPUT_PULLUP) + + #ifndef digitalLow + #define digitalLow(pin) digitalWrite(pin, LOW) + #endif + #ifndef digitalHigh + #define digitalHigh(pin) digitalWrite(pin, HIGH) + #endif + #ifndef isHigh + #define isHigh(pin) (digitalRead(pin) == HIGH) + #endif +#endif + +#ifndef ESP8266 + #define wait_Miso() while(isHigh(misoPin) ) { static uint8_t miso_count=255;delay(1); if(miso_count==0) return; miso_count--; } // wait until SPI MISO line goes low +#else + #define wait_Miso() while(isHigh(misoPin) ) { static uint8_t miso_count=255;delay(1); if(miso_count==0) break; miso_count--; } // wait until SPI MISO line goes low +#endif + + #define cc1101_Select() digitalLow(csPin) // select (SPI) CC1101 + #define cc1101_Deselect() digitalHigh(csPin) + + #define EE_CC1100_CFG 3 + #define EE_CC1100_CFG_SIZE 0x29 + #define EE_CC1100_PA 0x30 // (EE_CC1100_CFG+EE_CC1100_CFG_SIZE) // 2C + #define EE_CC1100_PA_SIZE 8 + + #define PATABLE_DEFAULT 0x84 // 5 dB default value for factory reset + + //------------------------------------------------------------------------------ + // Chip Status Byte + //------------------------------------------------------------------------------ + + // Bit fields in the chip status byte + #define CC1100_STATUS_CHIP_RDYn_BM 0x80 + #define CC1100_STATUS_STATE_BM 0x70 + #define CC1100_STATUS_FIFO_BYTES_AVAILABLE_BM 0x0F + + // Chip states + #define CC1100_STATE_IDLE 0x00 + #define CC1100_STATE_RX 0x10 + #define CC1100_STATE_TX 0x20 + #define CC1100_STATE_FSTXON 0x30 + #define CC1100_STATE_CALIBRATE 0x40 + #define CC1100_STATE_SETTLING 0x50 + #define CC1100_STATE_RX_OVERFLOW 0x60 + #define CC1100_STATE_TX_UNDERFLOW 0x70 + +#ifdef ARDUINO_AVR_ICT_BOARDS_ICT_BOARDS_AVR_RADINOCC1101 + uint8_t RADINOVARIANT = 0; // Standardwert welcher je radinoVarinat geändert wird +#endif + static const uint8_t initVal[] PROGMEM = + { + // IDX NAME RESET COMMENT + 0x0D, // 00 IOCFG2 29 GDO2 as serial output + 0x2E, // 01 IOCFG1 Tri-State + 0x2D, // 02 IOCFG0 3F GDO0 for input + 0x07, // 03 FIFOTHR + 0xD3, // 04 SYNC1 + 0x91, // 05 SYNC0 + 0x3D, // 06 PKTLEN 0F + 0x04, // 07 PKTCTRL1 + 0x32, // 08 PKTCTRL0 45 + 0x00, // 09 ADDR + 0x00, // 0A CHANNR + 0x06, // 0B FSCTRL1 0F 152kHz IF Frquency + 0x00, // 0C FSCTRL0 + 0x10, // 0D FREQ2 1E Freq + 0xB0, // 0E FREQ1 C4 + 0x71, // 0F FREQ0 EC + 0x57, // 10 MDMCFG4 8C bWidth 325kHz + 0xC4, // 11 MDMCFG3 22 DataRate + 0x30, // 12 MDMCFG2 02 Modulation: ASK + 0x23, // 13 MDMCFG1 22 + 0xb9, // 14 MDMCFG0 F8 ChannelSpace: 350kHz + 0x00, // 15 DEVIATN 47 + 0x07, // 16 MCSM2 07 + 0x00, // 17 MCSM1 30 Bit 3:2 RXOFF_MODE: Select what should happen when a packet has been received: 0 = IDLE 3 = Stay in RX #### + 0x18, // 18 MCSM0 04 Calibration: RX/TX->IDLE + 0x14, // 19 FOCCFG 36 + 0x6C, // 1A BSCFG + 0x07, // 1B AGCCTRL2 03 42 dB instead of 33dB + 0x00, // 1C AGCCTRL1 40 + 0x90, // 1D AGCCTRL0 91 4dB decision boundery + 0x87, // 1E WOREVT1 + 0x6B, // 1F WOREVT0 + 0xF8, // 20 WORCTRL + 0x56, // 21 FREND1 + 0x11, // 22 FREND0 16 0x11 for no PA ramping + 0xE9, // 23 FSCAL3 A9 E9 ?? + 0x2A, // 24 FSCAL2 0A + 0x00, // 25 FSCAL1 20 19 ?? + 0x1F, // 26 FSCAL0 0D + 0x41, // 27 RCCTRL1 + 0x00, // 28 RCCTRL0 + }; + + byte hex2int(byte hex) { // convert a hexdigit to int // Todo: printf oder scanf nutzen + if (hex >= '0' && hex <= '9') hex = hex - '0'; + else if (hex >= 'a' && hex <= 'f') hex = hex - 'a' + 10; + else if (hex >= 'A' && hex <= 'F') hex = hex - 'A' + 10; + return hex; + // printf ("%d\n",$hex) ?? + } + + void printHex2(const byte hex) { // Todo: printf oder scanf nutzen + if (hex < 16) { + MSG_PRINT("0"); + } + // char hexstr[2] = {0}; + //sprintf(hexstr, "%02X", hex); + + MSG_PRINT(hex, HEX); + } + + uint8_t sendSPI(const uint8_t val) { // send byte via SPI + #ifndef ESP8266 + SPDR = val; // transfer byte via SPI + while (!(SPSR & _BV(SPIF))); // wait until SPI operation is terminated + return SPDR; + #else + return SPI.transfer(val); + #endif + } + + uint8_t cmdStrobe(const uint8_t cmd) { // send command strobe to the CC1101 IC via SPI + #ifndef ESP8266 + cc1101_Select(); // select CC1101 + wait_Miso(); // wait until MISO goes low + #endif + uint8_t ret = sendSPI(cmd); // send strobe command + #ifndef ESP8266 + wait_Miso(); // wait until MISO goes low + cc1101_Deselect(); // deselect CC1101 + #endif + return ret; // Chip Status Byte + } + + uint8_t readReg(const uint8_t regAddr, const uint8_t regType) { // read CC1101 register via SPI + cc1101_Select(); // select CC1101 + wait_Miso(); // wait until MISO goes low + sendSPI(regAddr | regType); // send register address + uint8_t val = sendSPI(0x00); // read result + cc1101_Deselect(); // deselect CC1101 + return val; + } + + void writeReg(const uint8_t regAddr, const uint8_t val) { // write single register into the CC1101 IC via SPI + cc1101_Select(); // select CC1101 + wait_Miso(); // wait until MISO goes low + sendSPI(regAddr); // send register address + sendSPI(val); // send value + cc1101_Deselect(); // deselect CC1101 + } + + void readPatable(void) { + uint8_t PatableArray[8]; + // das PatableArray wird zum zwischenspeichern der PATABLE verwendet, + // da ich mir nicht sicher bin ob es timing maessig passt, wenn es nach jedem sendSPI(0x00) eine kurze Pause beim msgprint gibt. + + cc1101_Select(); // select CC1101 + wait_Miso(); // wait until MISO goes low + sendSPI(CC1100_PATABLE | CC1100_READ_BURST); // send register address + for (uint8_t i = 0; i < 8; i++) { + PatableArray[i] = sendSPI(0x00); // read result + } + cc1101_Deselect(); + + for (uint8_t i = 0; i < 8; i++) { + printHex2(PatableArray[i]); + MSG_PRINT(" "); + } + MSG_PRINTLN(""); + } + + void writePatable(void) { + cc1101_Select(); // select CC1101 + wait_Miso(); // wait until MISO goes low + sendSPI(CC1100_PATABLE | CC1100_WRITE_BURST); // send register address + for (uint8_t i = 0; i < 8; i++) { + sendSPI(EEPROM.read(EE_CC1100_PA+i)); // send value + } + cc1101_Deselect(); + } + + + void readCCreg(const uint8_t reg) { // read CC11001 register + uint8_t var; + uint8_t hex; + uint8_t n; + + if (cmdstring.charAt(3) == 'n' && isHexadecimalDigit(cmdstring.charAt(4))) { // Cn gibt anz+2 fortlaufende register zurueck + hex = (uint8_t)cmdstring.charAt(4); + n = hex2int(hex); + if (reg < 0x2F) { + MSG_PRINT("C"); + printHex2(reg); + MSG_PRINT("n"); + n += 2; + printHex2(n); + MSG_PRINT("="); + for (uint8_t i = 0; i < n; i++) { + var = readReg(reg + i, CC1101_CONFIG); + printHex2(var); + } + MSG_PRINTLN(""); + } + } else { + if (reg < 0x3E) { + if (reg < 0x2F) { + var = readReg(reg, CC1101_CONFIG); + } else { + var = readReg(reg, CC1101_STATUS); + } + MSG_PRINT("C"); + printHex2(reg); + MSG_PRINT(" = "); + printHex2(var); + MSG_PRINTLN(""); + } else if (reg == 0x3E) { // patable + MSG_PRINT(F("C3E = ")); + readPatable(); + } else if (reg == 0x99) { // alle register + for (uint8_t i = 0; i < 0x2f; i++) { + if (i == 0 || i == 0x10 || i == 0x20) { + if (i > 0) { + MSG_PRINT(" "); + } + MSG_PRINT(F("ccreg ")); + printHex2(i); + MSG_PRINT(F(": ")); + } + var = readReg(i, CC1101_CONFIG); + printHex2(var); + MSG_PRINT(" "); + } + MSG_PRINTLN(""); + } + } + } + + void commandStrobes(void) { + uint8_t hex; + uint8_t reg; + uint8_t val; + uint8_t val1; + + if (isHexadecimalDigit(cmdstring.charAt(3))) { + hex = (uint8_t)cmdstring.charAt(3); + reg = hex2int(hex) + 0x30; + if (reg < 0x3e) { + val = cmdStrobe(reg); + delay(1); + val1 = cmdStrobe(0x3D); // No operation. May be used to get access to the chip status byte. + MSG_PRINT(F("cmdStrobeReg ")); + printHex2(reg); + MSG_PRINT(F(" chipStatus ")); + val = val >> 4; + MSG_PRINT(val, HEX); + MSG_PRINT(F(" delay1 ")); + val = val1 >> 4; + MSG_PRINT(val, HEX); + MSG_PRINTLN(""); + } + } + } + + void writeCCreg(uint8_t reg, uint8_t var) { // write CC11001 register + if (reg > 1 && reg < 0x40) { + writeReg(reg-2, var); + MSG_PRINT("W"); + printHex2(reg); + printHex2(var); + MSG_PRINTLN(""); + } + } + + void writeCCpatable(uint8_t var) { // write 8 byte to patable (kein pa ramping) + for (uint8_t i = 0; i < 8; i++) { + if (i == 1) { + EEPROM.write(EE_CC1100_PA + i, var); + } else { + EEPROM.write(EE_CC1100_PA + i, 0); + } + } + writePatable(); + } + + void ccFactoryReset() { + for (uint8_t i = 0; i + +#ifndef ESP8266 + SPCR = _BV(SPE) | _BV(MSTR); // SPI speed = CLK/4 + /* + SPCR = ((1 << SPE) | // SPI Enable + (0 << SPIE) | // SPI Interupt Enable + (0 << DORD) | // Data Order (0:MSB first / 1:LSB first) + (1 << MSTR) | // Master/Slave select + (0 << SPR1) | (0 << SPR0) | // SPI Clock Rate + (0 << CPOL) | // Clock Polarity (0:SCK low / 1:SCK hi when idle) + (0 << CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling) + + SPSR = (1 << SPI2X); // Double Clock Rate + */ +#else + SPI.setDataMode(SPI_MODE0); + SPI.setBitOrder(MSBFIRST); + SPI.begin(); + SPI.setClockDivider(SPI_CLOCK_DIV4); +#endif + + pinAsInput(PIN_SEND); // gdo0Pi, sicherheitshalber bis zum CC1101 init erstmal input +#ifndef ESP8266 + digitalHigh(csPin); // SPI init + digitalHigh(sckPin); + digitalLow(mosiPin); +#endif + } + + uint8_t getRSSI() + { + return readReg(CC1100_RSSI, CC1101_STATUS);// Pruefen ob Umwandung von uint to int den richtigen Wert zurueck gibt + } + + inline void setIdleMode() + { + cmdStrobe(CC1100_SIDLE); // Idle mode + delay(1); + } + + uint8_t currentMode() { + return (cmdStrobe(CC1101_SNOP) & CC1100_STATUS_STATE_BM); + } + + void setReceiveMode() + { + setIdleMode(); + uint8_t maxloop = 0xff; + + while (maxloop-- && (cmdStrobe(CC1100_SRX) & CC1100_STATUS_STATE_BM) != CC1100_STATE_RX) // RX enable + delay(1); + if (maxloop == 0 ) DBG_PRINTLN("CC1101: Setting RX failed"); + + } + + void setTransmitMode() + { + cmdStrobe(CC1100_SFTX); // wird dies benoetigt? Wir verwenden kein FIFO + setIdleMode(); + uint8_t maxloop = 0xff; + while (maxloop-- && (cmdStrobe(CC1100_STX) & CC1100_STATUS_STATE_BM) != CC1100_STATE_TX) // TX enable + delay(1); + if (maxloop == 0) DBG_PRINTLN("CC1101: Setting TX failed"); + } + + void CCinit(void) { // initialize CC1101 + + cc1101_Deselect(); // some deselect and selects to init the cc1101 + delayMicroseconds(30); + + // Begin of power on reset + cc1101_Select(); + delayMicroseconds(30); + + cc1101_Deselect(); + delayMicroseconds(45); + + DBG_PRINTLN("SRES Started"); + cmdStrobe(CC1101_SRES); // send reset + DBG_PRINTLN("POR Done"); + delay(10); + + cc1101_Select(); + + sendSPI(CC1100_WRITE_BURST); + for (uint8_t i = 0; i