fd

Dependents:   xtoff3 CYS_Receiver

Fork of RF24Network by Akash Vibhute

Committer:
akashvibhute
Date:
Mon Jul 06 05:18:22 2015 +0000
Revision:
1:caf146ffe8b0
Parent:
0:c3db0798d9aa
Child:
2:a5f8e04bd02b
Maniacbug's RF24Network arduino library ported to mbed. Tested, it works for Nucleo F411

Who changed what in which revision?

UserRevisionLine numberNew contents of line
akashvibhute 0:c3db0798d9aa 1 /*
akashvibhute 0:c3db0798d9aa 2 Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
akashvibhute 0:c3db0798d9aa 3
akashvibhute 0:c3db0798d9aa 4 This program is free software; you can redistribute it and/or
akashvibhute 0:c3db0798d9aa 5 modify it under the terms of the GNU General Public License
akashvibhute 0:c3db0798d9aa 6 version 2 as published by the Free Software Foundation.
akashvibhute 0:c3db0798d9aa 7 */
akashvibhute 0:c3db0798d9aa 8
akashvibhute 0:c3db0798d9aa 9 #include "RF24Network_config.h"
akashvibhute 0:c3db0798d9aa 10 #include <RF24.h>
akashvibhute 0:c3db0798d9aa 11 #include "RF24Network.h"
akashvibhute 0:c3db0798d9aa 12
akashvibhute 0:c3db0798d9aa 13 uint16_t RF24NetworkHeader::next_id = 1;
akashvibhute 0:c3db0798d9aa 14
akashvibhute 0:c3db0798d9aa 15 uint64_t pipe_address( uint16_t node, uint8_t pipe );
akashvibhute 0:c3db0798d9aa 16 bool is_valid_address( uint16_t node );
akashvibhute 0:c3db0798d9aa 17
akashvibhute 0:c3db0798d9aa 18 /******************************************************************/
akashvibhute 0:c3db0798d9aa 19
akashvibhute 0:c3db0798d9aa 20 RF24Network::RF24Network( RF24& _radio ): radio(_radio), next_frame(frame_queue)
akashvibhute 0:c3db0798d9aa 21 {
akashvibhute 0:c3db0798d9aa 22 }
akashvibhute 0:c3db0798d9aa 23
akashvibhute 0:c3db0798d9aa 24 /******************************************************************/
akashvibhute 0:c3db0798d9aa 25
akashvibhute 0:c3db0798d9aa 26 void RF24Network::begin(uint8_t _channel, uint16_t _node_address )
akashvibhute 0:c3db0798d9aa 27 {
akashvibhute 0:c3db0798d9aa 28 if (! is_valid_address(_node_address) )
akashvibhute 0:c3db0798d9aa 29 return;
akashvibhute 0:c3db0798d9aa 30
akashvibhute 0:c3db0798d9aa 31 node_address = _node_address;
akashvibhute 0:c3db0798d9aa 32
akashvibhute 0:c3db0798d9aa 33 // Set up the radio the way we want it to look
akashvibhute 0:c3db0798d9aa 34 radio.setChannel(_channel);
akashvibhute 0:c3db0798d9aa 35 radio.setDataRate(RF24_1MBPS);
akashvibhute 0:c3db0798d9aa 36 radio.setCRCLength(RF24_CRC_16);
akashvibhute 0:c3db0798d9aa 37
akashvibhute 1:caf146ffe8b0 38 // Setup Auto ack enabled as it is required by nodes
akashvibhute 1:caf146ffe8b0 39 radio.setAutoAck(1);
akashvibhute 0:c3db0798d9aa 40
akashvibhute 0:c3db0798d9aa 41 // Setup our address helper cache
akashvibhute 0:c3db0798d9aa 42 setup_address();
akashvibhute 0:c3db0798d9aa 43
akashvibhute 0:c3db0798d9aa 44 // Open up all listening pipes
akashvibhute 0:c3db0798d9aa 45 int i = 6;
akashvibhute 0:c3db0798d9aa 46 while (i--)
akashvibhute 0:c3db0798d9aa 47 radio.openReadingPipe(i,pipe_address(_node_address,i));
akashvibhute 0:c3db0798d9aa 48 radio.startListening();
akashvibhute 0:c3db0798d9aa 49
akashvibhute 0:c3db0798d9aa 50 // Spew debugging state about the radio
akashvibhute 0:c3db0798d9aa 51 radio.printDetails();
akashvibhute 0:c3db0798d9aa 52 }
akashvibhute 0:c3db0798d9aa 53
akashvibhute 0:c3db0798d9aa 54 /******************************************************************/
akashvibhute 0:c3db0798d9aa 55
akashvibhute 0:c3db0798d9aa 56 void RF24Network::update(void)
akashvibhute 0:c3db0798d9aa 57 {
akashvibhute 0:c3db0798d9aa 58 // if there is data ready
akashvibhute 0:c3db0798d9aa 59 uint8_t pipe_num;
akashvibhute 0:c3db0798d9aa 60 while ( radio.available(&pipe_num) )
akashvibhute 0:c3db0798d9aa 61 {
akashvibhute 0:c3db0798d9aa 62 // Dump the payloads until we've gotten everything
akashvibhute 0:c3db0798d9aa 63 bool done = false;
akashvibhute 0:c3db0798d9aa 64 while (!done)
akashvibhute 0:c3db0798d9aa 65 {
akashvibhute 0:c3db0798d9aa 66 // Fetch the payload, and see if this was the last one.
akashvibhute 0:c3db0798d9aa 67 done = radio.read( frame_buffer, sizeof(frame_buffer) );
akashvibhute 0:c3db0798d9aa 68
akashvibhute 0:c3db0798d9aa 69 // Read the beginning of the frame as the header
akashvibhute 0:c3db0798d9aa 70 const RF24NetworkHeader& header = * reinterpret_cast<RF24NetworkHeader*>(frame_buffer);
akashvibhute 0:c3db0798d9aa 71
akashvibhute 0:c3db0798d9aa 72 //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Received on %u %s\n\r"),millis(),pipe_num,header.toString()));
akashvibhute 0:c3db0798d9aa 73 //IF_SERIAL_DEBUG(const uint16_t* i = reinterpret_cast<const uint16_t*>(frame_buffer + sizeof(RF24NetworkHeader));printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i));
akashvibhute 0:c3db0798d9aa 74
akashvibhute 0:c3db0798d9aa 75 // Throw it away if it's not a valid address
akashvibhute 0:c3db0798d9aa 76 if ( !is_valid_address(header.to_node) )
akashvibhute 0:c3db0798d9aa 77 continue;
akashvibhute 0:c3db0798d9aa 78
akashvibhute 0:c3db0798d9aa 79 // Is this for us?
akashvibhute 0:c3db0798d9aa 80 if ( header.to_node == node_address )
akashvibhute 0:c3db0798d9aa 81 // Add it to the buffer of frames for us
akashvibhute 0:c3db0798d9aa 82 enqueue();
akashvibhute 0:c3db0798d9aa 83 else
akashvibhute 0:c3db0798d9aa 84 // Relay it
akashvibhute 0:c3db0798d9aa 85 write(header.to_node);
akashvibhute 0:c3db0798d9aa 86
akashvibhute 0:c3db0798d9aa 87 // NOT NEEDED anymore. Now all reading pipes are open to start.
akashvibhute 0:c3db0798d9aa 88 #if 0
akashvibhute 0:c3db0798d9aa 89 // If this was for us, from one of our children, but on our listening
akashvibhute 0:c3db0798d9aa 90 // pipe, it could mean that we are not listening to them. If so, open up
akashvibhute 0:c3db0798d9aa 91 // and listen to their talking pipe
akashvibhute 0:c3db0798d9aa 92
akashvibhute 0:c3db0798d9aa 93 if ( header.to_node == node_address && pipe_num == 0 && is_descendant(header.from_node) )
akashvibhute 0:c3db0798d9aa 94 {
akashvibhute 0:c3db0798d9aa 95 uint8_t pipe = pipe_to_descendant(header.from_node);
akashvibhute 0:c3db0798d9aa 96 radio.openReadingPipe(pipe,pipe_address(node_address,pipe));
akashvibhute 0:c3db0798d9aa 97
akashvibhute 0:c3db0798d9aa 98 // Also need to open pipe 1 so the system can get the full 5-byte address of the pipe.
akashvibhute 0:c3db0798d9aa 99 radio.openReadingPipe(1,pipe_address(node_address,1));
akashvibhute 0:c3db0798d9aa 100 }
akashvibhute 0:c3db0798d9aa 101 #endif
akashvibhute 0:c3db0798d9aa 102 }
akashvibhute 0:c3db0798d9aa 103 }
akashvibhute 0:c3db0798d9aa 104 }
akashvibhute 0:c3db0798d9aa 105
akashvibhute 0:c3db0798d9aa 106 /******************************************************************/
akashvibhute 0:c3db0798d9aa 107
akashvibhute 0:c3db0798d9aa 108 bool RF24Network::enqueue(void)
akashvibhute 0:c3db0798d9aa 109 {
akashvibhute 0:c3db0798d9aa 110 bool result = false;
akashvibhute 0:c3db0798d9aa 111
akashvibhute 0:c3db0798d9aa 112 //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Enqueue @%x "),millis(),next_frame-frame_queue));
akashvibhute 0:c3db0798d9aa 113
akashvibhute 0:c3db0798d9aa 114 // Copy the current frame into the frame queue
akashvibhute 0:c3db0798d9aa 115 if ( next_frame < frame_queue + sizeof(frame_queue) )
akashvibhute 0:c3db0798d9aa 116 {
akashvibhute 0:c3db0798d9aa 117 memcpy(next_frame,frame_buffer, frame_size );
akashvibhute 0:c3db0798d9aa 118 next_frame += frame_size;
akashvibhute 0:c3db0798d9aa 119
akashvibhute 0:c3db0798d9aa 120 result = true;
akashvibhute 0:c3db0798d9aa 121 //IF_SERIAL_DEBUG(printf_P(PSTR("ok\n\r")));
akashvibhute 0:c3db0798d9aa 122 }
akashvibhute 0:c3db0798d9aa 123 else
akashvibhute 0:c3db0798d9aa 124 {
akashvibhute 0:c3db0798d9aa 125 //IF_SERIAL_DEBUG(printf_P(PSTR("failed\n\r")));
akashvibhute 0:c3db0798d9aa 126 }
akashvibhute 0:c3db0798d9aa 127
akashvibhute 0:c3db0798d9aa 128 return result;
akashvibhute 0:c3db0798d9aa 129 }
akashvibhute 0:c3db0798d9aa 130
akashvibhute 0:c3db0798d9aa 131 /******************************************************************/
akashvibhute 0:c3db0798d9aa 132
akashvibhute 0:c3db0798d9aa 133 bool RF24Network::available(void)
akashvibhute 0:c3db0798d9aa 134 {
akashvibhute 0:c3db0798d9aa 135 // Are there frames on the queue for us?
akashvibhute 0:c3db0798d9aa 136 return (next_frame > frame_queue);
akashvibhute 0:c3db0798d9aa 137 }
akashvibhute 0:c3db0798d9aa 138
akashvibhute 0:c3db0798d9aa 139 /******************************************************************/
akashvibhute 0:c3db0798d9aa 140
akashvibhute 0:c3db0798d9aa 141 void RF24Network::peek(RF24NetworkHeader& header)
akashvibhute 0:c3db0798d9aa 142 {
akashvibhute 0:c3db0798d9aa 143 if ( available() )
akashvibhute 0:c3db0798d9aa 144 {
akashvibhute 0:c3db0798d9aa 145 // Copy the next available frame from the queue into the provided buffer
akashvibhute 0:c3db0798d9aa 146 memcpy(&header,next_frame-frame_size,sizeof(RF24NetworkHeader));
akashvibhute 0:c3db0798d9aa 147 }
akashvibhute 0:c3db0798d9aa 148 }
akashvibhute 0:c3db0798d9aa 149
akashvibhute 0:c3db0798d9aa 150 /******************************************************************/
akashvibhute 0:c3db0798d9aa 151
akashvibhute 0:c3db0798d9aa 152 size_t RF24Network::read(RF24NetworkHeader& header,void* message, size_t maxlen)
akashvibhute 0:c3db0798d9aa 153 {
akashvibhute 0:c3db0798d9aa 154 size_t bufsize = 0;
akashvibhute 0:c3db0798d9aa 155
akashvibhute 0:c3db0798d9aa 156 if ( available() )
akashvibhute 0:c3db0798d9aa 157 {
akashvibhute 0:c3db0798d9aa 158 // Move the pointer back one in the queue
akashvibhute 0:c3db0798d9aa 159 next_frame -= frame_size;
akashvibhute 0:c3db0798d9aa 160 uint8_t* frame = next_frame;
akashvibhute 0:c3db0798d9aa 161
akashvibhute 0:c3db0798d9aa 162 // How much buffer size should we actually copy?
akashvibhute 0:c3db0798d9aa 163 bufsize = min(maxlen,frame_size-sizeof(RF24NetworkHeader));
akashvibhute 0:c3db0798d9aa 164
akashvibhute 0:c3db0798d9aa 165 // Copy the next available frame from the queue into the provided buffer
akashvibhute 0:c3db0798d9aa 166 memcpy(&header,frame,sizeof(RF24NetworkHeader));
akashvibhute 0:c3db0798d9aa 167 memcpy(message,frame+sizeof(RF24NetworkHeader),bufsize);
akashvibhute 0:c3db0798d9aa 168
akashvibhute 0:c3db0798d9aa 169 //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Received %s\n\r"),millis(),header.toString()));
akashvibhute 0:c3db0798d9aa 170 }
akashvibhute 0:c3db0798d9aa 171
akashvibhute 0:c3db0798d9aa 172 return bufsize;
akashvibhute 0:c3db0798d9aa 173 }
akashvibhute 0:c3db0798d9aa 174
akashvibhute 0:c3db0798d9aa 175 /******************************************************************/
akashvibhute 0:c3db0798d9aa 176
akashvibhute 0:c3db0798d9aa 177 bool RF24Network::write(RF24NetworkHeader& header,const void* message, size_t len)
akashvibhute 0:c3db0798d9aa 178 {
akashvibhute 0:c3db0798d9aa 179 // Fill out the header
akashvibhute 0:c3db0798d9aa 180 header.from_node = node_address;
akashvibhute 0:c3db0798d9aa 181
akashvibhute 0:c3db0798d9aa 182 // Build the full frame to send
akashvibhute 0:c3db0798d9aa 183 memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader));
akashvibhute 0:c3db0798d9aa 184 if (len)
akashvibhute 0:c3db0798d9aa 185 memcpy(frame_buffer + sizeof(RF24NetworkHeader),message,min(frame_size-sizeof(RF24NetworkHeader),len));
akashvibhute 0:c3db0798d9aa 186
akashvibhute 0:c3db0798d9aa 187 //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Sending %s\n\r"),millis(),header.toString()));
akashvibhute 0:c3db0798d9aa 188 if (len)
akashvibhute 0:c3db0798d9aa 189 {
akashvibhute 0:c3db0798d9aa 190 //IF_SERIAL_DEBUG(const uint16_t* i = reinterpret_cast<const uint16_t*>(message);printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i));
akashvibhute 0:c3db0798d9aa 191 }
akashvibhute 0:c3db0798d9aa 192
akashvibhute 0:c3db0798d9aa 193 // If the user is trying to send it to himself
akashvibhute 0:c3db0798d9aa 194 if ( header.to_node == node_address )
akashvibhute 0:c3db0798d9aa 195 // Just queue it in the received queue
akashvibhute 0:c3db0798d9aa 196 return enqueue();
akashvibhute 0:c3db0798d9aa 197 else
akashvibhute 0:c3db0798d9aa 198 // Otherwise send it out over the air
akashvibhute 0:c3db0798d9aa 199 return write(header.to_node);
akashvibhute 0:c3db0798d9aa 200 }
akashvibhute 0:c3db0798d9aa 201
akashvibhute 0:c3db0798d9aa 202 /******************************************************************/
akashvibhute 0:c3db0798d9aa 203
akashvibhute 0:c3db0798d9aa 204 bool RF24Network::write(uint16_t to_node)
akashvibhute 0:c3db0798d9aa 205 {
akashvibhute 0:c3db0798d9aa 206 bool ok = false;
akashvibhute 0:c3db0798d9aa 207
akashvibhute 0:c3db0798d9aa 208 // Throw it away if it's not a valid address
akashvibhute 0:c3db0798d9aa 209 if ( !is_valid_address(to_node) )
akashvibhute 0:c3db0798d9aa 210 return false;
akashvibhute 0:c3db0798d9aa 211
akashvibhute 0:c3db0798d9aa 212 // First, stop listening so we can talk.
akashvibhute 0:c3db0798d9aa 213 //radio.stopListening();
akashvibhute 0:c3db0798d9aa 214
akashvibhute 0:c3db0798d9aa 215 // Where do we send this? By default, to our parent
akashvibhute 0:c3db0798d9aa 216 uint16_t send_node = parent_node;
akashvibhute 0:c3db0798d9aa 217 // On which pipe
akashvibhute 0:c3db0798d9aa 218 uint8_t send_pipe = parent_pipe;
akashvibhute 0:c3db0798d9aa 219
akashvibhute 0:c3db0798d9aa 220 // If the node is a direct child,
akashvibhute 0:c3db0798d9aa 221 if ( is_direct_child(to_node) )
akashvibhute 0:c3db0798d9aa 222 {
akashvibhute 0:c3db0798d9aa 223 // Send directly
akashvibhute 0:c3db0798d9aa 224 send_node = to_node;
akashvibhute 0:c3db0798d9aa 225
akashvibhute 0:c3db0798d9aa 226 // To its listening pipe
akashvibhute 0:c3db0798d9aa 227 send_pipe = 0;
akashvibhute 0:c3db0798d9aa 228 }
akashvibhute 0:c3db0798d9aa 229 // If the node is a child of a child
akashvibhute 0:c3db0798d9aa 230 // talk on our child's listening pipe,
akashvibhute 0:c3db0798d9aa 231 // and let the direct child relay it.
akashvibhute 0:c3db0798d9aa 232 else if ( is_descendant(to_node) )
akashvibhute 0:c3db0798d9aa 233 {
akashvibhute 0:c3db0798d9aa 234 send_node = direct_child_route_to(to_node);
akashvibhute 0:c3db0798d9aa 235 send_pipe = 0;
akashvibhute 0:c3db0798d9aa 236 }
akashvibhute 0:c3db0798d9aa 237
akashvibhute 0:c3db0798d9aa 238 //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Sending to 0%o via 0%o on pipe %x\n\r"),millis(),to_node,send_node,send_pipe));
akashvibhute 0:c3db0798d9aa 239
akashvibhute 0:c3db0798d9aa 240 // First, stop listening so we can talk
akashvibhute 0:c3db0798d9aa 241 radio.stopListening();
akashvibhute 0:c3db0798d9aa 242
akashvibhute 0:c3db0798d9aa 243 // Put the frame on the pipe
akashvibhute 0:c3db0798d9aa 244 ok = write_to_pipe( send_node, send_pipe );
akashvibhute 0:c3db0798d9aa 245
akashvibhute 0:c3db0798d9aa 246 // NOT NEEDED anymore. Now all reading pipes are open to start.
akashvibhute 0:c3db0798d9aa 247 #if 0
akashvibhute 0:c3db0798d9aa 248 // If we are talking on our talking pipe, it's possible that no one is listening.
akashvibhute 0:c3db0798d9aa 249 // If this fails, try sending it on our parent's listening pipe. That will wake
akashvibhute 0:c3db0798d9aa 250 // it up, and next time it will listen to us.
akashvibhute 0:c3db0798d9aa 251
akashvibhute 0:c3db0798d9aa 252 if ( !ok && send_node == parent_node )
akashvibhute 0:c3db0798d9aa 253 ok = write_to_pipe( parent_node, 0 );
akashvibhute 0:c3db0798d9aa 254 #endif
akashvibhute 0:c3db0798d9aa 255
akashvibhute 0:c3db0798d9aa 256 // Now, continue listening
akashvibhute 0:c3db0798d9aa 257 radio.startListening();
akashvibhute 0:c3db0798d9aa 258
akashvibhute 0:c3db0798d9aa 259 return ok;
akashvibhute 0:c3db0798d9aa 260 }
akashvibhute 0:c3db0798d9aa 261
akashvibhute 0:c3db0798d9aa 262 /******************************************************************/
akashvibhute 0:c3db0798d9aa 263
akashvibhute 0:c3db0798d9aa 264 bool RF24Network::write_to_pipe( uint16_t node, uint8_t pipe )
akashvibhute 0:c3db0798d9aa 265 {
akashvibhute 0:c3db0798d9aa 266 bool ok = false;
akashvibhute 0:c3db0798d9aa 267
akashvibhute 0:c3db0798d9aa 268 uint64_t out_pipe = pipe_address( node, pipe );
akashvibhute 0:c3db0798d9aa 269
akashvibhute 0:c3db0798d9aa 270 // Open the correct pipe for writing.
akashvibhute 0:c3db0798d9aa 271 radio.openWritingPipe(out_pipe);
akashvibhute 0:c3db0798d9aa 272
akashvibhute 0:c3db0798d9aa 273 // Retry a few times
akashvibhute 0:c3db0798d9aa 274 short attempts = 5;
akashvibhute 0:c3db0798d9aa 275 do
akashvibhute 0:c3db0798d9aa 276 {
akashvibhute 0:c3db0798d9aa 277 ok = radio.write( frame_buffer, frame_size );
akashvibhute 0:c3db0798d9aa 278 }
akashvibhute 0:c3db0798d9aa 279 while ( !ok && --attempts );
akashvibhute 0:c3db0798d9aa 280
akashvibhute 0:c3db0798d9aa 281 //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Sent on %lx %S\n\r"),millis(),(uint32_t)out_pipe,ok?PSTR("ok"):PSTR("failed")));
akashvibhute 0:c3db0798d9aa 282
akashvibhute 0:c3db0798d9aa 283 return ok;
akashvibhute 0:c3db0798d9aa 284 }
akashvibhute 0:c3db0798d9aa 285
akashvibhute 0:c3db0798d9aa 286 /******************************************************************/
akashvibhute 0:c3db0798d9aa 287
akashvibhute 0:c3db0798d9aa 288 const char* RF24NetworkHeader::toString(void) const
akashvibhute 0:c3db0798d9aa 289 {
akashvibhute 0:c3db0798d9aa 290 static char buffer[45];
akashvibhute 0:c3db0798d9aa 291 //snprintf_P(buffer,sizeof(buffer),("id %04x from 0%o to 0%o type %c"),id,from_node,to_node,type);
akashvibhute 0:c3db0798d9aa 292 return buffer;
akashvibhute 0:c3db0798d9aa 293 }
akashvibhute 0:c3db0798d9aa 294
akashvibhute 0:c3db0798d9aa 295 /******************************************************************/
akashvibhute 0:c3db0798d9aa 296
akashvibhute 0:c3db0798d9aa 297 bool RF24Network::is_direct_child( uint16_t node )
akashvibhute 0:c3db0798d9aa 298 {
akashvibhute 0:c3db0798d9aa 299 bool result = false;
akashvibhute 0:c3db0798d9aa 300
akashvibhute 0:c3db0798d9aa 301 // A direct child of ours has the same low numbers as us, and only
akashvibhute 0:c3db0798d9aa 302 // one higher number.
akashvibhute 0:c3db0798d9aa 303 //
akashvibhute 0:c3db0798d9aa 304 // e.g. node 0234 is a direct child of 034, and node 01234 is a
akashvibhute 0:c3db0798d9aa 305 // descendant but not a direct child
akashvibhute 0:c3db0798d9aa 306
akashvibhute 0:c3db0798d9aa 307 // First, is it even a descendant?
akashvibhute 0:c3db0798d9aa 308 if ( is_descendant(node) )
akashvibhute 0:c3db0798d9aa 309 {
akashvibhute 0:c3db0798d9aa 310 // Does it only have ONE more level than us?
akashvibhute 0:c3db0798d9aa 311 uint16_t child_node_mask = ( ~ node_mask ) << 3;
akashvibhute 0:c3db0798d9aa 312 result = ( node & child_node_mask ) == 0 ;
akashvibhute 0:c3db0798d9aa 313 }
akashvibhute 0:c3db0798d9aa 314
akashvibhute 0:c3db0798d9aa 315 return result;
akashvibhute 0:c3db0798d9aa 316 }
akashvibhute 0:c3db0798d9aa 317
akashvibhute 0:c3db0798d9aa 318 /******************************************************************/
akashvibhute 0:c3db0798d9aa 319
akashvibhute 0:c3db0798d9aa 320 bool RF24Network::is_descendant( uint16_t node )
akashvibhute 0:c3db0798d9aa 321 {
akashvibhute 0:c3db0798d9aa 322 return ( node & node_mask ) == node_address;
akashvibhute 0:c3db0798d9aa 323 }
akashvibhute 0:c3db0798d9aa 324
akashvibhute 0:c3db0798d9aa 325 /******************************************************************/
akashvibhute 0:c3db0798d9aa 326
akashvibhute 0:c3db0798d9aa 327 void RF24Network::setup_address(void)
akashvibhute 0:c3db0798d9aa 328 {
akashvibhute 0:c3db0798d9aa 329 // First, establish the node_mask
akashvibhute 0:c3db0798d9aa 330 uint16_t node_mask_check = 0xFFFF;
akashvibhute 0:c3db0798d9aa 331 while ( node_address & node_mask_check )
akashvibhute 0:c3db0798d9aa 332 node_mask_check <<= 3;
akashvibhute 0:c3db0798d9aa 333
akashvibhute 0:c3db0798d9aa 334 node_mask = ~ node_mask_check;
akashvibhute 0:c3db0798d9aa 335
akashvibhute 0:c3db0798d9aa 336 // parent mask is the next level down
akashvibhute 0:c3db0798d9aa 337 uint16_t parent_mask = node_mask >> 3;
akashvibhute 0:c3db0798d9aa 338
akashvibhute 0:c3db0798d9aa 339 // parent node is the part IN the mask
akashvibhute 0:c3db0798d9aa 340 parent_node = node_address & parent_mask;
akashvibhute 0:c3db0798d9aa 341
akashvibhute 0:c3db0798d9aa 342 // parent pipe is the part OUT of the mask
akashvibhute 0:c3db0798d9aa 343 uint16_t i = node_address;
akashvibhute 0:c3db0798d9aa 344 uint16_t m = parent_mask;
akashvibhute 0:c3db0798d9aa 345 while (m)
akashvibhute 0:c3db0798d9aa 346 {
akashvibhute 0:c3db0798d9aa 347 i >>= 3;
akashvibhute 0:c3db0798d9aa 348 m >>= 3;
akashvibhute 0:c3db0798d9aa 349 }
akashvibhute 0:c3db0798d9aa 350 parent_pipe = i;
akashvibhute 0:c3db0798d9aa 351
akashvibhute 0:c3db0798d9aa 352 #ifdef SERIAL_DEBUG
akashvibhute 0:c3db0798d9aa 353 printf_P(PSTR("setup_address node=0%o mask=0%o parent=0%o pipe=0%o\n\r"),node_address,node_mask,parent_node,parent_pipe);
akashvibhute 0:c3db0798d9aa 354 #endif
akashvibhute 0:c3db0798d9aa 355 }
akashvibhute 0:c3db0798d9aa 356
akashvibhute 0:c3db0798d9aa 357 /******************************************************************/
akashvibhute 0:c3db0798d9aa 358
akashvibhute 0:c3db0798d9aa 359 uint16_t RF24Network::direct_child_route_to( uint16_t node )
akashvibhute 0:c3db0798d9aa 360 {
akashvibhute 0:c3db0798d9aa 361 // Presumes that this is in fact a child!!
akashvibhute 0:c3db0798d9aa 362
akashvibhute 0:c3db0798d9aa 363 uint16_t child_mask = ( node_mask << 3 ) | 7;
akashvibhute 0:c3db0798d9aa 364 return node & child_mask ;
akashvibhute 0:c3db0798d9aa 365 }
akashvibhute 0:c3db0798d9aa 366
akashvibhute 0:c3db0798d9aa 367 /******************************************************************/
akashvibhute 0:c3db0798d9aa 368
akashvibhute 0:c3db0798d9aa 369 uint8_t RF24Network::pipe_to_descendant( uint16_t node )
akashvibhute 0:c3db0798d9aa 370 {
akashvibhute 0:c3db0798d9aa 371 uint16_t i = node;
akashvibhute 0:c3db0798d9aa 372 uint16_t m = node_mask;
akashvibhute 0:c3db0798d9aa 373
akashvibhute 0:c3db0798d9aa 374 while (m)
akashvibhute 0:c3db0798d9aa 375 {
akashvibhute 0:c3db0798d9aa 376 i >>= 3;
akashvibhute 0:c3db0798d9aa 377 m >>= 3;
akashvibhute 0:c3db0798d9aa 378 }
akashvibhute 0:c3db0798d9aa 379
akashvibhute 0:c3db0798d9aa 380 return i & 7;
akashvibhute 0:c3db0798d9aa 381 }
akashvibhute 0:c3db0798d9aa 382
akashvibhute 0:c3db0798d9aa 383 /******************************************************************/
akashvibhute 0:c3db0798d9aa 384
akashvibhute 0:c3db0798d9aa 385 bool is_valid_address( uint16_t node )
akashvibhute 0:c3db0798d9aa 386 {
akashvibhute 0:c3db0798d9aa 387 bool result = true;
akashvibhute 0:c3db0798d9aa 388
akashvibhute 0:c3db0798d9aa 389 while(node)
akashvibhute 0:c3db0798d9aa 390 {
akashvibhute 0:c3db0798d9aa 391 uint8_t digit = node & 7;
akashvibhute 0:c3db0798d9aa 392 if (digit < 1 || digit > 5)
akashvibhute 0:c3db0798d9aa 393 {
akashvibhute 0:c3db0798d9aa 394 result = false;
akashvibhute 0:c3db0798d9aa 395 //printf_P(("*** WARNING *** Invalid address 0%o\n\r"),node);
akashvibhute 0:c3db0798d9aa 396 break;
akashvibhute 0:c3db0798d9aa 397 }
akashvibhute 0:c3db0798d9aa 398 node >>= 3;
akashvibhute 0:c3db0798d9aa 399 }
akashvibhute 0:c3db0798d9aa 400
akashvibhute 0:c3db0798d9aa 401 return result;
akashvibhute 0:c3db0798d9aa 402 }
akashvibhute 0:c3db0798d9aa 403
akashvibhute 0:c3db0798d9aa 404 /******************************************************************/
akashvibhute 0:c3db0798d9aa 405
akashvibhute 0:c3db0798d9aa 406 uint64_t pipe_address( uint16_t node, uint8_t pipe )
akashvibhute 0:c3db0798d9aa 407 {
akashvibhute 0:c3db0798d9aa 408 static uint8_t pipe_segment[] = { 0x3c, 0x5a, 0x69, 0x96, 0xa5, 0xc3 };
akashvibhute 0:c3db0798d9aa 409
akashvibhute 0:c3db0798d9aa 410 uint64_t result;
akashvibhute 0:c3db0798d9aa 411 uint8_t* out = reinterpret_cast<uint8_t*>(&result);
akashvibhute 0:c3db0798d9aa 412
akashvibhute 0:c3db0798d9aa 413 out[0] = pipe_segment[pipe];
akashvibhute 0:c3db0798d9aa 414
akashvibhute 0:c3db0798d9aa 415 uint8_t w;
akashvibhute 0:c3db0798d9aa 416 short i = 4;
akashvibhute 0:c3db0798d9aa 417 short shift = 12;
akashvibhute 0:c3db0798d9aa 418 while(i--)
akashvibhute 0:c3db0798d9aa 419 {
akashvibhute 0:c3db0798d9aa 420 w = ( node >> shift ) & 0xF ;
akashvibhute 0:c3db0798d9aa 421 w |= ~w << 4;
akashvibhute 0:c3db0798d9aa 422 out[i+1] = w;
akashvibhute 0:c3db0798d9aa 423
akashvibhute 0:c3db0798d9aa 424 shift -= 4;
akashvibhute 0:c3db0798d9aa 425 }
akashvibhute 0:c3db0798d9aa 426
akashvibhute 0:c3db0798d9aa 427 //IF_SERIAL_DEBUG(uint32_t* top = reinterpret_cast<uint32_t*>(out+1);printf_P(PSTR("%lu: NET Pipe %i on node 0%o has address %lx%x\n\r"),millis(),pipe,node,*top,*out));
akashvibhute 0:c3db0798d9aa 428
akashvibhute 0:c3db0798d9aa 429 return result;
akashvibhute 0:c3db0798d9aa 430 }
akashvibhute 0:c3db0798d9aa 431
akashvibhute 0:c3db0798d9aa 432 // vim:ai:cin:sts=2 sw=2 ft=cpp
akashvibhute 0:c3db0798d9aa 433
akashvibhute 0:c3db0798d9aa 434 uint8_t RF24Network::min(uint8_t a, uint8_t b)
akashvibhute 0:c3db0798d9aa 435 {
akashvibhute 0:c3db0798d9aa 436 if(a < b)
akashvibhute 0:c3db0798d9aa 437 return a;
akashvibhute 0:c3db0798d9aa 438 else
akashvibhute 0:c3db0798d9aa 439 return b;
akashvibhute 0:c3db0798d9aa 440 }