FinT

Dependencies:   mbed RF24Network RF24

Files at this revision

API Documentation at this revision

Comitter:
akashvibhute
Date:
Mon Jul 06 05:23:41 2015 +0000
Parent:
1:5be48a9550c3
Child:
3:e9c4d66da50c
Commit message:
Example RF24Network receive program. Tested on Nucleo 411

Changed in this revision

RF24.lib Show annotated file Show diff for this revision Revisions of this file
RF24Network.lib Show annotated file Show diff for this revision Revisions of this file
RF24Network/RF24Network.cpp Show diff for this revision Revisions of this file
RF24Network/RF24Network.h Show diff for this revision Revisions of this file
RF24Network/RF24Network_config.h Show diff for this revision Revisions of this file
RF24Network/Sync.cpp Show diff for this revision Revisions of this file
RF24Network/Sync.h Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show diff for this revision Revisions of this file
nRF24L01P_Maniacbug/nRF24L01P_Maniacbug.cpp Show diff for this revision Revisions of this file
nRF24L01P_Maniacbug/nRF24L01P_Maniacbug.h Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RF24.lib	Mon Jul 06 05:23:41 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/akashvibhute/code/RF24/#00706a42491e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RF24Network.lib	Mon Jul 06 05:23:41 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/akashvibhute/code/RF24Network/#caf146ffe8b0
--- a/RF24Network/RF24Network.cpp	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,439 +0,0 @@
-/*
- Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-#include "RF24Network_config.h"
-#include <nRF24L01P_Maniacbug.h>
-#include "RF24Network.h"
-
-uint16_t RF24NetworkHeader::next_id = 1;
-
-uint64_t pipe_address( uint16_t node, uint8_t pipe );
-bool is_valid_address( uint16_t node );
-
-/******************************************************************/
-
-RF24Network::RF24Network( RF24& _radio ): radio(_radio), next_frame(frame_queue)
-{
-}
-
-/******************************************************************/
-
-void RF24Network::begin(uint8_t _channel, uint16_t _node_address )
-{
-  if (! is_valid_address(_node_address) )
-    return;
-
-  node_address = _node_address;
-
-  // Set up the radio the way we want it to look
-  radio.setChannel(_channel);
-  radio.setDataRate(RF24_1MBPS);
-  radio.setCRCLength(RF24_CRC_16);
-    
-    radio.setAutoAck(1); /*****/
-    
-  // Setup our address helper cache
-  setup_address();
-  
-  // Open up all listening pipes
-  int i = 6;
-  while (i--)
-    radio.openReadingPipe(i,pipe_address(_node_address,i));
-  radio.startListening();
-
-  // Spew debugging state about the radio
-  radio.printDetails();
-}
-
-/******************************************************************/
-
-void RF24Network::update(void)
-{
-  // if there is data ready
-  uint8_t pipe_num;
-  while ( radio.available(&pipe_num) )
-  {
-    // Dump the payloads until we've gotten everything
-    bool done = false;
-    while (!done)
-    {
-      // Fetch the payload, and see if this was the last one.
-      done = radio.read( frame_buffer, sizeof(frame_buffer) );
-
-      // Read the beginning of the frame as the header
-      const RF24NetworkHeader& header = * reinterpret_cast<RF24NetworkHeader*>(frame_buffer);
-
-      //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Received on %u %s\n\r"),millis(),pipe_num,header.toString()));
-      //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));
-
-      // Throw it away if it's not a valid address
-      if ( !is_valid_address(header.to_node) )
-    continue;
-
-      // Is this for us?
-      if ( header.to_node == node_address )
-    // Add it to the buffer of frames for us
-    enqueue();
-      else
-    // Relay it
-    write(header.to_node);
-
-      // NOT NEEDED anymore.  Now all reading pipes are open to start.
-#if 0
-      // If this was for us, from one of our children, but on our listening
-      // pipe, it could mean that we are not listening to them.  If so, open up
-      // and listen to their talking pipe
-
-      if ( header.to_node == node_address && pipe_num == 0 && is_descendant(header.from_node) )
-      {
-    uint8_t pipe = pipe_to_descendant(header.from_node);
-    radio.openReadingPipe(pipe,pipe_address(node_address,pipe));
-
-    // Also need to open pipe 1 so the system can get the full 5-byte address of the pipe.
-    radio.openReadingPipe(1,pipe_address(node_address,1));
-      }
-#endif
-    }
-  }
-}
-
-/******************************************************************/
-
-bool RF24Network::enqueue(void)
-{
-  bool result = false;
-  
-  //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Enqueue @%x "),millis(),next_frame-frame_queue));
-
-  // Copy the current frame into the frame queue
-  if ( next_frame < frame_queue + sizeof(frame_queue) )
-  {
-    memcpy(next_frame,frame_buffer, frame_size );
-    next_frame += frame_size; 
-
-    result = true;
-    //IF_SERIAL_DEBUG(printf_P(PSTR("ok\n\r")));
-  }
-  else
-  {
-    //IF_SERIAL_DEBUG(printf_P(PSTR("failed\n\r")));
-  }
-
-  return result;
-}
-
-/******************************************************************/
-
-bool RF24Network::available(void)
-{
-  // Are there frames on the queue for us?
-  return (next_frame > frame_queue);
-}
-
-/******************************************************************/
-
-void RF24Network::peek(RF24NetworkHeader& header)
-{
-  if ( available() )
-  {
-    // Copy the next available frame from the queue into the provided buffer
-    memcpy(&header,next_frame-frame_size,sizeof(RF24NetworkHeader));
-  }
-}
-
-/******************************************************************/
-
-size_t RF24Network::read(RF24NetworkHeader& header,void* message, size_t maxlen)
-{
-  size_t bufsize = 0;
-
-  if ( available() )
-  {
-    // Move the pointer back one in the queue 
-    next_frame -= frame_size;
-    uint8_t* frame = next_frame;
-      
-    // How much buffer size should we actually copy?
-    bufsize = min(maxlen,frame_size-sizeof(RF24NetworkHeader));
-
-    // Copy the next available frame from the queue into the provided buffer
-    memcpy(&header,frame,sizeof(RF24NetworkHeader));
-    memcpy(message,frame+sizeof(RF24NetworkHeader),bufsize);
-    
-    //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Received %s\n\r"),millis(),header.toString()));
-  }
-
-  return bufsize;
-}
-
-/******************************************************************/
-
-bool RF24Network::write(RF24NetworkHeader& header,const void* message, size_t len)
-{
-  // Fill out the header
-  header.from_node = node_address;
-
-  // Build the full frame to send
-  memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader));
-  if (len)
-    memcpy(frame_buffer + sizeof(RF24NetworkHeader),message,min(frame_size-sizeof(RF24NetworkHeader),len));
-
-  //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Sending %s\n\r"),millis(),header.toString()));
-  if (len)
-  {
-    //IF_SERIAL_DEBUG(const uint16_t* i = reinterpret_cast<const uint16_t*>(message);printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i));
-  }
-
-  // If the user is trying to send it to himself
-  if ( header.to_node == node_address )
-    // Just queue it in the received queue
-    return enqueue();
-  else
-    // Otherwise send it out over the air
-    return write(header.to_node);
-}
-
-/******************************************************************/
-
-bool RF24Network::write(uint16_t to_node)
-{
-  bool ok = false;
-  
-  // Throw it away if it's not a valid address
-  if ( !is_valid_address(to_node) )
-    return false;
-
-  // First, stop listening so we can talk.
-  //radio.stopListening();
-
-  // Where do we send this?  By default, to our parent
-  uint16_t send_node = parent_node;
-  // On which pipe
-  uint8_t send_pipe = parent_pipe;
-  
-  // If the node is a direct child,
-  if ( is_direct_child(to_node) )
-  {
-    // Send directly
-    send_node = to_node;
-
-    // To its listening pipe
-    send_pipe = 0;
-  }
-  // If the node is a child of a child
-  // talk on our child's listening pipe,
-  // and let the direct child relay it.
-  else if ( is_descendant(to_node) )
-  {
-    send_node = direct_child_route_to(to_node);
-    send_pipe = 0;
-  }
-  
-  //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));
-
-  // First, stop listening so we can talk
-  radio.stopListening();
-
-  // Put the frame on the pipe
-  ok = write_to_pipe( send_node, send_pipe );
-
-      // NOT NEEDED anymore.  Now all reading pipes are open to start.
-#if 0
-  // If we are talking on our talking pipe, it's possible that no one is listening.
-  // If this fails, try sending it on our parent's listening pipe.  That will wake
-  // it up, and next time it will listen to us.
-
-  if ( !ok && send_node == parent_node )
-    ok = write_to_pipe( parent_node, 0 );
-#endif
-
-  // Now, continue listening
-  radio.startListening();
-
-  return ok;
-}
-
-/******************************************************************/
-
-bool RF24Network::write_to_pipe( uint16_t node, uint8_t pipe )
-{
-  bool ok = false;
-  
-  uint64_t out_pipe = pipe_address( node, pipe );
- 
-  // Open the correct pipe for writing.  
-  radio.openWritingPipe(out_pipe);
-
-  // Retry a few times
-  short attempts = 5;
-  do
-  {
-    ok = radio.write( frame_buffer, frame_size );
-  }
-  while ( !ok && --attempts );
-
-  //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Sent on %lx %S\n\r"),millis(),(uint32_t)out_pipe,ok?PSTR("ok"):PSTR("failed")));
-
-  return ok;
-}
-
-/******************************************************************/
-
-const char* RF24NetworkHeader::toString(void) const
-{
-  static char buffer[45];
-  //snprintf_P(buffer,sizeof(buffer),("id %04x from 0%o to 0%o type %c"),id,from_node,to_node,type);
-  return buffer;
-}
-
-/******************************************************************/
-
-bool RF24Network::is_direct_child( uint16_t node )
-{
-  bool result = false;
-
-  // A direct child of ours has the same low numbers as us, and only
-  // one higher number.
-  //
-  // e.g. node 0234 is a direct child of 034, and node 01234 is a
-  // descendant but not a direct child
-
-  // First, is it even a descendant?
-  if ( is_descendant(node) )
-  {
-    // Does it only have ONE more level than us?
-    uint16_t child_node_mask = ( ~ node_mask ) << 3;
-    result = ( node & child_node_mask ) == 0 ;
-  }
-
-  return result;
-}
-
-/******************************************************************/
-
-bool RF24Network::is_descendant( uint16_t node )
-{
-  return ( node & node_mask ) == node_address;
-}
-
-/******************************************************************/
-
-void RF24Network::setup_address(void)
-{
-  // First, establish the node_mask
-  uint16_t node_mask_check = 0xFFFF;
-  while ( node_address & node_mask_check )
-    node_mask_check <<= 3;
-  
-  node_mask = ~ node_mask_check;
-
-  // parent mask is the next level down
-  uint16_t parent_mask = node_mask >> 3;
-
-  // parent node is the part IN the mask
-  parent_node = node_address & parent_mask;
-
-  // parent pipe is the part OUT of the mask
-  uint16_t i = node_address;
-  uint16_t m = parent_mask;
-  while (m)
-  {
-    i >>= 3;
-    m >>= 3;
-  }
-  parent_pipe = i;
-
-#ifdef SERIAL_DEBUG
-  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);
-#endif
-}
-
-/******************************************************************/
-
-uint16_t RF24Network::direct_child_route_to( uint16_t node )
-{
-  // Presumes that this is in fact a child!!
-
-  uint16_t child_mask = ( node_mask << 3 ) | 7;
-  return node & child_mask ;
-}
-
-/******************************************************************/
-
-uint8_t RF24Network::pipe_to_descendant( uint16_t node )
-{
-  uint16_t i = node;
-  uint16_t m = node_mask;
-  
-  while (m)
-  {
-    i >>= 3;
-    m >>= 3;
-  }
-
-  return i & 7;
-}
-
-/******************************************************************/
-
-bool is_valid_address( uint16_t node )
-{
-  bool result = true;
-
-  while(node)
-  {
-    uint8_t digit = node & 7;
-    if (digit < 1 || digit > 5)
-    {
-      result = false;
-      //printf_P(("*** WARNING *** Invalid address 0%o\n\r"),node);
-      break;
-    }
-    node >>= 3;
-  }
-
-  return result;
-}
-
-/******************************************************************/
-
-uint64_t pipe_address( uint16_t node, uint8_t pipe )
-{
-  static uint8_t pipe_segment[] = { 0x3c, 0x5a, 0x69, 0x96, 0xa5, 0xc3 };
-
-  uint64_t result;
-  uint8_t* out = reinterpret_cast<uint8_t*>(&result);
-
-  out[0] = pipe_segment[pipe];
-
-  uint8_t w; 
-  short i = 4;
-  short shift = 12;
-  while(i--)
-  {
-    w = ( node >> shift ) & 0xF ; 
-    w |= ~w << 4;
-    out[i+1] = w;
-
-    shift -= 4;
-  }
-
-  //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));
-
-  return result;
-}
-
-// vim:ai:cin:sts=2 sw=2 ft=cpp
-
-uint8_t RF24Network::min(uint8_t a, uint8_t b)
-{
-    if(a < b)
-        return a;
-    else
-        return b;
-}
\ No newline at end of file
--- a/RF24Network/RF24Network.h	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-#ifndef __RF24NETWORK_H__
-#define __RF24NETWORK_H__
-
-/**
- * @file RF24Network.h
- *
- * Class declaration for RF24Network
- */
-
-#include <stddef.h>
-#include <stdint.h>
-
-class RF24;
-
-/**
- * Header which is sent with each message
- *
- * The frame put over the air consists of this header and a message
- */
-struct RF24NetworkHeader
-{
-  uint16_t from_node; /**< Logical address where the message was generated */
-  uint16_t to_node; /**< Logical address where the message is going */
-  uint16_t id; /**< Sequential message ID, incremented every message */
-  unsigned char type; /**< Type of the packet.  0-127 are user-defined types, 128-255 are reserved for system */
-  unsigned char reserved; /**< Reserved for future use */
-
-  static uint16_t next_id; /**< The message ID of the next message to be sent */
-
-  /**
-   * Default constructor
-   *
-   * Simply constructs a blank header
-   */
-  RF24NetworkHeader() {}
-
-  /**
-   * Send constructor
-   *
-   * Use this constructor to create a header and then send a message
-   *
-   * @code
-   *  RF24NetworkHeader header(recipient_address,'t');
-   *  network.write(header,&message,sizeof(message));
-   * @endcode
-   *
-   * @param _to The logical node address where the message is going
-   * @param _type The type of message which follows.  Only 0-127 are allowed for
-   * user messages.
-   */
-  RF24NetworkHeader(uint16_t _to, unsigned char _type = 0): to_node(_to), id(next_id++), type(_type&0x7f) {}
-
-  /**
-   * Create debugging string
-   *
-   * Useful for debugging.  Dumps all members into a single string, using
-   * internal static memory.  This memory will get overridden next time
-   * you call the method.
-   *
-   * @return String representation of this object
-   */
-  const char* toString(void) const;
-};
-
-/**
- * Network Layer for RF24 Radios
- *
- * This class implements an OSI Network Layer using nRF24L01(+) radios driven
- * by RF24 library.
- */
-
-class RF24Network
-{
-public:
-  /**
-   * Construct the network
-   *
-   * @param _radio The underlying radio driver instance
-   *
-   */
-  RF24Network( RF24& _radio );
-
-  /**
-   * Bring up the network
-   *
-   * @warning Be sure to 'begin' the radio first.
-   *
-   * @param _channel The RF channel to operate on
-   * @param _node_address The logical address of this node
-   */
-  void begin(uint8_t _channel, uint16_t _node_address );
-  
-  /**
-   * Main layer loop
-   *
-   * This function must be called regularly to keep the layer going.  This is where all
-   * the action happens!
-   */
-  void update(void);
-
-  /**
-   * Test whether there is a message available for this node
-   * 
-   * @return Whether there is a message available for this node
-   */
-  bool available(void);
- 
-  /**
-   * Read the next available header
-   *
-   * Reads the next available header without advancing to the next
-   * incoming message.  Useful for doing a switch on the message type
-   *
-   * If there is no message available, the header is not touched
-   *
-   * @param[out] header The header (envelope) of the next message
-   */
-  void peek(RF24NetworkHeader& header);
-
-  /**
-   * Read a message
-   *
-   * @param[out] header The header (envelope) of this message
-   * @param[out] message Pointer to memory where the message should be placed
-   * @param maxlen The largest message size which can be held in @p message
-   * @return The total number of bytes copied into @p message
-   */
-  size_t read(RF24NetworkHeader& header, void* message, size_t maxlen);
-  
-  /**
-   * Send a message
-   *
-   * @param[in,out] header The header (envelope) of this message.  The critical
-   * thing to fill in is the @p to_node field so we know where to send the
-   * message.  It is then updated with the details of the actual header sent.
-   * @param message Pointer to memory where the message is located 
-   * @param len The size of the message 
-   * @return Whether the message was successfully received 
-   */
-  bool write(RF24NetworkHeader& header,const void* message, size_t len);
-
-protected:
-  void open_pipes(void);
-  uint16_t find_node( uint16_t current_node, uint16_t target_node );
-  bool write(uint16_t);
-  bool write_to_pipe( uint16_t node, uint8_t pipe );
-  bool enqueue(void);
-
-  bool is_direct_child( uint16_t node );
-  bool is_descendant( uint16_t node );
-  uint16_t direct_child_route_to( uint16_t node );
-  uint8_t pipe_to_descendant( uint16_t node );
-  void setup_address(void);
-
-private:
-  RF24& radio; /**< Underlying radio driver, provides link/physical layers */ 
-  uint16_t node_address; /**< Logical node address of this unit, 1 .. UINT_MAX */
-  const static int frame_size = 32; /**< How large is each frame over the air */ 
-  uint8_t frame_buffer[frame_size]; /**< Space to put the frame that will be sent/received over the air */
-  uint8_t frame_queue[5*frame_size]; /**< Space for a small set of frames that need to be delivered to the app layer */
-  uint8_t* next_frame; /**< Pointer into the @p frame_queue where we should place the next received frame */
-
-  uint16_t parent_node; /**< Our parent's node address */
-  uint8_t parent_pipe; /**< The pipe our parent uses to listen to us */
-  uint16_t node_mask; /**< The bits which contain signfificant node address information */
-  uint8_t min(uint8_t, uint8_t);
-};
-
-/**
- * @example helloworld_tx.pde
- *
- * Simplest possible example of using RF24Network.  Put this sketch
- * on one node, and helloworld_rx.pde on the other.  Tx will send
- * Rx a nice message every 2 seconds which rx will print out for us.
- */
-
-/**
- * @example helloworld_rx.pde
- *
- * Simplest possible example of using RF24Network.  Put this sketch
- * on one node, and helloworld_tx.pde on the other.  Tx will send
- * Rx a nice message every 2 seconds which rx will print out for us.
- */
-
-/**
- * @example meshping.pde
- *
- * Example of pinging across a mesh network
- * Using this sketch, each node will send a ping to the base every
- * few seconds.  The RF24Network library will route the message across
- * the mesh to the correct node.
- */
-
-/**
- * @example sensornet.pde
- *
- * Example of a sensor network.
- * This sketch demonstrates how to use the RF24Network library to
- * manage a set of low-power sensor nodes which mostly sleep but
- * awake regularly to send readings to the base.
- */
-/**
- * @mainpage Network Layer for RF24 Radios
- *
- * This class implements an <a href="http://en.wikipedia.org/wiki/Network_layer">OSI Network Layer</a> using nRF24L01(+) radios driven
- * by the <a href="http://maniacbug.github.com/RF24/">RF24</a> library.
- *
- * @section Purpose Purpose/Goal
- *
- * Create an alternative to ZigBee radios for Arduino communication.
- *
- * Xbees are excellent little radios, backed up by a mature and robust standard 
- * protocol stack.  They are also expensive.
- *
- * For many Arduino uses, they seem like overkill.  So I am working to build
- * an alternative using nRF24L01 radios.  Modules are available for less than 
- * $6 from many sources.  With the RF24Network layer, I hope to cover many
- * common communication scenarios.
- *
- * Please see the @ref Zigbee page for a comparison against the ZigBee protocols
- *
- * @section Features Features
- *
- * The layer provides:
- * @li Host Addressing.  Each node has a logical address on the local network.
- * @li Message Forwarding.  Messages can be sent from one node to any other, and
- * this layer will get them there no matter how many hops it takes.
- * @li Ad-hoc Joining.  A node can join a network without any changes to any
- * existing nodes.
- *
- * The layer does not (yet) provide:
- * @li Fragmentation/reassembly.  Ability to send longer messages and put them
- * all back together before exposing them up to the app.
- * @li Power-efficient listening.  It would be useful for nodes who are listening
- * to sleep for extended periods of time if they could know that they would miss
- * no traffic.
- * @li Dynamic address assignment.
- *
- * @section More How to learn more
- *
- * @li <a href="http://maniacbug.github.com/RF24/">RF24: Underlying radio driver</a>
- * @li <a href="classRF24Network.html">RF24Network Class Documentation</a>
- * @li <a href="https://github.com/maniacbug/RF24Network/">Source Code</a>
- * @li <a href="https://github.com/maniacbug/RF24Network/archives/master">Downloads Page</a>
- * @li <a href="examples.html">Examples Page</a>.  Start with <a href="helloworld_rx_8pde-example.html">helloworld_rx</a> and <a href="helloworld_tx_8pde-example.html">helloworld_tx</a>.
- *
- * @section Topology Topology for Mesh Networks using nRF24L01(+)
- *
- * This network layer takes advantage of the fundamental capability of the nRF24L01(+) radio to
- * listen actively to up to 6 other radios at once.  The network is arranged in a 
- * <a href="http://en.wikipedia.org/wiki/Network_Topology#Tree">Tree Topology</a>, where
- * one node is the base, and all other nodes are children either of that node, or of another.
- * Unlike a true mesh network, multiple nodes are not connected together, so there is only one
- * path to any given node.
- *
- * @section Octal Octal Addressing
- *
- * Each node must be assigned an 15-bit address by the administrator.  This address exactly
- * describes the position of the node within the tree.  The address is an octal number.  Each
- * digit in the address represents a position in the tree further from the base.
- *
- * @li Node 00 is the base node.
- * @li Nodes 01-05 are nodes whose parent is the base.
- * @li Node 021 is the second child of node 01.
- * @li Node 0321 is the third child of node 021, an so on.
- * @li The largest node address is 05555, so 3,125 nodes are allowed on a single channel.
- *
- * @section Routing How routing is handled
- *
- * When sending a message using RF24Network::write(), you fill in the header with the logical
- * node address.  The network layer figures out the right path to find that node, and sends
- * it through the system until it gets to the right place.  This works even if the two nodes
- * are far separated, as it will send the message down to the base node, and then back out
- * to the final destination.
- *
- * All of this work is handled by the RF24Network::update() method, so be sure to call it
- * regularly or your network will miss packets.
- *
- * @section Startup Starting up a node
- *
- * When a node starts up, it only has to contact its parent to establish communication.
- * No direct connection to the Base node is needed.  This is useful in situations where
- * relay nodes are being used to bridge the distance to the base, so leaf nodes are out
- * of range of the base.
- *
- * @section Directionality Directionality 
- *
- * By default all nodes are always listening, so messages will quickly reach
- * their destination.  
- * 
- * You may choose to sleep any nodes which do not have any active children on the network
- * (i.e. leaf nodes).  This is useful in a case where
- * the leaf nodes are operating on batteries and need to sleep.
- * This is useful for a sensor network.  The leaf nodes can sleep most of the time, and wake
- * every few minutes to send in a reading.  However, messages cannot be sent to these 
- * sleeping nodes.
- *
- * In the future, I plan to write a system where messages can still be passed upward from
- * the base, and get delivered when a sleeping node is ready to receive them.  The radio
- * and underlying driver support 'ack payloads', which will be a handy mechanism for this.
- *
- * @page Zigbee Comparison to ZigBee
- *
- * This network layer is influenced by the design of ZigBee, but does not implement it
- * directly.  
- *
- * @section Advantage Which is better?
- *
- * ZigBee is a much more robust, feature-rich set of protocols, with many different vendors
- * providing compatible chips.
- *
- * RF24Network is cheap.  While ZigBee radios are well over $20, nRF24L01 modules can be found
- * for under $6.  My personal favorite is 
- * <a href="http://www.mdfly.com/index.php?main_page=product_info&products_id=82">MDFly RF-IS2401</a>.
- *
- * @section Contrast Similiarities & Differences
- *
- * Here are some comparisons between RF24Network and ZigBee.
- *
- * @li Both networks support Star and Tree topologies.  Only Zigbee supports a true mesh.
- * @li In both networks, only leaf nodes can sleep (see @ref NodeNames).
- * @li ZigBee nodes are configured using AT commands, or a separate Windows application. 
- * RF24 nodes are configured by recompiliing the firmware or writing to EEPROM.
- *
- * @section NodeNames Node Naming
- *
- * @li Leaf node: A node at the outer edge of the network with no children.  ZigBee calls it
- * an End Device node.
- * @li Relay node: A node which has both parents and children, and relays messages from one
- * to the other.  ZigBee calls it a Router.
- * @li Base node.  The top of the tree node with no parents, only children.  Typically this node
- * will bridge to another kind of network like Ethernet.  ZigBee calls it a Co-ordinator node.
- */
-
-#endif // __RF24NETWORK_H__
-// vim:ai:cin:sts=2 sw=2 ft=cpp
--- a/RF24Network/RF24Network_config.h	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-
-/*
- Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-#ifndef __RF24_CONFIG_H__
-#define __RF24_CONFIG_H__
-
-#include "mbed.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#define _BV(x) (1<<(x))
-
-
-#endif // __RF24_CONFIG_H__
-// vim:ai:cin:sts=2 sw=2 ft=cpp
--- a/RF24Network/Sync.cpp	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-// STL headers
-// C headers
-#include <stdlib.h>
-// Framework headers
-// Library headers
-#include <RF24Network.h>
-// Project headers
-// This component's header
-#include <Sync.h>
-
-/****************************************************************************/
-
-void Sync::update(void)
-{
-  // Pump the network
-  network.update();
-
-  // Look for changes to the data
-  uint8_t message[32];
-  uint8_t *mptr = message;
-  unsigned at = 0;
-  while ( at < len )
-  {
-    if ( app_data && internal_data && app_data[at] != internal_data[at] )
-    {
-      // Compose a message with the deltas
-      *mptr++ = at + 1;
-      *mptr++ = app_data[at];
-
-      // Update our internal view
-      internal_data[at] = app_data[at];
-    }
-    ++at;
-  }
-  // Zero out the remainder
-  while ( at++ < sizeof(message) )
-    *mptr++ = 0;
-
-  // If changes, send a message
-  if ( *message )
-  {
-    // TODO handle the case where this has to be broken into
-    // multiple messages
-    RF24NetworkHeader header(/*to node*/ to_node, /*type*/ 'S' /*Sync*/);
-    network.write(header,message,sizeof(message));
-  }
-
-  // Look for messages from the network
-  // Is there anything ready for us?
-  if ( network.available() )
-  {
-    // If so, take a look at it
-    RF24NetworkHeader header;
-    network.peek(header);
-
-    switch (header.type)
-    {
-    case 'S':
-      //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: SYN Received sync message\n\r"),millis()));
-
-      network.read(header,&message,sizeof(message));
-      // Parse the message and update the vars
-      mptr = message;
-      at = 0;
-      while ( mptr < message + sizeof(message) )
-      {
-        // A '0' in the first position means we are done
-        if ( !*mptr )
-          break;
-        uint8_t pos = (*mptr++) - 1;
-        uint8_t val = *mptr++;
-
-        //IF_SERIAL_DEBUG(printf_P(PSTR("%lu: SYN Updated position %u to value %u\n\r"),millis(),pos,val));
-
-        app_data[pos] = val;
-        internal_data[pos] = val;
-      }
-      break;
-    default:
-      // Leave other messages for the app
-      break;
-    };
-  }
-}
-// vim:cin:ai:sts=2 sw=2 ft=cpp
--- a/RF24Network/Sync.h	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-#ifndef __SYNC_H__
-#define __SYNC_H__
-
-// STL headers
-// C headers
-#include <stdlib.h>
-#include <string.h>
-// Framework headers
-// Library headers
-#include <RF24Network_config.h>
-// Project headers
-
-class RF24Network;
-
-/**
- * Synchronizes a shared set of variables between multiple nodes
- */
-
-class Sync
-{
-private:
-  RF24Network& network;
-  uint8_t* app_data; /**< Application's copy of the data */
-  uint8_t* internal_data; /**< Our copy of the data */
-  size_t len; /**< Length of the data in bytes */
-  uint16_t to_node; /**< The other node we're syncing with */
-
-protected:
-public:
-  /**
-   * Constructor
-   *
-   * @param _network Which network to syncrhonize over
-   */
-  Sync(RF24Network& _network): network(_network), app_data(NULL),
-    internal_data(NULL), len(0), to_node(0)
-  {
-  }
-  /**
-   * Begin the object
-   *
-   * @param _to_node Which node we are syncing with
-   */
-  void begin(uint16_t _to_node)
-  {
-    to_node = _to_node;
-  }
-  /**
-   * Declare the shared data set
-   *
-   * @param _data Location of shared data to be syncrhonized
-   */
-  template <class T>
-  void register_me(T& _data)
-  {
-    app_data = reinterpret_cast<uint8_t*>(&_data);
-    len = sizeof(_data);
-    internal_data = reinterpret_cast<uint8_t*>(malloc(len));
-    reset();
-  }
-
-  /**
-   * Reset the internal copy of the shared data set 
-   */
-  void reset(void)
-  {
-    memcpy(internal_data,app_data,len);
-  }
-  
-  /**
-   * Update the network and the shared data set
-   */
-  void update(void);
-};
-
-#endif // __SYNC_H__
-// vim:cin:ai:sts=2 sw=2 ft=cpp
--- a/main.cpp	Mon Jul 06 04:03:48 2015 +0000
+++ b/main.cpp	Mon Jul 06 05:23:41 2015 +0000
@@ -1,17 +1,15 @@
 #include "mbed.h"
 #include <RF24Network.h>
-#include <nRF24L01P_Maniacbug.h>
+#include <RF24.h>
 
 Serial pc(USBTX, USBRX);
 
 #define nrf_CE      D9
 #define nrf_CSN     D10
-#define nrf_IRQ     PB_0
 #define spi_SCK     D3
 #define spi_MOSI    D4
 #define spi_MISO    D5
 
-//RF24 radio(D11, D12, D13, D10, D9);
 RF24 radio(spi_MOSI, spi_MISO, spi_SCK, nrf_CSN, nrf_CE);
 
 // Network uses that radio
@@ -23,47 +21,41 @@
 // Address of the other node
 const uint16_t other_node = 0;
 
-// How often to send 'hello world to the other unit
-const unsigned long interval = 100; //ms
-
 // When did we last send?
 unsigned long last_sent;
-Timer t;
 
 // How many have we sent already
 unsigned long packets_sent;
-Timer t_packet;
 
 // Structure of our payload
-struct payload_t
+struct payload_t 
 {
-  unsigned long ms;
-  unsigned long counter;
-  
-  float vector_4d[4];
+    unsigned long ms;
+    unsigned long counter;
+
+    float vector_4d[4];
 };
 
 
-int main() 
+int main()
 {
     pc.baud(921600);
     wait_ms(1000);
-    
-    
-    
-    pc.printf("mBed RF24 network node - Rx only\n");
+
+
+
+    pc.printf("mBed RF24Network node\n");
     radio.begin();
     network.begin(/*channel*/ 90, /*node address*/ this_node);
     wait_ms(2000);
-    t.start();
-    t_packet.start();
-    while(1)
+
+    while(1) 
     {
         // Pump the network regularly
         network.update();
-  
+
         // Is there anything ready for us?
-        while ( network.available() )
+        while ( network.available() ) 
         {
             // If so, grab it and print it out
             RF24NetworkHeader header_rx;
@@ -71,33 +63,7 @@
             network.read(header_rx,&payload_rx,sizeof(payload_rx));
             pc.printf("Received packet # %d at %d ms, message: V4 %f, %f, %f, %f \n",payload_rx.counter,payload_rx.ms, payload_rx.vector_4d[0],payload_rx.vector_4d[1],payload_rx.vector_4d[2],payload_rx.vector_4d[3]);
         }
-        
-        /* If it's time to send a message, send it! */
-        unsigned long now = t.read_ms();
-        if ( now >= interval  )
-        {
-            t.reset();
 
-            pc.printf("Sending...");
-            //payload_t payload_tx = { millis(), packets_sent++, "Hello from node 0" };
-            payload_t payload_tx;
-            payload_tx.ms = t_packet.read_ms();
-            payload_tx.counter = packets_sent++;
-            for(int i=0;i<=3;i++)
-            {
-                payload_tx.vector_4d[i] = i + 1.00f;
-            }
-    
-    
-            RF24NetworkHeader header_tx(/*to node*/ other_node);
-            bool ok = network.write(header_tx,&payload_tx,sizeof(payload_tx));
-            if (ok)
-            pc.printf("ok.\n");
-            else
-            pc.printf("failed.\n");
-        } 
-        
-        
     }
-        
+
 }
\ No newline at end of file
--- a/mbed-rtos.lib	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#58c3b7759abf
--- a/nRF24L01P_Maniacbug/nRF24L01P_Maniacbug.cpp	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1003 +0,0 @@
-/*
- Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-#include "nRF24L01P_Maniacbug.h"
-
-/****************************************************************************/
-
-void RF24::csn(int mode)
-{
-  // Minimum ideal spi bus speed is 2x data rate
-  // If we assume 2Mbs data rate and 16Mhz clock, a
-  // divider of 4 is the minimum we want.
-  // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz
-//#ifdef ARDUINO
-//  spi.setBitOrder(MSBFIRST);
-//  spi.setDataMode(spi_MODE0);
-//  spi.setClockDivider(spi_CLOCK_DIV4);
-//#endif
-//  digitalWrite(csn_pin,mode);
-    csn_pin = mode;
-    
-}
-
-/****************************************************************************/
-
-void RF24::ce(int level)
-{
-  //digitalWrite(ce_pin,level);
-  ce_pin = level;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len)
-{
-  uint8_t status;
-
-  csn(LOW);
-  status = spi.write( R_REGISTER | ( REGISTER_MASK & reg ) );
-  while ( len-- )
-    *buf++ = spi.write(0xff);
-
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::read_register(uint8_t reg)
-{
-  csn(LOW);
-  spi.write( R_REGISTER | ( REGISTER_MASK & reg ) );
-  uint8_t result = spi.write(0xff);
-
-  csn(HIGH);
-  return result;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)
-{
-  uint8_t status;
-
-  csn(LOW);
-  status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) );
-  while ( len-- )
-    spi.write(*buf++);
-
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::write_register(uint8_t reg, uint8_t value)
-{
-  uint8_t status;
-
-//  IF_SERIAL_DEBUG(printf(("write_register(%02x,%02x)\r\n"),reg,value));
-
-  csn(LOW);
-  status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) );
-  spi.write(value);
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::write_payload(const void* buf, uint8_t len)
-{
-  uint8_t status;
-
-  const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
-
-  uint8_t data_len = min(len,payload_size);
-  uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
-  
-  //printf("[Writing %u bytes %u blanks]",data_len,blank_len);
-  
-  csn(LOW);
-  status = spi.write( W_TX_PAYLOAD );
-  while ( data_len-- )
-    spi.write(*current++);
-  while ( blank_len-- )
-    spi.write(0);
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::read_payload(void* buf, uint8_t len)
-{
-  uint8_t status;
-  uint8_t* current = reinterpret_cast<uint8_t*>(buf);
-
-  uint8_t data_len = min(len,payload_size);
-  uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
-  
-  //printf("[Reading %u bytes %u blanks]",data_len,blank_len);
-  
-  csn(LOW);
-  status = spi.write( R_RX_PAYLOAD );
-  while ( data_len-- )
-    *current++ = spi.write(0xff);
-  while ( blank_len-- )
-    spi.write(0xff);
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::flush_rx(void)
-{
-  uint8_t status;
-
-  csn(LOW);
-  status = spi.write( FLUSH_RX );
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::flush_tx(void)
-{
-  uint8_t status;
-
-  csn(LOW);
-  status = spi.write( FLUSH_TX );
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-uint8_t RF24::get_status(void)
-{
-  uint8_t status;
-
-  csn(LOW);
-  status = spi.write( NOP );
-  csn(HIGH);
-
-  return status;
-}
-
-/****************************************************************************/
-
-void RF24::print_status(uint8_t status)
-{
-  printf(("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"),
-           status,
-           (status & _BV(RX_DR))?1:0,
-           (status & _BV(TX_DS))?1:0,
-           (status & _BV(MAX_RT))?1:0,
-           ((status >> RX_P_NO) & 7),
-           (status & _BV(TX_FULL))?1:0
-          );
-}
-
-/****************************************************************************/
-
-void RF24::print_observe_tx(uint8_t value)
-{
-  printf(("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"),
-           value,
-           (value >> PLOS_CNT) & 15,
-           (value >> ARC_CNT) & 15
-          );
-}
-
-/****************************************************************************/
-
-void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty)
-{
-//  char extra_tab = strlen(name) < 8 ? '\t' : 0;
-  printf("%s =",name);
-  while (qty--)
-    printf((" 0x%02x"),read_register(reg++));
-  printf(("\r\n"));
-}
-
-/****************************************************************************/
-
-void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
-{
-//  char extra_tab = strlen_P(name) < 8 ? '\t' : 0;
-  printf("%s =",name);
-
-  while (qty--)
-  {
-    uint8_t buffer[5];
-    read_register(reg++,buffer,sizeof buffer);
-
-    printf((" 0x"));
-    uint8_t* bufptr = buffer + sizeof buffer;
-    while( --bufptr >= buffer )
-      printf(("%02x"),*bufptr);
-  }
-
-  printf(("\r\n"));
-}
-
-/****************************************************************************/
-
-RF24::RF24(PinName mosi, PinName miso, PinName sck, PinName _csnpin, PinName _cepin):
-  ce_pin(_cepin), csn_pin(_csnpin), wide_band(true), p_variant(false), 
-  payload_size(32), ack_payload_available(false), dynamic_payloads_enabled(false),
-  pipe0_reading_address(0), spi(mosi, miso, sck)
-{
-    spi.frequency(10000000/5);     // 2Mbit, 1/5th the maximum transfer rate for the spi bus
-    spi.format(8,0);                                   // 8-bit, ClockPhase = 0, ClockPolarity = 0
-    wait_ms(100);
-}
-
-/****************************************************************************/
-
-void RF24::setChannel(uint8_t channel)
-{
-  // TODO: This method could take advantage of the 'wide_band' calculation
-  // done in setChannel() to require certain channel spacing.
-
-  const uint8_t max_channel = 127;
-  write_register(RF_CH,min(channel,max_channel));
-}
-
-/****************************************************************************/
-
-void RF24::setPayloadSize(uint8_t size)
-{
-  const uint8_t max_payload_size = 32;
-  payload_size = min(size,max_payload_size);
-}
-
-/****************************************************************************/
-
-uint8_t RF24::getPayloadSize(void)
-{
-  return payload_size;
-}
-
-/****************************************************************************/
-
-static const char rf24_datarate_e_str_0[]  = "1MBPS";
-static const char rf24_datarate_e_str_1[]  = "2MBPS";
-static const char rf24_datarate_e_str_2[]  = "250KBPS";
-static const char * const rf24_datarate_e_str_P[]  = {
-  rf24_datarate_e_str_0,
-  rf24_datarate_e_str_1,
-  rf24_datarate_e_str_2,
-};
-static const char rf24_model_e_str_0[]  = "nRF24L01";
-static const char rf24_model_e_str_1[]  = "nRF24L01+";
-static const char * const rf24_model_e_str_P[]  = {
-  rf24_model_e_str_0,
-  rf24_model_e_str_1,
-};
-static const char rf24_crclength_e_str_0[]  = "Disabled";
-static const char rf24_crclength_e_str_1[]  = "8 bits";
-static const char rf24_crclength_e_str_2[]  = "16 bits" ;
-static const char * const rf24_crclength_e_str_P[]  = {
-  rf24_crclength_e_str_0,
-  rf24_crclength_e_str_1,
-  rf24_crclength_e_str_2,
-};
-static const char rf24_pa_dbm_e_str_0[]  = "PA_MIN";
-static const char rf24_pa_dbm_e_str_1[]  = "PA_LOW";
-static const char rf24_pa_dbm_e_str_2[]  = "PA_MED";
-static const char rf24_pa_dbm_e_str_3[]  = "PA_HIGH";
-static const char * const rf24_pa_dbm_e_str_P[]  = { 
-  rf24_pa_dbm_e_str_0,
-  rf24_pa_dbm_e_str_1,
-  rf24_pa_dbm_e_str_2,
-  rf24_pa_dbm_e_str_3,
-};
-
-void RF24::printDetails(void)
-{
-  print_status(get_status());
-
-  print_address_register(("RX_ADDR_P0-1"),RX_ADDR_P0,2);
-  print_byte_register(("RX_ADDR_P2-5"),RX_ADDR_P2,4);
-  print_address_register(("TX_ADDR"),TX_ADDR);
-
-  print_byte_register(("RX_PW_P0-6"),RX_PW_P0,6);
-  print_byte_register(("EN_AA"),EN_AA);
-  print_byte_register(("EN_RXADDR"),EN_RXADDR);
-  print_byte_register(("RF_CH"),RF_CH);
-  print_byte_register(("RF_SETUP"),RF_SETUP);
-  print_byte_register(("CONFIG"),CONFIG);
-  print_byte_register(("DYNPD/FEATURE"),DYNPD,2);
-
-  printf(("Data Rate\t = %s\r\n"), rf24_datarate_e_str_P[getDataRate()]);
-  printf(("Model\t\t = %s\r\n"), rf24_model_e_str_P[isPVariant()]);
-  printf(("CRC Length\t = %s\r\n"),rf24_crclength_e_str_P[getCRCLength()]);
-  printf(("PA Power\t = %s\r\n"),rf24_pa_dbm_e_str_P[getPALevel()]);
-}
-
-/****************************************************************************/
-
-void RF24::begin(void)
-{
-  // Initialize pins
-//  pinMode(ce_pin,OUTPUT);
-//  pinMode(csn_pin,OUTPUT);
-
-  // Initialize spi bus
-  //spi.begin();
-  mainTimer.start();
-
-  ce(LOW);
-  csn(HIGH);
-
-  // Must allow the radio time to settle else configuration bits will not necessarily stick.
-  // This is actually only required following power up but some settling time also appears to
-  // be required after resets too. For full coverage, we'll always assume the worst.
-  // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped.
-  // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure.
-  // WARNING: wait_ms is based on P-variant whereby non-P *may* require different timing.
-  wait_ms( 5 ) ;
-
-  // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
-  // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
-  // sizes must never be used. See documentation for a more complete explanation.
-  write_register(SETUP_RETR,(4 << ARD) | (15 << ARC));
-
-  // Restore our default PA level
-  setPALevel( RF24_PA_MAX ) ;
-
-  // Determine if this is a p or non-p RF24 module and then
-  // reset our data rate back to default value. This works
-  // because a non-P variant won't allow the data rate to
-  // be set to 250Kbps.
-  if( setDataRate( RF24_250KBPS ) )
-  {
-    p_variant = true ;
-  }
-  
-  // Then set the data rate to the slowest (and most reliable) speed supported by all
-  // hardware.
-  setDataRate( RF24_1MBPS ) ;
-
-  // Initialize CRC and request 2-byte (16bit) CRC
-  setCRCLength( RF24_CRC_16 ) ;
-  
-  // Disable dynamic payloads, to match dynamic_payloads_enabled setting
-  write_register(DYNPD,0);
-
-  // Reset current status
-  // Notice reset and flush is the last thing we do
-  write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
-
-  // Set up default configuration.  Callers can always change it later.
-  // This channel should be universally safe and not bleed over into adjacent
-  // spectrum.
-  //setChannel(76);
-  setChannel(90);
-
-  // Flush buffers
-  flush_rx();
-  flush_tx();
-  
-  // set EN_RXADDRR to 0 to fix pipe 0 from receiving
-  write_register(EN_RXADDR, 0);
-}
-
-/****************************************************************************/
-
-void RF24::startListening(void)
-{
-  write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX));
-  write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
-
-  // Restore the pipe0 adddress, if exists
-  if (pipe0_reading_address)
-    write_register(RX_ADDR_P0, reinterpret_cast<const uint8_t*>(&pipe0_reading_address), 5);
-
-  // Flush buffers
-  flush_rx();
-  flush_tx();
-
-  // Go!
-  ce(HIGH);
-
-  // wait for the radio to come up (130us actually only needed)
-//  wait_msMicroseconds(130);
-    wait_us(130);
-}
-
-/****************************************************************************/
-
-void RF24::stopListening(void)
-{
-  ce(LOW);
-  flush_tx();
-  flush_rx();
-}
-
-/****************************************************************************/
-
-void RF24::powerDown(void)
-{
-  write_register(CONFIG,read_register(CONFIG) & ~_BV(PWR_UP));
-}
-
-/****************************************************************************/
-
-void RF24::powerUp(void)
-{
-  write_register(CONFIG,read_register(CONFIG) | _BV(PWR_UP));
-}
-
-/******************************************************************/
-
-bool RF24::write( const void* buf, uint8_t len )
-{
-  bool result = false;
-
-  // Begin the write
-  startWrite(buf,len);
-
-  // ------------
-  // At this point we could return from a non-blocking write, and then call
-  // the rest after an interrupt
-
-  // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd)
-  // or MAX_RT (maximum retries, transmission failed).  Also, we'll timeout in case the radio
-  // is flaky and we get neither.
-
-  // IN the end, the send should be blocking.  It comes back in 60ms worst case, or much faster
-  // if I tighted up the retry logic.  (Default settings will be 1500us.
-  // Monitor the send
-  uint8_t observe_tx;
-  uint8_t status;
-  uint32_t sent_at = mainTimer.read_ms();
-  const uint32_t timeout = 500; //ms to wait for timeout
-  do
-  {
-    status = read_register(OBSERVE_TX,&observe_tx,1);
-//    IF_SERIAL_DEBUG(Serial.print(observe_tx,HEX));
-  }
-  while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) && ( mainTimer.read_ms() - sent_at < timeout ) );
-
-  // The part above is what you could recreate with your own interrupt handler,
-  // and then call this when you got an interrupt
-  // ------------
-
-  // Call this when you get an interrupt
-  // The status tells us three things
-  // * The send was successful (TX_DS)
-  // * The send failed, too many retries (MAX_RT)
-  // * There is an ack packet waiting (RX_DR)
-  bool tx_ok, tx_fail;
-  whatHappened(tx_ok,tx_fail,ack_payload_available);
-  
-  //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available);
-
-  result = tx_ok;
-//  IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed"));
-
-  // Handle the ack packet
-  if ( ack_payload_available )
-  {
-    ack_payload_length = getDynamicPayloadSize();
-//    IF_SERIAL_DEBUG(Serial.print("[AckPacket]/"));
-//    IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC));
-  }
-
-  // Yay, we are done.
-
-  // Power down
-//  powerDown();
-
-  // Flush buffers (Is this a relic of past experimentation, and not needed anymore?
-//  flush_tx();
-
-  return result;
-}
-/****************************************************************************/
-
-void RF24::startWrite( const void* buf, uint8_t len )
-{
-  // Transmitter power-up
-  write_register(CONFIG, ( read_register(CONFIG) | _BV(PWR_UP) ) & ~_BV(PRIM_RX) );
-//  wait_msMicroseconds(150);
-    wait_us(130);
-
-  // Send the payload
-  write_payload( buf, len );
-
-  // Allons!
-  ce(HIGH);
-//  wait_msMicroseconds(15);
-    wait_us(15); 
-  ce(LOW);
-}
-
-/****************************************************************************/
-
-uint8_t RF24::getDynamicPayloadSize(void)
-{
-  uint8_t result = 0;
-
-  csn(LOW);
-  spi.write( R_RX_PL_WID );
-  result = spi.write(0xff);
-  csn(HIGH);
-
-  return result;
-}
-
-/****************************************************************************/
-
-bool RF24::available(void)
-{
-  return available(NULL);
-}
-
-/****************************************************************************/
-
-bool RF24::available(uint8_t* pipe_num)
-{
-  uint8_t status = get_status();
-
-  // Too noisy, enable if you really want lots o data!!
-  //IF_SERIAL_DEBUG(print_status(status));
-
-  bool result = ( status & _BV(RX_DR) );
-
-  if (result)
-  {
-    // If the caller wants the pipe number, include that
-    if ( pipe_num )
-      *pipe_num = ( status >> RX_P_NO ) & 7;
-
-    // Clear the status bit
-
-    // ??? Should this REALLY be cleared now?  Or wait until we
-    // actually READ the payload?
-
-    write_register(STATUS,_BV(RX_DR) );
-
-    // Handle ack payload receipt
-    if ( status & _BV(TX_DS) )
-    {
-      write_register(STATUS,_BV(TX_DS));
-    }
-  }
-
-  return result;
-}
-
-/****************************************************************************/
-
-bool RF24::read( void* buf, uint8_t len )
-{
-  // Fetch the payload
-  read_payload( buf, len );
-
-  // was this the last of the data available?
-  return read_register(FIFO_STATUS) & _BV(RX_EMPTY);
-}
-
-/****************************************************************************/
-
-void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready)
-{
-  // Read the status & reset the status in one easy call
-  // Or is that such a good idea?
-  uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
-
-  // Report to the user what happened
-  tx_ok = status & _BV(TX_DS);
-  tx_fail = status & _BV(MAX_RT);
-  rx_ready = status & _BV(RX_DR);
-}
-
-/****************************************************************************/
-
-void RF24::openWritingPipe(uint64_t value)
-{
-  // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+)
-  // expects it LSB first too, so we're good.
-
-  write_register(RX_ADDR_P0, reinterpret_cast<uint8_t*>(&value), 5);
-  write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&value), 5);
-
-  const uint8_t max_payload_size = 32;
-  write_register(RX_PW_P0,min(payload_size,max_payload_size));
-  
-  flush_tx();
-}
-
-/****************************************************************************/
-
-static const uint8_t child_pipe[]  =
-{
-  RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5
-};
-static const uint8_t child_payload_size[]  =
-{
-  RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5
-};
-static const uint8_t child_pipe_enable[]  =
-{
-  ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5
-};
-
-void RF24::openReadingPipe(uint8_t child, uint64_t address)
-{
-  // If this is pipe 0, cache the address.  This is needed because
-  // openWritingPipe() will overwrite the pipe 0 address, so
-  // startListening() will have to restore it.
-  if (child == 0)
-    pipe0_reading_address = address;
-
-  if (child <= 6)
-  {
-    // For pipes 2-5, only write the LSB
-    if ( child < 2 )
-      write_register(child_pipe[child], reinterpret_cast<const uint8_t*>(&address), 5);
-    else
-      write_register(child_pipe[child], reinterpret_cast<const uint8_t*>(&address), 1);
-
-    write_register(child_payload_size[child],payload_size);
-
-    // Note it would be more efficient to set all of the bits for all open
-    // pipes at once.  However, I thought it would make the calling code
-    // more simple to do it this way.
-    write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(child_pipe_enable[child]));
-  }
-}
-
-/****************************************************************************/
-
-void RF24::toggle_features(void)
-{
-  csn(LOW);
-  spi.write( ACTIVATE );
-  spi.write( 0x73 );
-  csn(HIGH);
-}
-
-/****************************************************************************/
-
-void RF24::enableDynamicPayloads(void)
-{
-  // Enable dynamic payload throughout the system
-  write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
-
-  // If it didn't work, the features are not enabled
-  if ( ! read_register(FEATURE) )
-  {
-    // So enable them and try again
-    toggle_features();
-    write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
-  }
-
-//  IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
-
-  // Enable dynamic payload on all pipes
-  //
-  // Not sure the use case of only having dynamic payload on certain
-  // pipes, so the library does not support it.
-  write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0));
-
-  dynamic_payloads_enabled = true;
-}
-
-/****************************************************************************/
-
-void RF24::enableAckPayload(void)
-{
-  //
-  // enable ack payload and dynamic payload features
-  //
-
-  write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
-
-  // If it didn't work, the features are not enabled
-  if ( ! read_register(FEATURE) )
-  {
-    // So enable them and try again
-    toggle_features();
-    write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
-  }
-
-//  IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
-
-  //
-  // Enable dynamic payload on pipes 0 & 1
-  //
-
-  write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0));
-}
-
-/****************************************************************************/
-
-void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
-{
-  const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
-
-  csn(LOW);
-  spi.write( W_ACK_PAYLOAD | ( pipe & 7 ) );
-  const uint8_t max_payload_size = 32;
-  uint8_t data_len = min(len,max_payload_size);
-  while ( data_len-- )
-    spi.write(*current++);
-
-  csn(HIGH);
-}
-
-/****************************************************************************/
-
-bool RF24::isAckPayloadAvailable(void)
-{
-  bool result = ack_payload_available;
-  ack_payload_available = false;
-  return result;
-}
-
-/****************************************************************************/
-
-bool RF24::isPVariant(void)
-{
-  return p_variant ;
-}
-
-/****************************************************************************/
-
-void RF24::setAutoAck(bool enable)
-{
-  if ( enable )
-    write_register(EN_AA, 63);
-  else
-    write_register(EN_AA, 0);
-}
-
-/****************************************************************************/
-
-void RF24::setAutoAck( uint8_t pipe, bool enable )
-{
-  if ( pipe <= 6 )
-  {
-    uint8_t en_aa = read_register( EN_AA ) ;
-    if( enable )
-    {
-      en_aa |= _BV(pipe) ;
-    }
-    else
-    {
-      en_aa &= ~_BV(pipe) ;
-    }
-    write_register( EN_AA, en_aa ) ;
-  }
-}
-
-/****************************************************************************/
-
-bool RF24::testCarrier(void)
-{
-  return ( read_register(CD) & 1 );
-}
-
-/****************************************************************************/
-
-bool RF24::testRPD(void)
-{
-  return ( read_register(RPD) & 1 ) ;
-}
-
-/****************************************************************************/
-
-void RF24::setPALevel(rf24_pa_dbm_e level)
-{
-  uint8_t setup = read_register(RF_SETUP) ;
-  setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
-
-  // switch uses RAM (evil!)
-  if ( level == RF24_PA_MAX )
-  {
-    setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
-  }
-  else if ( level == RF24_PA_HIGH )
-  {
-    setup |= _BV(RF_PWR_HIGH) ;
-  }
-  else if ( level == RF24_PA_LOW )
-  {
-    setup |= _BV(RF_PWR_LOW);
-  }
-  else if ( level == RF24_PA_MIN )
-  {
-    // nothing
-  }
-  else if ( level == RF24_PA_ERROR )
-  {
-    // On error, go to maximum PA
-    setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
-  }
-
-  write_register( RF_SETUP, setup ) ;
-}
-
-/****************************************************************************/
-
-rf24_pa_dbm_e RF24::getPALevel(void)
-{
-  rf24_pa_dbm_e result = RF24_PA_ERROR ;
-  uint8_t power = read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) ;
-
-  // switch uses RAM (evil!)
-  if ( power == (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)) )
-  {
-    result = RF24_PA_MAX ;
-  }
-  else if ( power == _BV(RF_PWR_HIGH) )
-  {
-    result = RF24_PA_HIGH ;
-  }
-  else if ( power == _BV(RF_PWR_LOW) )
-  {
-    result = RF24_PA_LOW ;
-  }
-  else
-  {
-    result = RF24_PA_MIN ;
-  }
-
-  return result ;
-}
-
-/****************************************************************************/
-
-bool RF24::setDataRate(rf24_datarate_e speed)
-{
-  bool result = false;
-  uint8_t setup = read_register(RF_SETUP) ;
-
-  // HIGH and LOW '00' is 1Mbs - our default
-  wide_band = false ;
-  setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ;
-  if( speed == RF24_250KBPS )
-  {
-    // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
-    // Making it '10'.
-    wide_band = false ;
-    setup |= _BV( RF_DR_LOW ) ;
-  }
-  else
-  {
-    // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1
-    // Making it '01'
-    if ( speed == RF24_2MBPS )
-    {
-      wide_band = true ;
-      setup |= _BV(RF_DR_HIGH);
-    }
-    else
-    {
-      // 1Mbs
-      wide_band = false ;
-    }
-  }
-  write_register(RF_SETUP,setup);
-
-  // Verify our result
-  if ( read_register(RF_SETUP) == setup )
-  {
-    result = true;
-  }
-  else
-  {
-    wide_band = false;
-  }
-
-  return result;
-}
-
-/****************************************************************************/
-
-rf24_datarate_e RF24::getDataRate( void )
-{
-  rf24_datarate_e result ;
-  uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH));
-  
-  // switch uses RAM (evil!)
-  // Order matters in our case below
-  if ( dr == _BV(RF_DR_LOW) )
-  {
-    // '10' = 250KBPS
-    result = RF24_250KBPS ;
-  }
-  else if ( dr == _BV(RF_DR_HIGH) )
-  {
-    // '01' = 2MBPS
-    result = RF24_2MBPS ;
-  }
-  else
-  {
-    // '00' = 1MBPS
-    result = RF24_1MBPS ;
-  }
-  return result ;
-}
-
-/****************************************************************************/
-
-void RF24::setCRCLength(rf24_crclength_e length)
-{
-  uint8_t config = read_register(CONFIG) & ~( _BV(CRCO) | _BV(EN_CRC)) ;
- 
-  if ( length == RF24_CRC_DISABLED )
-  {
-    // Do nothing, we turned it off above. 
-  }
-  else if ( length == RF24_CRC_8 )
-  {
-    config |= _BV(EN_CRC);
-  }
-  else
-  {
-    config |= _BV(EN_CRC);
-    config |= _BV( CRCO );
-  }
-  write_register( CONFIG, config ) ;
-}
-
-/****************************************************************************/
-
-rf24_crclength_e RF24::getCRCLength(void)
-{
-  rf24_crclength_e result = RF24_CRC_DISABLED;
-  uint8_t config = read_register(CONFIG) & ( _BV(CRCO) | _BV(EN_CRC)) ;
-
-  if ( config & _BV(EN_CRC ) )
-  {
-    if ( config & _BV(CRCO) )
-      result = RF24_CRC_16;
-    else
-      result = RF24_CRC_8;
-  }
-
-  return result;
-}
-
-/****************************************************************************/
-
-void RF24::disableCRC( void )
-{
-  uint8_t disable = read_register(CONFIG) & ~_BV(EN_CRC) ;
-  write_register( CONFIG, disable ) ;
-}
-
-/****************************************************************************/
-void RF24::setRetries(uint8_t delay, uint8_t count)
-{
- write_register(SETUP_RETR,(delay&0xf)<<ARD | (count&0xf)<<ARC);
-}
-
-uint8_t RF24::min(uint8_t a, uint8_t b)
-{
-    if(a < b)
-        return a;
-    else
-        return b;
-}
--- a/nRF24L01P_Maniacbug/nRF24L01P_Maniacbug.h	Mon Jul 06 04:03:48 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,779 +0,0 @@
-/*
-    Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
-
-    Permission is hereby granted, free of charge, to any person 
-    obtaining a copy of this software and associated documentation 
-    files (the "Software"), to deal in the Software without 
-    restriction, including without limitation the rights to use, copy, 
-    modify, merge, publish, distribute, sublicense, and/or sell copies 
-    of the Software, and to permit persons to whom the Software is 
-    furnished to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be 
-    included in all copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
-    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
-    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
-    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
-    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
-    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
-    DEALINGS IN THE SOFTWARE.
-*/
-
-/* Memory Map */
-#define CONFIG      0x00
-#define EN_AA       0x01
-#define EN_RXADDR   0x02
-#define SETUP_AW    0x03
-#define SETUP_RETR  0x04
-#define RF_CH       0x05
-#define RF_SETUP    0x06
-#define STATUS      0x07
-#define OBSERVE_TX  0x08
-#define CD          0x09
-#define RX_ADDR_P0  0x0A
-#define RX_ADDR_P1  0x0B
-#define RX_ADDR_P2  0x0C
-#define RX_ADDR_P3  0x0D
-#define RX_ADDR_P4  0x0E
-#define RX_ADDR_P5  0x0F
-#define TX_ADDR     0x10
-#define RX_PW_P0    0x11
-#define RX_PW_P1    0x12
-#define RX_PW_P2    0x13
-#define RX_PW_P3    0x14
-#define RX_PW_P4    0x15
-#define RX_PW_P5    0x16
-#define FIFO_STATUS 0x17
-#define DYNPD       0x1C
-#define FEATURE     0x1D
-
-/* Bit Mnemonics */
-#define MASK_RX_DR  6
-#define MASK_TX_DS  5
-#define MASK_MAX_RT 4
-#define EN_CRC      3
-#define CRCO        2
-#define PWR_UP      1
-#define PRIM_RX     0
-#define ENAA_P5     5
-#define ENAA_P4     4
-#define ENAA_P3     3
-#define ENAA_P2     2
-#define ENAA_P1     1
-#define ENAA_P0     0
-#define ERX_P5      5
-#define ERX_P4      4
-#define ERX_P3      3
-#define ERX_P2      2
-#define ERX_P1      1
-#define ERX_P0      0
-#define AW          0
-#define ARD         4
-#define ARC         0
-#define PLL_LOCK    4
-#define RF_DR       3
-#define RF_PWR      6
-#define RX_DR       6
-#define TX_DS       5
-#define MAX_RT      4
-#define RX_P_NO     1
-#define TX_FULL     0
-#define PLOS_CNT    4
-#define ARC_CNT     0
-#define TX_REUSE    6
-#define FIFO_FULL   5
-#define TX_EMPTY    4
-#define RX_FULL     1
-#define RX_EMPTY    0
-#define DPL_P5      5
-#define DPL_P4      4
-#define DPL_P3      3
-#define DPL_P2      2
-#define DPL_P1      1
-#define DPL_P0      0
-#define EN_DPL      2
-#define EN_ACK_PAY  1
-#define EN_DYN_ACK  0
-
-/* Instruction Mnemonics */
-#define R_REGISTER    0x00
-#define W_REGISTER    0x20
-#define REGISTER_MASK 0x1F
-#define ACTIVATE      0x50
-#define R_RX_PL_WID   0x60
-#define R_RX_PAYLOAD  0x61
-#define W_TX_PAYLOAD  0xA0
-#define W_ACK_PAYLOAD 0xA8
-#define FLUSH_TX      0xE1
-#define FLUSH_RX      0xE2
-#define REUSE_TX_PL   0xE3
-#define NOP           0xFF
-
-/* Non-P omissions */
-#define LNA_HCURR   0
-
-/* P model memory Map */
-#define RPD         0x09
-
-/* P model bit Mnemonics */
-#define RF_DR_LOW   5
-#define RF_DR_HIGH  3
-#define RF_PWR_LOW  1
-#define RF_PWR_HIGH 2
-
-#define HIGH        1
-#define LOW         0
-#define _BV(n) (1 << n)
-
-/*
- Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as published by the Free Software Foundation.
- */
-
-/**
- * @file RF24.h
- *
- * Class declaration for RF24 and helper enums
- */
-
-#ifndef __RF24_H__
-#define __RF24_H__
-
-#include <mbed.h>
-
-/**
- * Power Amplifier level.
- *
- * For use with setPALevel()
- */
-typedef enum { RF24_PA_MIN = 0,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_PA_ERROR } rf24_pa_dbm_e ;
-
-/**
- * Data rate.  How fast data moves through the air.
- *
- * For use with setDataRate()
- */
-typedef enum { RF24_1MBPS = 0, RF24_2MBPS, RF24_250KBPS } rf24_datarate_e;
-
-/**
- * CRC Length.  How big (if any) of a CRC is included.
- *
- * For use with setCRCLength()
- */
-typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e;
-
-/**
- * Driver for nRF24L01(+) 2.4GHz Wireless Transceiver
- */
-
-class RF24
-{
-private:
-  DigitalOut ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
-  DigitalOut csn_pin; /**< SPI Chip select */
-  bool wide_band; /* 2Mbs data rate in use? */
-  bool p_variant; /* False for RF24L01 and true for RF24L01P */
-  uint8_t payload_size; /**< Fixed size of payloads */
-  bool ack_payload_available; /**< Whether there is an ack payload waiting */
-  bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ 
-  uint8_t ack_payload_length; /**< Dynamic size of pending ack payload. */
-  uint64_t pipe0_reading_address; /**< Last address set on pipe 0 for reading. */
-  SPI spi;
-  Timer mainTimer;
-
-protected:
-  /**
-   * @name Low-level internal interface.
-   *
-   *  Protected methods that address the chip directly.  Regular users cannot
-   *  ever call these.  They are documented for completeness and for developers who
-   *  may want to extend this class.
-   */
-  /**@{*/
-
-  /**
-   * Set chip select pin
-   *
-   * Running SPI bus at PI_CLOCK_DIV2 so we don't waste time transferring data
-   * and best of all, we make use of the radio's FIFO buffers. A lower speed
-   * means we're less likely to effectively leverage our FIFOs and pay a higher
-   * AVR runtime cost as toll.
-   *
-   * @param mode HIGH to take this unit off the SPI bus, LOW to put it on
-   */
-  void csn(int mode);
-
-  /**
-   * Set chip enable
-   *
-   * @param level HIGH to actively begin transmission or LOW to put in standby.  Please see data sheet
-   * for a much more detailed description of this pin.
-   */
-  void ce(int level);  
-
-
-  /**
-   * Read a chunk of data in from a register
-   *
-   * @param reg Which register. Use constants from nRF24L01.h
-   * @param buf Where to put the data
-   * @param len How many bytes of data to transfer
-   * @return Current value of status register
-   */
-  uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len);
-
-  /**
-   * Read single byte from a register
-   *
-   * @param reg Which register. Use constants from nRF24L01.h
-   * @return Current value of register @p reg
-   */
-  uint8_t read_register(uint8_t reg);
-
-  /**
-   * Write a chunk of data to a register
-   *
-   * @param reg Which register. Use constants from nRF24L01.h
-   * @param buf Where to get the data
-   * @param len How many bytes of data to transfer
-   * @return Current value of status register
-   */
-  uint8_t write_register(uint8_t reg, const uint8_t* buf, uint8_t len);
-
-  /**
-   * Write a single byte to a register
-   *
-   * @param reg Which register. Use constants from nRF24L01.h
-   * @param value The new value to write
-   * @return Current value of status register
-   */
-  uint8_t write_register(uint8_t reg, uint8_t value);
-
-  /**
-   * Write the transmit payload
-   *
-   * The size of data written is the fixed payload size, see getPayloadSize()
-   *
-   * @param buf Where to get the data
-   * @param len Number of bytes to be sent
-   * @return Current value of status register
-   */
-  uint8_t write_payload(const void* buf, uint8_t len);
-
-  /**
-   * Read the receive payload
-   *
-   * The size of data read is the fixed payload size, see getPayloadSize()
-   *
-   * @param buf Where to put the data
-   * @param len Maximum number of bytes to read
-   * @return Current value of status register
-   */
-  uint8_t read_payload(void* buf, uint8_t len);
-
-
-  /**
-   * Decode and print the given status to stdout
-   *
-   * @param status Status value to print
-   *
-   * @warning Does nothing if stdout is not defined.  See fdevopen in stdio.h
-   */
-  void print_status(uint8_t status);
-
-  /**
-   * Decode and print the given 'observe_tx' value to stdout
-   *
-   * @param value The observe_tx value to print
-   *
-   * @warning Does nothing if stdout is not defined.  See fdevopen in stdio.h
-   */
-  void print_observe_tx(uint8_t value);
-
-  /**
-   * Print the name and value of an 8-bit register to stdout
-   *
-   * Optionally it can print some quantity of successive
-   * registers on the same line.  This is useful for printing a group
-   * of related registers on one line.
-   *
-   * @param name Name of the register
-   * @param reg Which register. Use constants from nRF24L01.h
-   * @param qty How many successive registers to print
-   */
-  void print_byte_register(const char* name, uint8_t reg, uint8_t qty = 1);
-
-  /**
-   * Print the name and value of a 40-bit address register to stdout
-   *
-   * Optionally it can print some quantity of successive
-   * registers on the same line.  This is useful for printing a group
-   * of related registers on one line.
-   *
-   * @param name Name of the register
-   * @param reg Which register. Use constants from nRF24L01.h
-   * @param qty How many successive registers to print
-   */
-  void print_address_register(const char* name, uint8_t reg, uint8_t qty = 1);
-
-  /**
-   * Turn on or off the special features of the chip
-   *
-   * The chip has certain 'features' which are only available when the 'features'
-   * are enabled.  See the datasheet for details.
-   */
-  void toggle_features(void);
-  /**@}*/
-
-public:
-  /**
-   * @name Primary public interface
-   *
-   *  These are the main methods you need to operate the chip
-   */
-  /**@{*/
-
-  /**
-   * Constructor
-   *
-   * Creates a new instance of this driver.  Before using, you create an instance
-   * and send in the unique pins that this chip is connected to.
-   *
-   * @param _cepin The pin attached to Chip Enable on the RF module
-   * @param _cspin The pin attached to Chip Select
-   */
-  RF24(PinName mosi, PinName miso, PinName sck, PinName _csnpin, PinName _cepin);
-
-  /**
-   * Begin operation of the chip
-   *
-   * Call this in setup(), before calling any other methods.
-   */
-  void begin(void);
-  
-    /**
-   * Retrieve the current status of the chip
-   *
-   * @return Current value of status register
-   */
-  uint8_t get_status(void);
-    
-  /**
-   * Empty the receive buffer
-   *
-   * @return Current value of status register
-   */
-  uint8_t flush_rx(void);
-
-  /**
-   * Empty the transmit buffer
-   *
-   * @return Current value of status register
-   */
-  uint8_t flush_tx(void);
-
-  /**
-   * Start listening on the pipes opened for reading.
-   *
-   * Be sure to call openReadingPipe() first.  Do not call write() while
-   * in this mode, without first calling stopListening().  Call
-   * isAvailable() to check for incoming traffic, and read() to get it.
-   */
-  void startListening(void);
-
-  /**
-   * Stop listening for incoming messages
-   *
-   * Do this before calling write().
-   */
-  void stopListening(void);
-
-  /**
-   * Write to the open writing pipe
-   *
-   * Be sure to call openWritingPipe() first to set the destination
-   * of where to write to.
-   *
-   * This blocks until the message is successfully acknowledged by
-   * the receiver or the timeout/retransmit maxima are reached.  In
-   * the current configuration, the max delay here is 60ms.
-   *
-   * The maximum size of data written is the fixed payload size, see
-   * getPayloadSize().  However, you can write less, and the remainder
-   * will just be filled with zeroes.
-   *
-   * @param buf Pointer to the data to be sent
-   * @param len Number of bytes to be sent
-   * @return True if the payload was delivered successfully false if not
-   */
-  bool write( const void* buf, uint8_t len );
-
-  /**
-   * Test whether there are bytes available to be read
-   *
-   * @return True if there is a payload available, false if none is
-   */
-  bool available(void);
-
-  /**
-   * Read the payload
-   *
-   * Return the last payload received
-   *
-   * The size of data read is the fixed payload size, see getPayloadSize()
-   *
-   * @note I specifically chose 'void*' as a data type to make it easier
-   * for beginners to use.  No casting needed.
-   *
-   * @param buf Pointer to a buffer where the data should be written
-   * @param len Maximum number of bytes to read into the buffer
-   * @return True if the payload was delivered successfully false if not
-   */
-  bool read( void* buf, uint8_t len );
-
-  /**
-   * Open a pipe for writing
-   *
-   * Only one pipe can be open at once, but you can change the pipe
-   * you'll listen to.  Do not call this while actively listening.
-   * Remember to stopListening() first.
-   *
-   * Addresses are 40-bit hex values, e.g.:
-   *
-   * @code
-   *   openWritingPipe(0xF0F0F0F0F0);
-   * @endcode
-   *
-   * @param address The 40-bit address of the pipe to open.  This can be
-   * any value whatsoever, as long as you are the only one writing to it
-   * and only one other radio is listening to it.  Coordinate these pipe
-   * addresses amongst nodes on the network.
-   */
-  void openWritingPipe(uint64_t address);
-
-  /**
-   * Open a pipe for reading
-   *
-   * Up to 6 pipes can be open for reading at once.  Open all the
-   * reading pipes, and then call startListening().
-   *
-   * @see openWritingPipe
-   *
-   * @warning Pipes 1-5 should share the first 32 bits.
-   * Only the least significant byte should be unique, e.g.
-   * @code
-   *   openReadingPipe(1,0xF0F0F0F0AA);
-   *   openReadingPipe(2,0xF0F0F0F066);
-   * @endcode
-   *
-   * @warning Pipe 0 is also used by the writing pipe.  So if you open
-   * pipe 0 for reading, and then startListening(), it will overwrite the
-   * writing pipe.  Ergo, do an openWritingPipe() again before write().
-   *
-   * @todo Enforce the restriction that pipes 1-5 must share the top 32 bits
-   *
-   * @param number Which pipe# to open, 0-5.
-   * @param address The 40-bit address of the pipe to open.
-   */
-  void openReadingPipe(uint8_t number, uint64_t address);
-
-  /**@}*/
-  /**
-   * @name Optional Configurators 
-   *
-   *  Methods you can use to get or set the configuration of the chip.
-   *  None are required.  Calling begin() sets up a reasonable set of
-   *  defaults.
-   */
-  /**@{*/
-  /**
-   * Set the number and delay of retries upon failed submit
-   *
-   * @param delay How long to wait between each retry, in multiples of 250us,
-   * max is 15.  0 means 250us, 15 means 4000us.
-   * @param count How many retries before giving up, max 15
-   */
-  void setRetries(uint8_t delay, uint8_t count);
-
-  /**
-   * Set RF communication channel
-   *
-   * @param channel Which RF channel to communicate on, 0-127
-   */
-  void setChannel(uint8_t channel);
-
-  /**
-   * Set Static Payload Size
-   *
-   * This implementation uses a pre-stablished fixed payload size for all
-   * transmissions.  If this method is never called, the driver will always
-   * transmit the maximum payload size (32 bytes), no matter how much
-   * was sent to write().
-   *
-   * @todo Implement variable-sized payloads feature
-   *
-   * @param size The number of bytes in the payload
-   */
-  void setPayloadSize(uint8_t size);
-
-  /**
-   * Get Static Payload Size
-   *
-   * @see setPayloadSize()
-   *
-   * @return The number of bytes in the payload
-   */
-  uint8_t getPayloadSize(void);
-
-  /**
-   * Get Dynamic Payload Size
-   *
-   * For dynamic payloads, this pulls the size of the payload off
-   * the chip
-   *
-   * @return Payload length of last-received dynamic payload
-   */
-  uint8_t getDynamicPayloadSize(void);
-  
-  /**
-   * Enable custom payloads on the acknowledge packets
-   *
-   * Ack payloads are a handy way to return data back to senders without
-   * manually changing the radio modes on both units.
-   *
-   * @see examples/pingpair_pl/pingpair_pl.pde
-   */
-  void enableAckPayload(void);
-
-  /**
-   * Enable dynamically-sized payloads
-   *
-   * This way you don't always have to send large packets just to send them
-   * once in a while.  This enables dynamic payloads on ALL pipes.
-   *
-   * @see examples/pingpair_pl/pingpair_dyn.pde
-   */
-  void enableDynamicPayloads(void);
-
-  /**
-   * Determine whether the hardware is an nRF24L01+ or not.
-   *
-   * @return true if the hardware is nRF24L01+ (or compatible) and false
-   * if its not.
-   */
-  bool isPVariant(void) ;
-
-  /**
-   * Enable or disable auto-acknowlede packets
-   *
-   * This is enabled by default, so it's only needed if you want to turn
-   * it off for some reason.
-   *
-   * @param enable Whether to enable (true) or disable (false) auto-acks
-   */
-  void setAutoAck(bool enable);
-
-  /**
-   * Enable or disable auto-acknowlede packets on a per pipeline basis.
-   *
-   * AA is enabled by default, so it's only needed if you want to turn
-   * it off/on for some reason on a per pipeline basis.
-   *
-   * @param pipe Which pipeline to modify
-   * @param enable Whether to enable (true) or disable (false) auto-acks
-   */
-  void setAutoAck( uint8_t pipe, bool enable ) ;
-
-  /**
-   * Set Power Amplifier (PA) level to one of four levels.
-   * Relative mnemonics have been used to allow for future PA level
-   * changes. According to 6.5 of the nRF24L01+ specification sheet,
-   * they translate to: RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
-   * RF24_PA_MED=-6dBM, and RF24_PA_HIGH=0dBm.
-   *
-   * @param level Desired PA level.
-   */
-  void setPALevel( rf24_pa_dbm_e level ) ;
-
-  /**
-   * Fetches the current PA level.
-   *
-   * @return Returns a value from the rf24_pa_dbm_e enum describing
-   * the current PA setting. Please remember, all values represented
-   * by the enum mnemonics are negative dBm. See setPALevel for
-   * return value descriptions.
-   */
-  rf24_pa_dbm_e getPALevel( void ) ;
-
-  /**
-   * Set the transmission data rate
-   *
-   * @warning setting RF24_250KBPS will fail for non-plus units
-   *
-   * @param speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
-   * @return true if the change was successful
-   */
-  bool setDataRate(rf24_datarate_e speed);
-  
-  /**
-   * Fetches the transmission data rate
-   *
-   * @return Returns the hardware's currently configured datarate. The value
-   * is one of 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS, as defined in the
-   * rf24_datarate_e enum.
-   */
-  rf24_datarate_e getDataRate( void ) ;
-
-  /**
-   * Set the CRC length
-   *
-   * @param length RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit
-   */
-  void setCRCLength(rf24_crclength_e length);
-
-  /**
-   * Get the CRC length
-   *
-   * @return RF24_DISABLED if disabled or RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit
-   */
-  rf24_crclength_e getCRCLength(void);
-
-  /**
-   * Disable CRC validation
-   *
-   */
-  void disableCRC( void ) ;
-
-  /**@}*/
-  /**
-   * @name Advanced Operation 
-   *
-   *  Methods you can use to drive the chip in more advanced ways 
-   */
-  /**@{*/
-
-  /**
-   * Print a giant block of debugging information to stdout
-   *
-   * @warning Does nothing if stdout is not defined.  See fdevopen in stdio.h
-   */
-  void printDetails(void);
-
-  /**
-   * Enter low-power mode
-   *
-   * To return to normal power mode, either write() some data or
-   * startListening, or powerUp().
-   */
-  void powerDown(void);
-
-  /**
-   * Leave low-power mode - making radio more responsive
-   *
-   * To return to low power mode, call powerDown().
-   */
-  void powerUp(void) ;
-
-  /**
-   * Test whether there are bytes available to be read
-   *
-   * Use this version to discover on which pipe the message
-   * arrived.
-   *
-   * @param[out] pipe_num Which pipe has the payload available
-   * @return True if there is a payload available, false if none is
-   */
-  bool available(uint8_t* pipe_num);
-
-  /**
-   * Non-blocking write to the open writing pipe
-   *
-   * Just like write(), but it returns immediately. To find out what happened
-   * to the send, catch the IRQ and then call whatHappened().
-   *
-   * @see write()
-   * @see whatHappened()
-   *
-   * @param buf Pointer to the data to be sent
-   * @param len Number of bytes to be sent
-   * @return True if the payload was delivered successfully false if not
-   */
-  void startWrite( const void* buf, uint8_t len );
-
-  /**
-   * Write an ack payload for the specified pipe
-   *
-   * The next time a message is received on @p pipe, the data in @p buf will
-   * be sent back in the acknowledgement.
-   *
-   * @warning According to the data sheet, only three of these can be pending
-   * at any time.  I have not tested this.
-   *
-   * @param pipe Which pipe# (typically 1-5) will get this response.
-   * @param buf Pointer to data that is sent
-   * @param len Length of the data to send, up to 32 bytes max.  Not affected
-   * by the static payload set by setPayloadSize().
-   */
-  void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len);
-
-  /**
-   * Determine if an ack payload was received in the most recent call to
-   * write().
-   *
-   * Call read() to retrieve the ack payload.
-   *
-   * @warning Calling this function clears the internal flag which indicates
-   * a payload is available.  If it returns true, you must read the packet
-   * out as the very next interaction with the radio, or the results are
-   * undefined.
-   *
-   * @return True if an ack payload is available.
-   */
-  bool isAckPayloadAvailable(void);
-
-  /**
-   * Call this when you get an interrupt to find out why
-   *
-   * Tells you what caused the interrupt, and clears the state of
-   * interrupts.
-   *
-   * @param[out] tx_ok The send was successful (TX_DS)
-   * @param[out] tx_fail The send failed, too many retries (MAX_RT)
-   * @param[out] rx_ready There is a message waiting to be read (RX_DS)
-   */
-  void whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready);
-
-  /**
-   * Test whether there was a carrier on the line for the
-   * previous listening period.
-   *
-   * Useful to check for interference on the current channel.
-   *
-   * @return true if was carrier, false if not
-   */
-  bool testCarrier(void);
-
-  /**
-   * Test whether a signal (carrier or otherwise) greater than
-   * or equal to -64dBm is present on the channel. Valid only
-   * on nRF24L01P (+) hardware. On nRF24L01, use testCarrier().
-   *
-   * Useful to check for interference on the current channel and
-   * channel hopping strategies.
-   *
-   * @return true if signal => -64dBm, false if not
-   */
-  bool testRPD(void) ;
-  
-  uint8_t min(uint8_t, uint8_t);
-};
-
-
-#endif // __RF24_H__
-// vim:ai:cin:sts=2 sw=2 ft=cpp