Skip to content

Commit

Permalink
Template layer for radio HW abstraction (#223)
Browse files Browse the repository at this point in the history
* apply template to RF24Mesh lib

  in accordance with discussion at nRF24/RF24Network#204

  uses type definition for RF24Mesh and renames class to ESB_Mesh for backwards compatibility.
  updates CI to check RF24Network changes specifically for the template-attempt2 branch

* Update docs for v2.0

* bump major version

---------

Co-authored-by: TMRh20 <[email protected]>
  • Loading branch information
2bndy5 and TMRh20 committed Jun 21, 2023
1 parent e0ba23c commit 2165daa
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 69 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build_arduino.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
- source-url: https://github.com/nRF24/RF24.git
- source-url: https://github.com/nRF24/RF24Network.git
- source-path: ./
- name: nrf_to_nrf
fqbn: ${{ matrix.fqbn }}
enable-deltas-report: ${{ matrix.enable-deltas-report }}
platforms: |
Expand Down Expand Up @@ -70,7 +71,7 @@ jobs:
- "arduino:avr:chiwawa"
- "arduino:avr:one"
- "arduino:avr:unowifi"
# - "arduino:mbed:nano33ble" # pending nRF5x integration
- "arduino:mbed:nano33ble"
- "arduino:samd:mkr1000"
- "arduino:samd:mkrwifi1010"
- "arduino:samd:nano_33_iot"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_platformIO.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ jobs:
needs: [check_formatting, validate_lib_json]
uses: nRF24/.github/.github/workflows/build_platformio.yaml@main
with:
example-path: ${{ matrix.example }}
board-id: ${{ matrix.board }}
example-path: ${{ matrix.example }}
board-id: ${{ matrix.board }}
strategy:
fail-fast: false
matrix:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ build/
.env/
.venv/

# ignore python build artifacts
*.egg-info/

# Cmake build-in-source generated stuff
CMakeCache.txt
CPackConfig.cmake
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,32 @@

Mesh Networking for RF24Network

Introducing **RF24Network & RF24Mesh v2.0** with some *significant API changes*, adding the use of [C++ Templates](https://cplusplus.com/doc/oldtutorial/templates/)
in order to support a range of ESB enabled radios, most recently NRF52x radios.

**Important Notes:**
- Any network layer that uses v2 needs to have RF24Network/RF24Mesh dependencies of v2 or newer. RF24 v1.x is an exception here.
- General usage should remain backward compatible, see the included examples of the related libraries for more info
- Any third party libs that extend the network/mesh layer may also need to be updated to incorporate the new templated class prototypes:
```cpp
template<class radio_t>
class ESBNetwork;

template<class network_t, class radio_t>
class ESBMesh;
```
- Third party libs should also be able to use the backward-compatible typedef in their template:
- ESBGateway.h:
```cpp
template<typename network_t, typename mesh_t>
class ESBGateway
```
and inform the compiler what types they intend to support:
- ESBGateway.cpp:
```cpp
template class ESBGateway<RF24Network, RF24Mesh>;
```
- The auto installers do not perform a version check like package managers, so having the correct versions of the software is important.
- We *will* be maintaining the v1.x versions with bugfixes etc for those who cannot or do not wish to migrate to the newer template approach.
https://nRF24.github.io/RF24Mesh
74 changes: 51 additions & 23 deletions RF24Mesh.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file RF24Mesh.cpp
*
* Class definitions for RF24Mesh
* Class definitions for ESBMesh
*/

#include "RF24Mesh.h"
Expand All @@ -10,7 +10,8 @@
#include <fstream>
#endif

RF24Mesh::RF24Mesh(RF24& _radio, RF24Network& _network) : radio(_radio), network(_network)
template<class network_t, class radio_t>
ESBMesh<network_t, radio_t>::ESBMesh(radio_t& _radio, network_t& _network) : radio(_radio), network(_network)
{
setCallback(NULL);
meshStarted = false;
Expand All @@ -21,7 +22,8 @@ RF24Mesh::RF24Mesh(RF24& _radio, RF24Network& _network) : radio(_radio), network

/*****************************************************/

bool RF24Mesh::begin(uint8_t channel, rf24_datarate_e data_rate, uint32_t timeout)
template<class network_t, class radio_t>
bool ESBMesh<network_t, radio_t>::begin(uint8_t channel, rf24_datarate_e data_rate, uint32_t timeout)
{
//delay(1); // Found problems w/SPIDEV & ncurses. Without this, getch() returns a stream of garbage
if (meshStarted) {
Expand Down Expand Up @@ -57,7 +59,8 @@ bool RF24Mesh::begin(uint8_t channel, rf24_datarate_e data_rate, uint32_t timeou

/*****************************************************/

uint8_t RF24Mesh::update()
template<class network_t, class radio_t>
uint8_t ESBMesh<network_t, radio_t>::update()
{
uint8_t type = network.update();
if (mesh_address == MESH_DEFAULT_ADDRESS) return type;
Expand Down Expand Up @@ -100,7 +103,8 @@ uint8_t RF24Mesh::update()

/*****************************************************/

bool RF24Mesh::write(uint16_t to_node, const void* data, uint8_t msg_type, size_t size)
template<class network_t, class radio_t>
bool ESBMesh<network_t, radio_t>::write(uint16_t to_node, const void* data, uint8_t msg_type, size_t size)
{
if (mesh_address == MESH_DEFAULT_ADDRESS) return 0;

Expand All @@ -110,7 +114,8 @@ bool RF24Mesh::write(uint16_t to_node, const void* data, uint8_t msg_type, size_

/*****************************************************/

bool RF24Mesh::write(const void* data, uint8_t msg_type, size_t size, uint8_t nodeID)
template<class network_t, class radio_t>
bool ESBMesh<network_t, radio_t>::write(const void* data, uint8_t msg_type, size_t size, uint8_t nodeID)
{
if (mesh_address == MESH_DEFAULT_ADDRESS) return 0;

Expand All @@ -132,7 +137,8 @@ bool RF24Mesh::write(const void* data, uint8_t msg_type, size_t size, uint8_t no

/*****************************************************/

void RF24Mesh::setChannel(uint8_t _channel)
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::setChannel(uint8_t _channel)
{
radio.stopListening();
radio.setChannel(_channel);
Expand All @@ -141,14 +147,16 @@ void RF24Mesh::setChannel(uint8_t _channel)

/*****************************************************/

void RF24Mesh::setChild(bool allow)
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::setChild(bool allow)
{
network.networkFlags = allow ? network.networkFlags & ~FLAG_NO_POLL : network.networkFlags | FLAG_NO_POLL;
}

/*****************************************************/

bool RF24Mesh::checkConnection()
template<class network_t, class radio_t>
bool ESBMesh<network_t, radio_t>::checkConnection()
{
// getAddress() doesn't use auto-ack; do a double-check to manually retry 1 more time
if (getAddress(_nodeID) < 1) {
Expand All @@ -161,7 +169,8 @@ bool RF24Mesh::checkConnection()

/*****************************************************/

int16_t RF24Mesh::getAddress(uint8_t nodeID)
template<class network_t, class radio_t>
int16_t ESBMesh<network_t, radio_t>::getAddress(uint8_t nodeID)
{ // Master will return and send 00 address for a nodeID with address 0, -1 if not found

//if (nodeID == _nodeID) return mesh_address;
Expand Down Expand Up @@ -198,7 +207,8 @@ int16_t RF24Mesh::getAddress(uint8_t nodeID)

/*****************************************************/

int16_t RF24Mesh::getNodeID(uint16_t address)
template<class network_t, class radio_t>
int16_t ESBMesh<network_t, radio_t>::getNodeID(uint16_t address)
{
if (address == MESH_BLANK_ID) return _nodeID;
if (address == 0) return 0;
Expand Down Expand Up @@ -231,7 +241,8 @@ int16_t RF24Mesh::getNodeID(uint16_t address)

/*****************************************************/

uint8_t RF24Mesh::getLevel(uint16_t address)
template<class network_t, class radio_t>
uint8_t ESBMesh<network_t, radio_t>::getLevel(uint16_t address)
{
uint8_t count = 0;
while (address) {
Expand All @@ -243,7 +254,8 @@ uint8_t RF24Mesh::getLevel(uint16_t address)

/*****************************************************/

void RF24Mesh::beginDefault()
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::beginDefault()
{
radio.stopListening();
network.begin(MESH_DEFAULT_ADDRESS);
Expand All @@ -252,7 +264,8 @@ void RF24Mesh::beginDefault()

/*****************************************************/

bool RF24Mesh::releaseAddress()
template<class network_t, class radio_t>
bool ESBMesh<network_t, radio_t>::releaseAddress()
{
if (mesh_address == MESH_DEFAULT_ADDRESS) return 0;

Expand All @@ -266,7 +279,8 @@ bool RF24Mesh::releaseAddress()

/*****************************************************/

uint16_t RF24Mesh::renewAddress(uint32_t timeout)
template<class network_t, class radio_t>
uint16_t ESBMesh<network_t, radio_t>::renewAddress(uint32_t timeout)
{
if (radio.available()) network.update();

Expand Down Expand Up @@ -295,7 +309,8 @@ uint16_t RF24Mesh::renewAddress(uint32_t timeout)

/*****************************************************/

bool RF24Mesh::requestAddress(uint8_t level)
template<class network_t, class radio_t>
bool ESBMesh<network_t, radio_t>::requestAddress(uint8_t level)
{
RF24NetworkHeader header(MESH_MULTICAST_ADDRESS, NETWORK_POLL);
//Find another radio, starting with level 0 multicast
Expand Down Expand Up @@ -397,22 +412,25 @@ bool RF24Mesh::requestAddress(uint8_t level)

/*****************************************************/

void RF24Mesh::setNodeID(uint8_t nodeID)
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::setNodeID(uint8_t nodeID)
{
_nodeID = nodeID;
}

/*****************************************************/
#if !defined(MESH_NOMASTER)

void RF24Mesh::setStaticAddress(uint8_t nodeID, uint16_t address)
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::setStaticAddress(uint8_t nodeID, uint16_t address)
{
setAddress(nodeID, address);
}

/*****************************************************/

void RF24Mesh::setAddress(uint8_t nodeID, uint16_t address, bool searchBy)
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::setAddress(uint8_t nodeID, uint16_t address, bool searchBy)
{
//Look for the node in the list
for (uint8_t i = 0; i < addrListTop; i++) {
Expand Down Expand Up @@ -449,7 +467,8 @@ void RF24Mesh::setAddress(uint8_t nodeID, uint16_t address, bool searchBy)

/*****************************************************/

void RF24Mesh::loadDHCP()
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::loadDHCP()
{

#if defined(__linux) && !defined(__ARDUINO_X86__)
Expand All @@ -472,7 +491,8 @@ void RF24Mesh::loadDHCP()

/*****************************************************/

void RF24Mesh::saveDHCP()
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::saveDHCP()
{
#if defined(__linux) && !defined(__ARDUINO_X86__)
std::ofstream outfile("dhcplist.txt", std::ofstream::binary | std::ofstream::trunc);
Expand All @@ -486,7 +506,8 @@ void RF24Mesh::saveDHCP()

/*****************************************************/

void RF24Mesh::DHCP()
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::DHCP()
{
if (doDHCP)
doDHCP = false;
Expand Down Expand Up @@ -576,10 +597,17 @@ void RF24Mesh::DHCP()

#endif // !MESH_NOMASTER

void RF24Mesh::setCallback(void (*meshCallback)(void))
template<class network_t, class radio_t>
void ESBMesh<network_t, radio_t>::setCallback(void (*meshCallback)(void))
{

this->meshCallback = meshCallback;
}

/*****************************************************/

// ensure the compiler is aware of the possible datatype for the template class
template class ESBMesh<ESBNetwork<RF24>, RF24>;
#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_NRF52840)
template class ESBMesh<ESBNetwork<nrf_to_nrf>, nrf_to_nrf>;
#endif
Loading

0 comments on commit 2165daa

Please sign in to comment.