Merge pull request #279 from rfquack/master
New .gitignore pattern, CC1101 streaming mode, RF69 SPI get/set/read/write overrides
This commit is contained in:
commit
070b4f5f83
5 changed files with 120 additions and 24 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -11,3 +11,6 @@
|
||||||
# Debug decoder
|
# Debug decoder
|
||||||
extras/decoder/log.txt
|
extras/decoder/log.txt
|
||||||
extras/decoder/out.txt
|
extras/decoder/out.txt
|
||||||
|
|
||||||
|
# PlatformIO
|
||||||
|
.pio*
|
||||||
|
|
|
@ -262,19 +262,32 @@ int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||||
int16_t state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
int16_t state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// data put on FIFO.
|
||||||
|
uint8_t dataSent = 0;
|
||||||
|
|
||||||
// optionally write packet length
|
// optionally write packet length
|
||||||
if (_packetLengthConfig == CC1101_LENGTH_CONFIG_VARIABLE) {
|
if (_packetLengthConfig == CC1101_LENGTH_CONFIG_VARIABLE) {
|
||||||
|
|
||||||
|
// enforce variable len limit.
|
||||||
|
if (len > CC1101_MAX_PACKET_LENGTH - 1) {
|
||||||
|
return (ERR_PACKET_TOO_LONG);
|
||||||
|
}
|
||||||
|
|
||||||
SPIwriteRegister(CC1101_REG_FIFO, len);
|
SPIwriteRegister(CC1101_REG_FIFO, len);
|
||||||
|
dataSent += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check address filtering
|
// check address filtering
|
||||||
uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0);
|
uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0);
|
||||||
if(filter != CC1101_ADR_CHK_NONE) {
|
if(filter != CC1101_ADR_CHK_NONE) {
|
||||||
SPIwriteRegister(CC1101_REG_FIFO, addr);
|
SPIwriteRegister(CC1101_REG_FIFO, addr);
|
||||||
|
dataSent += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write packet to FIFO
|
// fill the FIFO.
|
||||||
SPIwriteRegisterBurst(CC1101_REG_FIFO, data, len);
|
uint8_t initialWrite = min((uint8_t)len, (uint8_t)(CC1101_FIFO_SIZE - dataSent));
|
||||||
|
SPIwriteRegisterBurst(CC1101_REG_FIFO, data, initialWrite);
|
||||||
|
dataSent += initialWrite;
|
||||||
|
|
||||||
// set RF switch (if present)
|
// set RF switch (if present)
|
||||||
_mod->setRfSwitchState(LOW, HIGH);
|
_mod->setRfSwitchState(LOW, HIGH);
|
||||||
|
@ -282,7 +295,29 @@ int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||||
// set mode to transmit
|
// set mode to transmit
|
||||||
SPIsendCommand(CC1101_CMD_TX);
|
SPIsendCommand(CC1101_CMD_TX);
|
||||||
|
|
||||||
return(state);
|
// keep feeding the FIFO until the packet is over.
|
||||||
|
while (dataSent < len) {
|
||||||
|
// get number of bytes in FIFO.
|
||||||
|
uint8_t bytesInFIFO = SPIgetRegValue(CC1101_REG_TXBYTES, 6, 0);
|
||||||
|
|
||||||
|
// if there's room then put other data.
|
||||||
|
if (bytesInFIFO < CC1101_FIFO_SIZE) {
|
||||||
|
uint8_t bytesToWrite = min((uint8_t)(CC1101_FIFO_SIZE - bytesInFIFO), (uint8_t)(len - dataSent));
|
||||||
|
SPIwriteRegisterBurst(CC1101_REG_FIFO, &data[dataSent], bytesToWrite);
|
||||||
|
dataSent += bytesToWrite;
|
||||||
|
} else {
|
||||||
|
// wait for radio to send some data.
|
||||||
|
/*
|
||||||
|
* Does this work for all rates? If 1 ms is longer than the 1ms delay
|
||||||
|
* then the entire FIFO will be transmitted during that delay.
|
||||||
|
*
|
||||||
|
* TODO: test this on real hardware
|
||||||
|
*/
|
||||||
|
delayMicroseconds(250);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::startReceive() {
|
int16_t CC1101::startReceive() {
|
||||||
|
@ -292,8 +327,9 @@ int16_t CC1101::startReceive() {
|
||||||
// flush Rx FIFO
|
// flush Rx FIFO
|
||||||
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
||||||
|
|
||||||
// set GDO0 mapping
|
// set GDO0 mapping: Asserted when RX FIFO > 4 bytes.
|
||||||
int state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED);
|
int16_t state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_RX_FIFO_FULL_OR_PKT_END);
|
||||||
|
state |= SPIsetRegValue(CC1101_REG_FIFOTHR, CC1101_FIFO_THR_TX_61_RX_4, 3, 0);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set RF switch (if present)
|
// set RF switch (if present)
|
||||||
|
@ -308,8 +344,8 @@ int16_t CC1101::startReceive() {
|
||||||
int16_t CC1101::readData(uint8_t* data, size_t len) {
|
int16_t CC1101::readData(uint8_t* data, size_t len) {
|
||||||
// get packet length
|
// get packet length
|
||||||
size_t length = len;
|
size_t length = len;
|
||||||
if(len == CC1101_MAX_PACKET_LENGTH) {
|
if (len == CC1101_MAX_PACKET_LENGTH) {
|
||||||
length = getPacketLength();
|
length = getPacketLength(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check address filtering
|
// check address filtering
|
||||||
|
@ -318,28 +354,69 @@ int16_t CC1101::readData(uint8_t* data, size_t len) {
|
||||||
SPIreadRegister(CC1101_REG_FIFO);
|
SPIreadRegister(CC1101_REG_FIFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read packet data
|
uint8_t bytesInFIFO = SPIgetRegValue(CC1101_REG_RXBYTES, 6, 0);
|
||||||
SPIreadRegisterBurst(CC1101_REG_FIFO, length, data);
|
size_t readBytes = 0;
|
||||||
|
uint32_t lastPop = millis();
|
||||||
|
|
||||||
// read RSSI byte
|
// keep reading from FIFO until we get all the packet.
|
||||||
_rawRSSI = SPIgetRegValue(CC1101_REG_FIFO);
|
while (readBytes < length) {
|
||||||
|
if (bytesInFIFO == 0) {
|
||||||
|
if (millis() - lastPop > 5) {
|
||||||
|
// readData was required to read a packet longer than the one received.
|
||||||
|
RADIOLIB_DEBUG_PRINTLN(F("No data for more than 5mS. Stop here."));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Does this work for all rates? If 1 ms is longer than the 1ms delay
|
||||||
|
* then the entire FIFO will be transmitted during that delay.
|
||||||
|
*
|
||||||
|
* TODO: drop this delay(1) or come up with a better solution:
|
||||||
|
*/
|
||||||
|
delay(1);
|
||||||
|
bytesInFIFO = SPIgetRegValue(CC1101_REG_RXBYTES, 6, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the minimum between "remaining length" and bytesInFifo
|
||||||
|
uint8_t bytesToRead = min((uint8_t)(length - readBytes), bytesInFIFO);
|
||||||
|
SPIreadRegisterBurst(CC1101_REG_FIFO, bytesToRead, &(data[readBytes]));
|
||||||
|
readBytes += bytesToRead;
|
||||||
|
lastPop = millis();
|
||||||
|
|
||||||
|
// Get how many bytes are left in FIFO.
|
||||||
|
bytesInFIFO = SPIgetRegValue(CC1101_REG_RXBYTES, 6, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if status bytes are enabled (default: CC1101_APPEND_STATUS_ON)
|
||||||
|
bool isAppendStatus = SPIgetRegValue(CC1101_REG_PKTCTRL1, 2, 2) == CC1101_APPEND_STATUS_ON;
|
||||||
|
|
||||||
|
// If status byte is enabled at least 2 bytes (2 status bytes + any following packet) will remain in FIFO.
|
||||||
|
if (bytesInFIFO >= 2 && isAppendStatus) {
|
||||||
|
// read RSSI byte
|
||||||
|
_rawRSSI = SPIgetRegValue(CC1101_REG_FIFO);
|
||||||
|
|
||||||
// read LQI and CRC byte
|
// read LQI and CRC byte
|
||||||
uint8_t val = SPIgetRegValue(CC1101_REG_FIFO);
|
uint8_t val = SPIgetRegValue(CC1101_REG_FIFO);
|
||||||
_rawLQI = val & 0x7F;
|
_rawLQI = val & 0x7F;
|
||||||
|
|
||||||
// flush Rx FIFO
|
// check CRC
|
||||||
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
if (_crcOn && (val & CC1101_CRC_OK) == CC1101_CRC_ERROR) {
|
||||||
|
return (ERR_CRC_MISMATCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// clear internal flag so getPacketLength can return the new packet length
|
// clear internal flag so getPacketLength can return the new packet length
|
||||||
_packetLengthQueried = false;
|
_packetLengthQueried = false;
|
||||||
|
|
||||||
// set mode to standby
|
// Flush then standby according to RXOFF_MODE (default: CC1101_RXOFF_IDLE)
|
||||||
standby();
|
if (SPIgetRegValue(CC1101_REG_MCSM1, 3, 2) == CC1101_RXOFF_IDLE) {
|
||||||
|
|
||||||
// check CRC
|
// flush Rx FIFO
|
||||||
if (_crcOn && (val & 0b10000000) == 0b00000000) {
|
SPIsendCommand(CC1101_CMD_FLUSH_RX);
|
||||||
return (ERR_CRC_MISMATCH);
|
|
||||||
|
// set mode to standby
|
||||||
|
standby();
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
|
@ -609,7 +686,6 @@ int16_t CC1101::setOOK(bool enableOOK) {
|
||||||
state = SPIsetRegValue(CC1101_REG_FREND0, 1, 2, 0);
|
state = SPIsetRegValue(CC1101_REG_FREND0, 1, 2, 0);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
|
||||||
// update current modulation
|
// update current modulation
|
||||||
_modulation = CC1101_MOD_FORMAT_ASK_OOK;
|
_modulation = CC1101_MOD_FORMAT_ASK_OOK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -628,7 +704,6 @@ int16_t CC1101::setOOK(bool enableOOK) {
|
||||||
return(setOutputPower(_power));
|
return(setOutputPower(_power));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float CC1101::getRSSI() const {
|
float CC1101::getRSSI() const {
|
||||||
float rssi;
|
float rssi;
|
||||||
if(_rawRSSI >= 128) {
|
if(_rawRSSI >= 128) {
|
||||||
|
@ -715,9 +790,15 @@ int16_t CC1101::setPromiscuousMode(bool promiscuous) {
|
||||||
state = setCrcFiltering(true);
|
state = setCrcFiltering(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_promiscuous = promiscuous;
|
||||||
|
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CC1101::getPromiscuousMode() {
|
||||||
|
return (_promiscuous);
|
||||||
|
}
|
||||||
|
|
||||||
int16_t CC1101::setDataShaping(uint8_t sh) {
|
int16_t CC1101::setDataShaping(uint8_t sh) {
|
||||||
// set mode to standby
|
// set mode to standby
|
||||||
int16_t state = standby();
|
int16_t state = standby();
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
|
|
||||||
// CC1101 physical layer properties
|
// CC1101 physical layer properties
|
||||||
#define CC1101_FREQUENCY_STEP_SIZE 396.7285156
|
#define CC1101_FREQUENCY_STEP_SIZE 396.7285156
|
||||||
#define CC1101_MAX_PACKET_LENGTH 63
|
#define CC1101_MAX_PACKET_LENGTH 255
|
||||||
#define CC1101_CRYSTAL_FREQ 26.0
|
#define CC1101_CRYSTAL_FREQ 26.0
|
||||||
#define CC1101_DIV_EXPONENT 16
|
#define CC1101_DIV_EXPONENT 16
|
||||||
|
#define CC1101_FIFO_SIZE 64
|
||||||
|
|
||||||
// CC1101 SPI commands
|
// CC1101 SPI commands
|
||||||
#define CC1101_CMD_READ 0b10000000
|
#define CC1101_CMD_READ 0b10000000
|
||||||
|
@ -168,7 +169,7 @@
|
||||||
#define CC1101_RX_ATTEN_6_DB 0b00010000 // 5 4 6 dB
|
#define CC1101_RX_ATTEN_6_DB 0b00010000 // 5 4 6 dB
|
||||||
#define CC1101_RX_ATTEN_12_DB 0b00100000 // 5 4 12 dB
|
#define CC1101_RX_ATTEN_12_DB 0b00100000 // 5 4 12 dB
|
||||||
#define CC1101_RX_ATTEN_18_DB 0b00110000 // 5 4 18 dB
|
#define CC1101_RX_ATTEN_18_DB 0b00110000 // 5 4 18 dB
|
||||||
#define CC1101_FIFO_THR 0b00000111 // 5 4 Rx FIFO threshold [bytes] = CC1101_FIFO_THR * 4; Tx FIFO threshold [bytes] = 65 - (CC1101_FIFO_THR * 4)
|
#define CC1101_FIFO_THR_TX_61_RX_4 0b00000000 // 3 0 TX fifo threshold: 61, RX fifo threshold: 4
|
||||||
|
|
||||||
// CC1101_REG_SYNC1
|
// CC1101_REG_SYNC1
|
||||||
#define CC1101_SYNC_WORD_MSB 0xD3 // 7 0 sync word MSB
|
#define CC1101_SYNC_WORD_MSB 0xD3 // 7 0 sync word MSB
|
||||||
|
@ -599,9 +600,9 @@ class CC1101: public PhysicalLayer {
|
||||||
|
|
||||||
\param func ISR to call.
|
\param func ISR to call.
|
||||||
|
|
||||||
\param dir Signal change direction. Defaults to FALLING.
|
\param dir Signal change direction. Defaults to RISING.
|
||||||
*/
|
*/
|
||||||
void setGdo0Action(void (*func)(void), RADIOLIB_INTERRUPT_STATUS dir = FALLING);
|
void setGdo0Action(void (*func)(void), RADIOLIB_INTERRUPT_STATUS dir = RISING);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Clears interrupt service routine to call when GDO0 activates.
|
\brief Clears interrupt service routine to call when GDO0 activates.
|
||||||
|
@ -846,6 +847,13 @@ class CC1101: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
int16_t setPromiscuousMode(bool promiscuous = true);
|
int16_t setPromiscuousMode(bool promiscuous = true);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Get whether the modem is in promiscuous mode: no packet filtering (e.g., no preamble, sync word, address, CRC).
|
||||||
|
|
||||||
|
\returns Whether the modem is in promiscuous mode
|
||||||
|
*/
|
||||||
|
bool getPromiscuousMode();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets Gaussian filter bandwidth-time product that will be used for data shaping.
|
\brief Sets Gaussian filter bandwidth-time product that will be used for data shaping.
|
||||||
Allowed value is RADIOLIB_SHAPING_0_5. Set to RADIOLIB_SHAPING_NONE to disable data shaping.
|
Allowed value is RADIOLIB_SHAPING_0_5. Set to RADIOLIB_SHAPING_NONE to disable data shaping.
|
||||||
|
|
|
@ -407,6 +407,9 @@ int16_t RF69::setFrequency(float freq) {
|
||||||
_mod->SPIwriteRegister(RF69_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
|
_mod->SPIwriteRegister(RF69_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
|
||||||
_mod->SPIwriteRegister(RF69_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
|
_mod->SPIwriteRegister(RF69_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
|
||||||
_mod->SPIwriteRegister(RF69_REG_FRF_LSB, FRF & 0x0000FF);
|
_mod->SPIwriteRegister(RF69_REG_FRF_LSB, FRF & 0x0000FF);
|
||||||
|
|
||||||
|
_freq = freq;
|
||||||
|
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -878,6 +878,7 @@ class RF69: public PhysicalLayer {
|
||||||
protected:
|
protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float _freq = 0;
|
||||||
float _br = 0;
|
float _br = 0;
|
||||||
float _rxBw = 0;
|
float _rxBw = 0;
|
||||||
bool _ook = false;
|
bool _ook = false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue