Kristof T'Jonck / Mbed 2 deprecated CYS_Receiver

Dependencies:   xtoff2 RF24Network mbed

Fork of xtoff3 by pieter Berteloot

Committer:
akashvibhute
Date:
Mon Jul 06 03:17:33 2015 +0000
Revision:
0:3982c0e9eda1
First mbed-arduino working program!; mbed is able to receive data from arduino nodes 0 or 1 depending on address set

Who changed what in which revision?

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