[CC1101] Implemented interrupt-driven methods
This commit is contained in:
parent
00d06871c6
commit
c127a27446
5 changed files with 365 additions and 4 deletions
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
RadioLib CC1101 Receive with Interrupts Example
|
||||
|
||||
This example listens for FSK transmissions and tries to
|
||||
receive them. Once a packet is received, an interrupt is
|
||||
triggered.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 module is in slot A on the shield
|
||||
CC1101 cc = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
// carrier frequency: 868.0 MHz
|
||||
// bit rate: 4.8 kbps
|
||||
// Rx bandwidth: 325.0 kHz
|
||||
// frequency deviation: 48.0 kHz
|
||||
// sync word: 0xD391
|
||||
int state = cc.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when new packet is received
|
||||
cc.setGdo0Action(setFlag);
|
||||
|
||||
// start listening for packets
|
||||
Serial.print(F("[CC1101] Starting to listen ... "));
|
||||
state = cc.startReceive();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// if needed, 'listen' mode can be disabled by calling
|
||||
// any of the following methods:
|
||||
//
|
||||
// cc.standby()
|
||||
// cc.sleep()
|
||||
// cc.transmit();
|
||||
// cc.receive();
|
||||
// cc.scanChannel();
|
||||
}
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool receivedFlag = false;
|
||||
|
||||
// disable interrupt when it's not needed
|
||||
volatile bool enableInterrupt = true;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
void setFlag(void) {
|
||||
// check if the interrupt is enabled
|
||||
if(!enableInterrupt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we got a packet, set the flag
|
||||
receivedFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(receivedFlag) {
|
||||
// disable the interrupt service routine while
|
||||
// processing the data
|
||||
enableInterrupt = false;
|
||||
|
||||
// reset flag
|
||||
receivedFlag = false;
|
||||
|
||||
// you can read received data as an Arduino String
|
||||
String str;
|
||||
int state = cc.readData(str);
|
||||
|
||||
// you can also read received data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = cc.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println("[CC1101] Received packet!");
|
||||
|
||||
// print data of the packet
|
||||
Serial.print("[CC1101] Data:\t\t");
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print("[CC1101] RSSI:\t\t");
|
||||
Serial.print(cc.getRSSI());
|
||||
Serial.println(" dBm");
|
||||
|
||||
// print LQI (Link Quality Indicator)
|
||||
// of the last received packet, lower is better
|
||||
Serial.print("[CC1101] LQI:\t\t");
|
||||
Serial.println(cc.getLQI());
|
||||
}
|
||||
|
||||
// we're ready to receive more packets,
|
||||
// enable interrupt service routine
|
||||
enableInterrupt = true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
RadioLib CC1101 Transmit with Interrupts Example
|
||||
|
||||
This example transmits FSK packets with one second delays
|
||||
between them. Each packet contains up to 64 bytes
|
||||
of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 module is in slot A on the shield
|
||||
CC1101 cc = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
// carrier frequency: 868.0 MHz
|
||||
// bit rate: 4.8 kbps
|
||||
// Rx bandwidth: 325.0 kHz
|
||||
// frequency deviation: 48.0 kHz
|
||||
// sync word: 0xD391
|
||||
int state = cc.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when packet transmission is finished
|
||||
cc.setGdo0Action(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[CC1101] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 64 characters long
|
||||
state = cc.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||
0x78, 0xAB, 0xCD, 0xEF};
|
||||
state = cc.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool transmittedFlag = false;
|
||||
|
||||
void setFlag(void) {
|
||||
// packet transmission is finished, set the flag
|
||||
transmittedFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the previous transmission finished
|
||||
if(transmittedFlag) {
|
||||
Serial.println(F("[CC1101] Packet transmission finished!"));
|
||||
|
||||
// wait one second before next transmission
|
||||
delay(1000);
|
||||
|
||||
// send another packet
|
||||
Serial.print(F("[CC1101] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 64 characters long
|
||||
int state = cc.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||
0x78, 0xAB, 0xCD, 0xEF};
|
||||
int state = cc.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -89,6 +89,8 @@ setAmbientTemperature KEYWORD2
|
|||
|
||||
# CC1101-specific
|
||||
getLQI KEYWORD2
|
||||
setGdo0Action KEYWORD2
|
||||
setGdo1Action KEYWORD2
|
||||
|
||||
# ESP8266
|
||||
join KEYWORD2
|
||||
|
|
|
@ -93,8 +93,14 @@ int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
// set mode to standby
|
||||
standby();
|
||||
|
||||
// flush Tx FIFO
|
||||
SPIsendCommand(CC1101_CMD_FLUSH_TX);
|
||||
|
||||
// set GDO0 mapping
|
||||
SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||
int state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// write packet length
|
||||
SPIwriteRegister(CC1101_REG_FIFO, len);
|
||||
|
@ -117,7 +123,7 @@ int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
// flush Tx FIFO
|
||||
SPIsendCommand(CC1101_CMD_FLUSH_TX);
|
||||
|
||||
return(ERR_NONE);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t CC1101::receive(String& str, size_t len) {
|
||||
|
@ -142,7 +148,10 @@ int16_t CC1101::receive(uint8_t* data, size_t len) {
|
|||
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
||||
|
||||
// set GDO0 mapping
|
||||
SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||
int state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set mode to receive
|
||||
SPIsendCommand(CC1101_CMD_RX);
|
||||
|
@ -188,7 +197,7 @@ int16_t CC1101::receive(uint8_t* data, size_t len) {
|
|||
return(ERR_CRC_MISMATCH);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t CC1101::standby() {
|
||||
|
@ -229,6 +238,125 @@ int16_t CC1101::receiveDirect() {
|
|||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void CC1101::setGdo0Action(void (*func)(void), uint8_t dir) {
|
||||
attachInterrupt(digitalPinToInterrupt(_mod->getInt0()), func, dir);
|
||||
}
|
||||
|
||||
void CC1101::setGdo1Action(void (*func)(void), uint8_t dir) {
|
||||
attachInterrupt(digitalPinToInterrupt(_mod->getInt0()), func, dir);
|
||||
}
|
||||
|
||||
int16_t CC1101::startTransmit(String& str, uint8_t addr) {
|
||||
return(CC1101::startTransmit(str.c_str(), addr));
|
||||
}
|
||||
|
||||
int16_t CC1101::startTransmit(const char* str, uint8_t addr) {
|
||||
return(CC1101::startTransmit((uint8_t*)str, strlen(str), addr));
|
||||
}
|
||||
|
||||
int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||
// check packet length
|
||||
if(len > 63) {
|
||||
return(ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
standby();
|
||||
|
||||
// flush Tx FIFO
|
||||
SPIsendCommand(CC1101_CMD_FLUSH_TX);
|
||||
|
||||
// set GDO0 mapping
|
||||
int state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// write packet length
|
||||
SPIwriteRegister(CC1101_REG_FIFO, len);
|
||||
|
||||
// write packet to FIFO
|
||||
SPIwriteRegisterBurst(CC1101_REG_FIFO, data, len);
|
||||
|
||||
// set mode to transmit
|
||||
SPIsendCommand(CC1101_CMD_TX);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t CC1101::startReceive() {
|
||||
// set mode to standby
|
||||
standby();
|
||||
|
||||
// flush Rx FIFO
|
||||
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
||||
|
||||
// set GDO0 mapping
|
||||
int state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set mode to receive
|
||||
SPIsendCommand(CC1101_CMD_RX);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t CC1101::readData(String& str, size_t len) {
|
||||
// create temporary array to store received data
|
||||
char* data = new char[len];
|
||||
int16_t state = CC1101::readData((uint8_t*)data, len);
|
||||
|
||||
// if packet was received successfully, copy data into String
|
||||
if(state == ERR_NONE) {
|
||||
str = String(data);
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t CC1101::readData(uint8_t* data, size_t len) {
|
||||
// get packet length
|
||||
size_t length = SPIreadRegister(CC1101_REG_RXBYTES) - 2;
|
||||
|
||||
// read packet data
|
||||
if(len == 0) {
|
||||
// argument len equal to zero indicates String call, which means dynamically allocated data array
|
||||
// dispose of the original and create a new one
|
||||
delete[] data;
|
||||
data = new uint8_t[length + 1];
|
||||
}
|
||||
SPIreadRegisterBurst(CC1101_REG_FIFO, length, data);
|
||||
|
||||
// read RSSI byte
|
||||
_rawRSSI = SPIgetRegValue(CC1101_REG_FIFO);
|
||||
|
||||
// read LQI and CRC byte
|
||||
uint8_t val = SPIgetRegValue(CC1101_REG_FIFO);
|
||||
_rawLQI = val & 0x7F;
|
||||
|
||||
// add terminating null
|
||||
if(len == 0) {
|
||||
data[length] = 0;
|
||||
}
|
||||
|
||||
// flush Rx FIFO
|
||||
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
||||
|
||||
// set mode to receive
|
||||
SPIsendCommand(CC1101_CMD_RX);
|
||||
|
||||
// check CRC
|
||||
if((val & 0b10000000) == 0b00000000) {
|
||||
return(ERR_CRC_MISMATCH);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
|
||||
int16_t CC1101::setFrequency(float freq) {
|
||||
// check allowed frequency range
|
||||
if(!(((freq > 300.0) && (freq < 348.0)) ||
|
||||
|
|
|
@ -510,6 +510,16 @@ class CC1101: public PhysicalLayer {
|
|||
int16_t transmitDirect(uint32_t FRF = 0);
|
||||
int16_t receiveDirect();
|
||||
|
||||
// interrupt methods
|
||||
void setGdo0Action(void (*func)(void), uint8_t dir = FALLING);
|
||||
void setGdo1Action(void (*func)(void), uint8_t dir = FALLING);
|
||||
int16_t startTransmit(String& str, uint8_t addr = 0);
|
||||
int16_t startTransmit(const char* str, uint8_t addr = 0);
|
||||
int16_t startTransmit(uint8_t* data, size_t len, uint8_t addr = 0);
|
||||
int16_t startReceive();
|
||||
int16_t readData(String& str, size_t len = 0);
|
||||
int16_t readData(uint8_t* data, size_t len);
|
||||
|
||||
// configuration methods
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setBitRate(float br);
|
||||
|
|
Loading…
Add table
Reference in a new issue