Maniacbug's RF24 arduino library ported to mbed. Tested, it works for Nucleo F411

Dependents:   RF24Network_Send RF24Network_Receive maple_chotobot_rf_motores Thesis_Verzender ... more

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