diff --git a/examples/CC1101_Transmit/CC1101_Transmit.ino b/examples/CC1101_Transmit/CC1101_Transmit.ino new file mode 100644 index 00000000..06d65353 --- /dev/null +++ b/examples/CC1101_Transmit/CC1101_Transmit.ino @@ -0,0 +1,56 @@ +/* + KiteLib CC1101 Transmit Example + + This example transmits packets using RF69 FSK radio module. +*/ + +// include the library +#include + +// CC1101 is in slot A on the shield +CC1101 cc = Kite.ModuleA; + +void setup() { + Serial.begin(9600); + + // initialize CC1101 + Serial.print(F("[CC1101] Initializing ... ")); + // carrier frequency: 868.0 MHz + // bit rate: 115.2 kbps + // Rx bandwidth: 203 kHz + // frequency deviation: 48.0 kHz + int state = cc.begin(434); + if(state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while(true); + } +} + +void loop() { + Serial.print(F("[CC1101] Transmitting packet ... ")); + + // you can transmit C-string or Arduino string up to 255 characters long + int state = cc.transmit("Hello World!"); + + // you can also transmit byte array up to 255 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + int state = cc.transmit(byteArr, 8); + */ + + if (state == ERR_NONE) { + // the packet was successfully transmitted + Serial.println(" success!"); + + } else if (state == ERR_PACKET_TOO_LONG) { + // the supplied packet was longer than 255 bytes + Serial.println(" too long!"); + + } + + // wait for a second before transmitting again + delay(1000); +} diff --git a/src/modules/CC1101.cpp b/src/modules/CC1101.cpp index 90fee162..6205056d 100644 --- a/src/modules/CC1101.cpp +++ b/src/modules/CC1101.cpp @@ -81,12 +81,37 @@ int16_t CC1101::transmit(const char* str, uint8_t addr) { } int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) { - // TODO // check packet length + if(len > 255) { + return(ERR_PACKET_TOO_LONG); + } - // set GDO0 and GDO2 mapping - // set mode to standby + standby(); + + // set GDO0 mapping + _mod->SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED); + + // write packet length + _mod->SPIwriteRegister(CC1101_REG_FIFO, len); + + // write packet to FIFO + _mod->SPIwriteRegisterBurst(CC1101_REG_FIFO | CC1101_CMD_BURST, data, len); + + // set mode to transmit + SPIsendCommand(CC1101_CMD_TX); + + // wait for transmission start + while(!digitalRead(_mod->getInt0())); + + // wait for transmission end + while(digitalRead(_mod->getInt0())); + + // set mode to standby + standby(); + + // flush Tx FIFO + SPIsendCommand(CC1101_CMD_FLUSH_TX); return(ERR_NONE); } @@ -107,7 +132,10 @@ int16_t CC1101::receive(String& str, size_t len) { int16_t CC1101::receive(uint8_t* data, size_t len) { // TODO - + // set mode to standby + + // set GDO0 and GDO2 mapping + return(ERR_NONE); } @@ -138,8 +166,14 @@ int16_t CC1101::transmitDirect(uint32_t FRF) { } int16_t CC1101::receiveDirect() { - // TODO - + // activate direct mode + int16_t state = directMode(); + if(state != ERR_NONE) { + return(state); + } + + // start receiving + SPIsendCommand(CC1101_CMD_RX); return(ERR_NONE); } @@ -234,10 +268,23 @@ int16_t CC1101::setFrequencyDeviation(float freqDev) { return(state); } -int16_t CC1101::config() { - // enable autmatic frequency synthesizer calibration - int16_t state = _mod->SPIsetRegValue(CC1101_REG_MCSM0, CC1101_FS_AUTOCAL_IDLE_TO_RXTX, 5, 4); +int16_t CC1101::setSyncWord(uint8_t syncH, uint8_t syncL) { + // set sync word + int16_t state = _mod->SPIsetRegValue(CC1101_REG_SYNC1, syncH); + state |= _mod->SPIsetRegValue(CC1101_REG_SYNC0, syncL); + return(state); +} +int16_t CC1101::config() { + // enable automatic frequency synthesizer calibration + int16_t state = _mod->SPIsetRegValue(CC1101_REG_MCSM0, CC1101_FS_AUTOCAL_IDLE_TO_RXTX, 5, 4); + if(state != ERR_NONE) { + return(state); + } + + // set output power + _mod->SPIwriteRegister(CC1101_REG_PATABLE, 0x60); + return(state); } @@ -280,12 +327,26 @@ void CC1101::getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8 } } +void CC1101::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len) { + _mod->SPIwriteRegisterBurst(reg | CC1101_CMD_BURST, data, len); +} + int16_t CC1101::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) { - return(_mod->SPIgetRegValue(reg | CC1101_CMD_ACCESS_STATUS_REG, msb, lsb)); + // status registers require special command + if(reg > CC1101_REG_TEST0) { + reg |= CC1101_CMD_ACCESS_STATUS_REG; + } + + return(_mod->SPIgetRegValue(reg, msb, lsb)); } uint8_t CC1101::SPIreadRegister(uint8_t reg) { - return(_mod->SPIreadRegister(reg | CC1101_CMD_ACCESS_STATUS_REG)); + // status registers require special command + if(reg > CC1101_REG_TEST0) { + reg |= CC1101_CMD_ACCESS_STATUS_REG; + } + + return(_mod->SPIreadRegister(reg)); } void CC1101::SPIsendCommand(uint8_t cmd) { diff --git a/src/modules/CC1101.h b/src/modules/CC1101.h index a2734f10..796945ad 100644 --- a/src/modules/CC1101.h +++ b/src/modules/CC1101.h @@ -30,8 +30,6 @@ #define CC1101_CMD_FLUSH_TX 0x3B #define CC1101_CMD_WOR_RESET 0x3C #define CC1101_CMD_NOP 0x3D -#define CC1101_CMD_PATABLE 0x3E -#define CC1101_CMD_FIFO 0x3F // CC1101 regsiter map #define CC1101_REG_IOCFG2 0x00 @@ -61,9 +59,9 @@ #define CC1101_REG_MCSM0 0x18 #define CC1101_REG_FOCCFG 0x19 #define CC1101_REG_BSCFG 0x1A -#define CC1101_REG_AGCTRL2 0x1B -#define CC1101_REG_AGCTRL1 0x1C -#define CC1101_REG_AGCTRL0 0x1D +#define CC1101_REG_AGCCTRL2 0x1B +#define CC1101_REG_AGCCTRL1 0x1C +#define CC1101_REG_AGCCTRL0 0x1D #define CC1101_REG_WOREVT1 0x1E #define CC1101_REG_WOREVT0 0x1F #define CC1101_REG_WORCTRL 0x20 @@ -95,6 +93,8 @@ #define CC1101_REG_RXBYTES 0x3B #define CC1101_REG_RCCTRL1_STATUS 0x3C #define CC1101_REG_RCCTRL0_STATUS 0x3D +#define CC1101_REG_PATABLE 0x3E +#define CC1101_REG_FIFO 0x3F // CC1101_REG_IOCFG2 MSB LSB DESCRIPTION #define CC1101_GDO2_NORM 0b00000000 // 6 6 GDO2 output: active high (default) @@ -513,6 +513,7 @@ class CC1101: public PhysicalLayer { int16_t setBitRate(float br); int16_t setRxBandwidth(float rxBw); int16_t setFrequencyDeviation(float freqDev); + int16_t setSyncWord(uint8_t syncH, uint8_t syncL); private: Module* _mod; @@ -521,7 +522,8 @@ class CC1101: public PhysicalLayer { int16_t directMode(); void getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant); - // SPI read overrides to set access bit for status registers + // SPI read overrides to set bit for burst write and status registers access + void SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len); int16_t SPIgetRegValue(uint8_t reg, uint8_t msb = 7, uint8_t lsb = 0); uint8_t SPIreadRegister(uint8_t reg);