diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ff372a4 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +############################################################################# +# +# Makefile for librf24-bcm on Raspberry Pi +# +# License: GPL (General Public License) +# Author: Charles-Henri Hallard +# Date: 2013/03/13 +# +# Description: +# ------------ +# use make all and mak install to install the library +# You can change the install directory by editing the LIBDIR line +# +PREFIX=/usr/local + +# Library parameters +# where to put the lib +LIBDIR=$(PREFIX)/lib +# lib name +LIB=librf24-network +# shared library name +LIBNAME=$(LIB).so.1.0 + +CPPFLAGS=-I$(PREFIX)/include -I. + +# The recommended compiler flags for the Raspberry Pi +CXXFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s + +all: $(LIB) + +# Make the library +$(LIB): RF24Network.o Sync.o + g++ -shared -Wl,-soname,$@.so.1 ${CCFLAGS} -o ${LIBNAME} $^ + +clean: + rm -rf *.o ${LIB}.* + +# Install the library to LIBPATH +install: + if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi + install -m 0755 ${LIBNAME} ${LIBDIR} + ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so.1 + ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so + ldconfig + install RF24Network.h RF24Network_config.h $(PREFIX)/include diff --git a/RF24Network.cpp b/RF24Network.cpp index 01386f5..7742bf5 100644 --- a/RF24Network.cpp +++ b/RF24Network.cpp @@ -35,8 +35,6 @@ void RF24Network::begin(uint8_t _channel, uint16_t _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); // Setup our address helper cache setup_address(); @@ -46,9 +44,6 @@ void RF24Network::begin(uint8_t _channel, uint16_t _node_address ) while (i--) radio.openReadingPipe(i,pipe_address(_node_address,i)); radio.startListening(); - - // Spew debugging state about the radio - radio.printDetails(); } /******************************************************************/ @@ -60,7 +55,7 @@ void RF24Network::update(void) while ( radio.isValid() && radio.available(&pipe_num) ) { // Dump the payloads until we've gotten everything - boolean done = false; + bool done = false; while (!done) { // Fetch the payload, and see if this was the last one. @@ -69,8 +64,7 @@ void RF24Network::update(void) // Read the beginning of the frame as the header const RF24NetworkHeader& header = * reinterpret_cast(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(frame_buffer + sizeof(RF24NetworkHeader));printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i)); + on_header(pipe_num, header, frame_buffer); // Throw it away if it's not a valid address if ( !is_valid_address(header.to_node) ) @@ -109,21 +103,14 @@ 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"))); } + on_enqueue(next_frame - frame_queue, result); return result; } @@ -180,7 +167,7 @@ size_t RF24Network::read(RF24NetworkHeader& header,void* message, size_t maxlen) memcpy(message,frame+sizeof(RF24NetworkHeader),bufsize); } - IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Received %s\n\r"),millis(),header.toString())); + on_receive(header); } return bufsize; @@ -198,12 +185,7 @@ bool RF24Network::write(RF24NetworkHeader& header,const void* message, size_t le 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(message);printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i)); - } - + on_send(header, message, len); // If the user is trying to send it to himself if ( header.to_node == node_address ) @@ -250,7 +232,7 @@ bool RF24Network::write(uint16_t 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)); + on_write(to_node, send_node, send_pipe); // First, stop listening so we can talk radio.stopListening(); @@ -298,22 +280,11 @@ bool RF24Network::write_to_pipe( uint16_t node, uint8_t pipe ) } 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),PSTR("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; @@ -369,9 +340,7 @@ void RF24Network::setup_address(void) } 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 + on_setup_address(node_address, node_mask, parent_node, parent_pipe); } /******************************************************************/ @@ -412,7 +381,6 @@ bool is_valid_address( uint16_t node ) if (digit < 1 || digit > 5) { result = false; - printf_P(PSTR("*** WARNING *** Invalid address 0%o\n\r"),node); break; } node >>= 3; @@ -444,8 +412,6 @@ uint64_t pipe_address( uint16_t node, uint8_t pipe ) shift -= 4; } - IF_SERIAL_DEBUG(uint32_t* top = reinterpret_cast(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; } diff --git a/RF24Network.h b/RF24Network.h index 0da9781..2be2aca 100644 --- a/RF24Network.h +++ b/RF24Network.h @@ -58,17 +58,6 @@ struct RF24NetworkHeader * 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; }; /** @@ -80,6 +69,15 @@ struct RF24NetworkHeader class RF24Network { +protected: + // debugging: by default does nothing + virtual void on_header(uint8_t pipe_num, const RF24NetworkHeader &header, uint8_t *frame_buffer) {} + virtual void on_enqueue(size_t frame, bool result) {} + virtual void on_receive(const RF24NetworkHeader& header) {} + virtual void on_send(const RF24NetworkHeader& header, const void *message, size_t len) {} + virtual void on_write(uint16_t to_node, uint16_t send_node, uint8_t send_pipe) {} + virtual void on_setup_address(uint16_t node_address, uint16_t node_mask, uint16_t parent_node, uint16_t parent_pipe) {} + public: /** * Construct the network @@ -181,6 +179,33 @@ class RF24Network uint16_t node_mask; /**< The bits which contain signfificant node address information */ }; +class RF24NetworkDebug: public RF24Network +{ +private: + class Print &_out; + + void print_timed(const char *str); + void print_header(const RF24NetworkHeader &h); + +protected: + void on_header(uint8_t pipe_num, const RF24NetworkHeader &header, uint8_t *frame_buffer); + + void on_enqueue(size_t frame, bool result); + + void on_receive(const RF24NetworkHeader& header); + + virtual void on_send(const RF24NetworkHeader& header, const void *message, size_t len); + + void on_write(uint16_t to_node, uint16_t send_node, uint8_t send_pipe); + + void wrote_pipe(uint8_t out_pipe, bool ok); + + void on_setup_address(uint16_t node_address, uint16_t node_mask, uint16_t parent_node, uint16_t parent_pipe); + +public: + RF24NetworkDebug(class RF24 &radio, Print &out = Serial): RF24Network(radio), _out(out) {} +}; + /** * @example helloworld_tx.pde * diff --git a/RF24NetworkDebug.cpp b/RF24NetworkDebug.cpp new file mode 100644 index 0000000..126eb10 --- /dev/null +++ b/RF24NetworkDebug.cpp @@ -0,0 +1,81 @@ +#include "RF24Network_config.h" +#include "RF24Network.h" + +#if defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) +# define FLASH_PTR(x) ((fstr_t *)x) +#else +# define FLASH_PTR(x) ((const __FlashStringHelper *)x) +#endif + +void RF24NetworkDebug::print_timed(const char *str) +{ + _out.print(millis()); + _out.print(F(": ")); + _out.print(FLASH_PTR(str)); +} + +void RF24NetworkDebug::print_header(const RF24NetworkHeader &h) +{ + _out.print(F("id ")); + _out.print(h.id, HEX); + _out.print(F(" from 0")); + _out.print(h.from_node, OCT); + _out.print(F(" to 0")); + _out.print(h.to_node, OCT); + _out.print(F(" type ")); + _out.print(h.type); +} + +void RF24NetworkDebug::on_header(uint8_t pipe_num, const RF24NetworkHeader &header, uint8_t *frame_buffer) { + print_timed(PSTR("MAC Received on ")); + _out.print(pipe_num, DEC); + _out.print(' '); + print_header(header); + + const uint16_t* i = reinterpret_cast(frame_buffer + sizeof(RF24NetworkHeader)); + print_timed(PSTR("NET message ")); + _out.println(*i, HEX); +} + +void RF24NetworkDebug::on_enqueue(size_t frame, bool result) { + print_timed(PSTR("NET Enqueue ")); + _out.print(frame, HEX); + _out.println(result? F("ok"): F("failed")); +} + +void RF24NetworkDebug::on_receive(const RF24NetworkHeader& header) { + print_timed(PSTR("NET Received ")); + print_header(header); + _out.println(); +} + +void RF24NetworkDebug::on_send(const RF24NetworkHeader& header, const void *message, size_t len) { + print_timed(PSTR("NET Sending ")); + print_header(header); + if (len) { + const uint16_t* i = reinterpret_cast(message); + _out.print(F(" message ")); + _out.print(*i, HEX); + } + _out.println(); +} + +void RF24NetworkDebug::on_write(uint16_t to_node, uint16_t send_node, uint8_t send_pipe) { + print_timed(PSTR("MAC Sending to 0")); + _out.print(to_node, OCT); + _out.print(F(" via 0")); + _out.print(send_node, OCT); + _out.print(F(" on ")); + _out.println(send_pipe, HEX); +} + +void RF24NetworkDebug::on_setup_address(uint16_t node_address, uint16_t node_mask, uint16_t parent_node, uint16_t parent_pipe) { + _out.print(F("setup_address node=0")); + _out.print(node_address, OCT); + _out.print(F(" mask=0")); + _out.print(node_mask, OCT); + _out.print(F(" parent=0")); + _out.print(parent_node, OCT); + _out.print(F(" pipe=")); + _out.print(parent_pipe, HEX); +} diff --git a/RF24Network_config.h b/RF24Network_config.h index 16f5b97..06b3a51 100644 --- a/RF24Network_config.h +++ b/RF24Network_config.h @@ -10,51 +10,39 @@ #ifndef __RF24_CONFIG_H__ #define __RF24_CONFIG_H__ +#ifdef ARDUINO #if ARDUINO < 100 #include #else #include #endif +#endif #include -// Stuff that is normally provided by Arduino -#ifndef ARDUINO -#include -#include -#include -extern HardwareSPI SPI; -#define _BV(x) (1<<(x)) -#endif +#if defined(ARDUINO) -#undef SERIAL_DEBUG -#ifdef SERIAL_DEBUG -#define IF_SERIAL_DEBUG(x) ({x;}) +#if !defined(ENERGIA) +// Progmem is Arduino-specific +#include #else -#define IF_SERIAL_DEBUG(x) +#define prog_char char +#define PSTR(s) (s) +#define __FlashStringHelper char #endif -// Avoid spurious warnings -#if ! defined( NATIVE ) && defined( ARDUINO ) -#undef PROGMEM -#define PROGMEM __attribute__(( section(".progmem.data") )) -#undef PSTR -#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) -#endif - -// Progmem is Arduino-specific -#ifdef ARDUINO -#include -#define PRIPSTR "%S" #else +#include +#include +#include +#define _BV(x) (1<<(x)) typedef char const prog_char; typedef uint16_t prog_uint16_t; #define PSTR(x) (x) -#define printf_P printf #define strlen_P strlen #define PROGMEM #define pgm_read_word(p) (*(p)) -#define PRIPSTR "%s" +#define min(a,b) (a // Framework headers // Library headers -#include +#include "RF24Network_config.h" +#include "RF24Network.h" // Project headers // This component's header -#include +#include "Sync.h" /****************************************************************************/ +// FIXME +#define IF_SERIAL_DEBUG(...) void Sync::update(void) { diff --git a/examples/helloworld_rx/helloworld_rx.pde b/examples/helloworld_rx/helloworld_rx.ino similarity index 82% rename from examples/helloworld_rx/helloworld_rx.pde rename to examples/helloworld_rx/helloworld_rx.ino index 8097462..0e34dd2 100644 --- a/examples/helloworld_rx/helloworld_rx.pde +++ b/examples/helloworld_rx/helloworld_rx.ino @@ -13,15 +13,24 @@ * Listens for messages from the transmitter and prints them out. */ -#include #include #include +#include + +#if defined(ENERGIA) +# define CE P2_1 +# define CS P2_0 +# define BAUD 9600 +#else +# define CE 9 +# define CS 10 +# define BAUD 57600 +#endif -// nRF24L01(+) radio attached using Getting Started board -RF24 radio(9,10); +RF24 radio(CE, CS); // Network uses that radio -RF24Network network(radio); +RF24NetworkDebug network(radio); // Address of our node const uint16_t this_node = 0; @@ -38,7 +47,7 @@ struct payload_t void setup(void) { - Serial.begin(57600); + Serial.begin(BAUD); Serial.println("RF24Network/examples/helloworld_rx/"); SPI.begin(); diff --git a/examples/helloworld_tx/helloworld_tx.pde b/examples/helloworld_tx/helloworld_tx.ino similarity index 83% rename from examples/helloworld_tx/helloworld_tx.pde rename to examples/helloworld_tx/helloworld_tx.ino index 34e1b9a..215d1d2 100644 --- a/examples/helloworld_tx/helloworld_tx.pde +++ b/examples/helloworld_tx/helloworld_tx.ino @@ -13,12 +13,26 @@ * Every 2 seconds, send a payload to the receiver node. */ -#include -#include #include +#include +#include + +#if defined(ENERGIA) +#if defined(__MSP430FR5739__) +# define CE P1_2 +# define CS P1_3 +#elif defined(__MSP430G2553__) +# define CE P2_1 +# define CS P2_0 +#endif +# define BAUD 9600 +#else +# define CE 9 +# define CS 10 +# define BAUD 115200 +#endif -// nRF24L01(+) radio attached using Getting Started board -RF24 radio(9,10); +RF24 radio(CE, CS); // Network uses that radio RF24Network network(radio); @@ -47,7 +61,7 @@ struct payload_t void setup(void) { - Serial.begin(57600); + Serial.begin(BAUD); Serial.println("RF24Network/examples/helloworld_tx/"); SPI.begin();