Receive messages for multiple POCSAG RICs (#998)

* Make it possible to supply a list of addresses for POCSAG reception.

* Initialize some instance variables to sensible values.
This commit is contained in:
Jan Szumiec 2024-03-02 18:01:32 +01:00 committed by GitHub
parent 744834509f
commit 268e2d704f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 3 deletions

View file

@ -28,6 +28,9 @@ PagerClient::PagerClient(PhysicalLayer* phy) {
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
readBitInstance = phyLayer;
#endif
filterNumAddresses = 0;
filterAddresses = NULL;
filterMasks = NULL;
}
int16_t PagerClient::begin(float base, uint16_t speed, bool invert, uint16_t shift) {
@ -246,6 +249,21 @@ int16_t PagerClient::startReceive(uint32_t pin, uint32_t addr, uint32_t mask) {
filterAddr = addr;
filterMask = mask;
return startReceiveCommon();
}
int16_t PagerClient::startReceive(uint32_t pin, uint32_t *addrs, uint32_t *masks, size_t numAddresses) {
// save the variables
readBitPin = pin;
filterAddresses = addrs;
filterMasks = masks;
filterNumAddresses = numAddresses;
return startReceiveCommon();
}
uint16_t PagerClient::startReceiveCommon() {
// set the carrier frequency
int16_t state = phyLayer->setFrequency(baseFreq);
RADIOLIB_ASSERT(state);
@ -260,7 +278,7 @@ int16_t PagerClient::startReceive(uint32_t pin, uint32_t addr, uint32_t mask) {
// now set up the direct mode reception
Module* mod = phyLayer->getMod();
mod->hal->pinMode(pin, mod->hal->GpioModeInput);
mod->hal->pinMode(readBitPin, mod->hal->GpioModeInput);
// set direct sync word to the frame sync word
// the logic here is inverted, because modules like SX1278
@ -356,8 +374,7 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) {
// should be an address code word, extract the address
uint32_t addr_found = ((cw & RADIOLIB_PAGER_ADDRESS_BITS_MASK) >> (RADIOLIB_PAGER_ADDRESS_POS - 3)) | (framePos/2);
if((addr_found & filterMask) == (filterAddr & filterMask)) {
// we have a match!
if (addressMatched(addr_found)) {
match = true;
if(addr) {
*addr = addr_found;
@ -460,6 +477,22 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) {
}
#endif
bool PagerClient::addressMatched(uint32_t addr) {
if (filterNumAddresses == 0) {
return ((addr & filterMask) == (filterAddr & filterMask));
} else {
if (filterAddresses == NULL || filterMasks == NULL) {
return false;
}
for (size_t i = 0; i < filterNumAddresses; i++) {
if ((filterAddresses[i] & filterMasks[i]) == (addr & filterMasks[i])) {
return true;
}
}
return false;
}
}
void PagerClient::write(uint32_t* data, size_t len) {
// write code words from buffer
for(size_t i = 0; i < len; i++) {

View file

@ -130,6 +130,15 @@ class PagerClient {
*/
int16_t startReceive(uint32_t pin, uint32_t addr, uint32_t mask = 0xFFFFF);
/*!
\brief Start reception of POCSAG packets for multiple addresses and masks.
\param pin Pin to receive digital data on (e.g., DIO2 for SX127x).
\param addrs Array of addresses to receive.
\param masks Array of address masks to use for filtering. Masks will be applied to corresponding addresses in addr array.
\returns \ref status_codes
*/
int16_t startReceive(uint32_t pin, uint32_t *addrs, uint32_t *masks, size_t numAddress);
/*!
\brief Get the number of POCSAG batches available in buffer. Limited by the size of direct mode buffer!
\returns Number of available batches.
@ -175,10 +184,15 @@ class PagerClient {
uint16_t bitDuration;
uint32_t filterAddr;
uint32_t filterMask;
uint32_t *filterAddresses;
uint32_t *filterMasks;
size_t filterNumAddresses;
bool inv = false;
void write(uint32_t* data, size_t len);
void write(uint32_t codeWord);
uint16_t startReceiveCommon();
bool addressMatched(uint32_t addr);
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
uint32_t read();