Skip to content
Browse files

Merge branch 'master' of https://github.com/benlaurie/arduino--

  • Loading branch information...
2 parents 1676e0c + 04a7b50 commit c02f8e20a0b8443c892c272b7e386cb9e58e742d @larsimmisch committed Mar 5, 2012
Showing with 535 additions and 34 deletions.
  1. +1 −1 Makefile
  2. +1 −0 nanode/mac.h
  3. +56 −16 rf12base.h
  4. +18 −11 rf12jeelabs.h
  5. +56 −0 rf12star.h
  6. +6 −0 serial.h
  7. +270 −0 star.h
  8. +22 −6 test_rf12_layered.cc
  9. +51 −0 test_star.cc
  10. +54 −0 test_star_slave.cc
View
2 Makefile
@@ -17,7 +17,7 @@ BIN = blink.bin test_clock.bin test_enc28j60.bin onewire_test.bin test_ip.bin \
test_serial.bin test_rf12.bin test_nanode_mac.bin test_pushbutton.bin \
test_watchdog.bin test_serial.bin test_rf12.bin test_nanode_mac.bin \
test_timer.bin test_onewire_serial.bin blink_nanode.bin \
- test_rf12_layered.bin
+ test_rf12_layered.bin test_star.bin test_star_slave.bin
all: avr-ports.h .depend $(BIN) $(BIN:.bin=.lst) sizes/sizes.html
View
1 nanode/mac.h
@@ -178,6 +178,7 @@ class NanodeMAC
}
operator const byte *() const { return macaddr_; }
bool ok() const { return ok_; }
+ byte length() const { return 6; }
};
byte NanodeMAC::macaddr_[6];
View
72 rf12base.h
@@ -31,6 +31,7 @@
#include <util/crc16.h>
#include "arduino++.h"
+#include "clock16.h"
#include "spi.h"
#define RF12_MAXDATA 66
@@ -99,9 +100,9 @@
// ATmega168, ATmega328, etc.
//#define RFM_IRQ 2
-#define SS_DDR DDRB
-#define SS_PORT PORTB
-#define SS_BIT 2 // for PORTB: 2 = d.10, 1 = d.9, 0 = d.8
+//#define SS_DDR DDRB
+//#define SS_PORT PORTB
+//#define SS_BIT 2 // for PORTB: 2 = d.10, 1 = d.9, 0 = d.8
//#define SPI_SS 10 // PB2, pin 16
#define SPI_MOSI 11 // PB3, pin 17
@@ -129,10 +130,14 @@
#define NODE_ACKANY 0x20 // ack on broadcast packets if set
#define NODE_ID 0x1F // id of this node, as A..Z or 1..31
-template <class RFM_IRQ> class _RF12Base
+template <class RFM_IRQ, class SelectPin> class _RF12Base
{
+ static const uint16_t MIN_SEND_INTERVAL = 500; // in ms.
static volatile uint16_t _crc; // running crc value, should be
// zero at end
+
+ static uint16_t _lastSend;
+
enum BufferOffset
{
GROUP = 0,
@@ -183,6 +188,9 @@ template <class RFM_IRQ> class _RF12Base
// rf12_initialize does it
static void spiInit(void)
{
+ SelectPin::set();
+ SelectPin::modeOutput();
+
// maybe use clk/2 (2x 1/4th) for sending (and clk/8 for recv,
// see rf12_xferSlow)
SPISS::init(0, F_CPU > 10000000);
@@ -267,13 +275,27 @@ template <class RFM_IRQ> class _RF12Base
static byte header() { return _buf[HEADER]; }
static void setHeader(byte hdr) { _buf[HEADER] = hdr; }
static byte length() { return _buf[LENGTH]; }
- static const volatile byte *data() { return &_buf[DATA]; }
+ // This was originally declared volatile, but it is only volatile
+ // if you have a bug, so that has been removed.
+ static const byte *data() { return (byte *)&_buf[DATA]; }
// call this to check whether a new transmission can be started
// returns true when a new transmission may be started with
// rf12_sendStart()
static bool canSend(void)
{
+ // This allows canSend() to be called, even if recvDone() has
+ // already returned true, which previously caused canSend() to
+ // return false.
+ //
+ // FIXME: should the time limit be enforced? According to the
+ // original logic, no, because either it already was, or we're
+ // in TXIDLE because a packet was received, after which it was
+ // allowed to send immediately.
+ if (_rxstate == TXIDLE)
+ return true;
+ if (Clock16::millis() - _lastSend < MIN_SEND_INTERVAL)
+ return false;
// no need to test with interrupts disabled: state TXRECV is
// only reached outside of ISR and we don't care if rxfill
// jumps from 0 to 1 here
@@ -291,13 +313,14 @@ template <class RFM_IRQ> class _RF12Base
return false;
}
- // call this only when rf12_recvDone() or rf12_canSend() return true
+ // call this only when recvDone() or canSend() return true
static void sendStart()
{
_crc = ~0;
_crc = _crc16_update(_crc, _buf[GROUP]);
_rxstate = TXPRE1;
xfer(RF_XMITTER_ON); // bytes will be fed via interrupts
+ _lastSend = Clock16::millis();
}
static void sendStart(const void *ptr, uint8_t len)
@@ -307,6 +330,15 @@ template <class RFM_IRQ> class _RF12Base
sendStart();
}
+ static void clearData()
+ { _buf[LENGTH] = 0; }
+
+ static void writeData(const byte *data, byte length)
+ {
+ memcpy((void *)&_buf[DATA + _buf[LENGTH]], data, length);
+ _buf[LENGTH] += length;
+ }
+
// wait for send to finish, sleep mode: 0=none, 1=idle, 2=standby, 3=powerdown
void rf12_sendWait(uint8_t mode);
@@ -455,11 +487,11 @@ enum rf12DataRates {
Register::SPCR.set(SPR0);
#endif
//bitClear(SS_PORT, SS_BIT);
- Pin::SPI_SS::clear();
+ SelectPin::clear();
uint16_t reply = xferByte(cmd >> 8) << 8;
reply |= xferByte(cmd);
//bitSet(SS_PORT, SS_BIT);
- Pin::SPI_SS::set();
+ SelectPin::set();
#if F_CPU > 10000000
//bitClear(SPCR, SPR0);
//SPCR &= ~(1 << SPR0);
@@ -473,11 +505,11 @@ enum rf12DataRates {
#if OPTIMIZE_SPI
// writing can take place at full speed, even 8 MHz works
//bitClear(SS_PORT, SS_BIT);
- Pin::SPI_SS::clear();
+ SelectPin::clear();
xferByte(cmd >> 8);
xferByte(cmd);
//bitSet(SS_PORT, SS_BIT);
- Pin::SPI_SS::set();
+ SelectPin::set();
#else
xferSlow(cmd);
#endif
@@ -496,11 +528,19 @@ enum rf12DataRates {
};
-template <class RFM_IRQ> volatile byte _RF12Base<RFM_IRQ>::_buf[RF_MAX];
-template <class RFM_IRQ> volatile byte _RF12Base<RFM_IRQ>::_rxfill;
-template <class RFM_IRQ> volatile uint16_t _RF12Base<RFM_IRQ>::_crc;
-template <class RFM_IRQ> byte _RF12Base<RFM_IRQ>::_group;
-template <class RFM_IRQ> volatile int8_t _RF12Base<RFM_IRQ>::_rxstate;
-template <class RFM_IRQ> void (*_RF12Base<RFM_IRQ>::_crypter)(byte);
+template <class RFM_IRQ, class SelectPin>
+ uint16_t _RF12Base<RFM_IRQ, SelectPin>::_lastSend;
+template <class RFM_IRQ, class SelectPin>
+ volatile byte _RF12Base<RFM_IRQ, SelectPin>::_buf[RF_MAX];
+template <class RFM_IRQ, class SelectPin>
+ volatile byte _RF12Base<RFM_IRQ, SelectPin>::_rxfill;
+template <class RFM_IRQ, class SelectPin>
+ volatile uint16_t _RF12Base<RFM_IRQ, SelectPin>::_crc;
+template <class RFM_IRQ, class SelectPin>
+ byte _RF12Base<RFM_IRQ, SelectPin>::_group;
+template <class RFM_IRQ, class SelectPin>
+ volatile int8_t _RF12Base<RFM_IRQ, SelectPin>::_rxstate;
+template <class RFM_IRQ, class SelectPin>
+ void (*_RF12Base<RFM_IRQ, SelectPin>::_crypter)(byte);
#endif
View
29 rf12jeelabs.h
@@ -48,7 +48,8 @@
#define RF12_HDR_ACK 0x20
#define RF12_HDR_MASK 0x1F
-template <class RFM_IRQ> class RF12BJeelabs : public _RF12Base<RFM_IRQ>
+template <class RFM_IRQ, class SelectPin> class RF12BJeelabs
+ : public _RF12Base<RFM_IRQ, SelectPin>
{
static uint8_t _nodeid; // address of this node
static long _seq; // seq number of encrypted packet (or -1)
@@ -63,17 +64,19 @@ template <class RFM_IRQ> class RF12BJeelabs : public _RF12Base<RFM_IRQ>
static void init(uint8_t id, uint8_t band, uint8_t group = 0xD4)
{
_nodeid = id;
- _RF12Base<RFM_IRQ>::init(band, (_nodeid & NODE_ID) != 0, group);
+ _RF12Base<RFM_IRQ, SelectPin>::init(band, (_nodeid & NODE_ID) != 0,
+ group);
}
- static byte header() { return _RF12Base<RFM_IRQ>::header(); }
- static void setHeader(byte hdr) { _RF12Base<RFM_IRQ>::setHeader(hdr); }
- static bool goodCRC() { return _RF12Base<RFM_IRQ>::goodCRC(); }
+ static byte header() { return _RF12Base<RFM_IRQ, SelectPin>::header(); }
+ static void setHeader(byte hdr)
+ { _RF12Base<RFM_IRQ, SelectPin>::setHeader(hdr); }
+ static bool goodCRC() { return _RF12Base<RFM_IRQ, SelectPin>::goodCRC(); }
// call this frequently, returns true if a packet has been received
static bool recvDone(void)
{
- if (!_RF12Base<RFM_IRQ>::recvDone())
+ if (!_RF12Base<RFM_IRQ, SelectPin>::recvDone())
return false;
if (!(header() & RF12_HDR_DST) || (_nodeid & NODE_ID) == 31 ||
(header() & RF12_HDR_MASK) == (_nodeid & NODE_ID))
@@ -120,17 +123,21 @@ template <class RFM_IRQ> class RF12BJeelabs : public _RF12Base<RFM_IRQ>
(hdr & ~RF12_HDR_MASK) + (_nodeid & NODE_ID));
if (_crypter != 0)
_crypter(1);
- _RF12Base<RFM_IRQ>::sendStart(ptr, len);
+ _RF12Base<RFM_IRQ, SelectPin>::sendStart(ptr, len);
}
};
-template <class RFM_IRQ> byte RF12BJeelabs<RFM_IRQ>::_nodeid;
-template <class RFM_IRQ> long RF12BJeelabs<RFM_IRQ>::_seq;
-template <class RFM_IRQ> void (*RF12BJeelabs<RFM_IRQ>::_crypter)(byte);
+template <class RFM_IRQ, class SelectPin>
+ byte RF12BJeelabs<RFM_IRQ, SelectPin>::_nodeid;
+template <class RFM_IRQ, class SelectPin>
+ long RF12BJeelabs<RFM_IRQ, SelectPin>::_seq;
+template <class RFM_IRQ, class SelectPin>
+ void (*RF12BJeelabs<RFM_IRQ, SelectPin>::_crypter)(byte);
// Setup for Jeenodes and Wi/Nanodes.
-typedef RF12BJeelabs<Pin::D2> RF12B;
+typedef RF12BJeelabs<Pin::D2, Pin::B2> RF12B;
+// FIXME: this should be in rf12base.
SIGNAL(INT0_vect)
{
RF12B::interrupt();
View
56 rf12star.h
@@ -0,0 +1,56 @@
+#include "rf12base.h"
+#include "star.h"
+
+typedef _RF12Base<Pin::D2, Pin::B2> RF12B;
+
+class RF12Star : RF12B // not public, we want to hide it
+ {
+public:
+ static void init()
+ {
+ // Disable other SPI devices on the Nanode
+ // FIXME: framework should take care of this
+ // ENC28J60
+ Pin::B0::set();
+ Pin::B0::modeOutput();
+ // 23K256
+ Pin::B1::set();
+ Pin::B1::modeOutput();
+ RF12B::init(MHZ868, true);
+ }
+ // This will not be called again until the available data has been
+ // processed. Data should not change until it has been called
+ // again.
+ static bool dataAvailable()
+ { return recvDone() && goodCRC(); }
+ static byte getID()
+ { return data()[0]; }
+ // Retrieve the type field from the current received packet.
+ static byte getType()
+ { return header(); }
+ // Retrieve the length of the data in the current received packet.
+ static byte getLength()
+ { return length() - 1; }
+ // Retrieve a copy of the received data. This must be constant
+ // until dataAvailable() is called again.
+ static const byte *getData()
+ { return data() + 1; }
+ // Can we send a packet?
+ static bool canSend()
+ { return RF12B::canSend(); }
+ // Send a packet. Only call if canSend() returns true.
+ static void sendPacket(byte id, byte type, byte length, const byte *data)
+ {
+ setHeader(type);
+ clearData();
+ writeData(&id, 1);
+ writeData(data, length);
+ sendStart();
+ }
+ };
+
+// FIXME: this should be in rf12base.
+SIGNAL(INT0_vect)
+ {
+ RF12B::interrupt();
+ }
View
6 serial.h
@@ -1,3 +1,4 @@
+// -*- mode: c++; indent-tabs-mode: nil; -*-
/*
HardwareSerial.cpp - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
@@ -22,6 +23,9 @@
Modified 5 February 2012 by Lars Immisch (template remix)
*/
+#ifndef SERIAL_H
+#define SERIAL_H
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -224,3 +228,5 @@ SIGNAL(USART_RX_vect)
}
#endif
+
+#endif // ndef SERIAL_H
View
270 star.h
@@ -0,0 +1,270 @@
+// -*- mode: c++; indent-tabs-mode: nil; -*-
+
+/*
+ * There is one master and up to 256 slaves. Slaves can only send to
+ * the master.
+ *
+ * The contents are:
+ *
+ * byte ID;
+ * byte TYPE;
+ * byte LENGTH;
+ * byte MESSAGE[LENGTH];
+ *
+ * When sent by a slave, ID is the id of the sender, if they have
+ * one. When sent by the master, it is the id of the recipient.
+ *
+ * Request ID (Slave Type 0):
+ *
+ * ID = 0. Note that id 0 is a valid id!
+ *
+ * MESSAGE is the MAC of the sender. It can be any length > 0. Two
+ * slaves should not have the same MAC! Note that the master may
+ * impose a limit on MAC length, in which case it will not respond
+ * to a MAC that is too long. A MAC of up to 8 bytes is always
+ * acceptable.
+ *
+ * The response is an Allocate ID packet.
+ *
+ * This message must be resent periodically until a response is
+ * received. No other message type can be send until an ID is
+ * allocated.
+ *
+ *
+ * Allocate ID (Master Type 0):
+ *
+ * ID = allocated id.
+ *
+ * MESSAGE is the MAC of the requestor.
+ *
+ *
+ * Out of IDs Error (Master Type 1):
+ *
+ * ID = 0
+ *
+ * MESSAGE = MAC of the requestor.
+ *
+ * Presumably the slave should give some kind of visual indication
+ * if it gets this error. It can retry in case the master changes
+ * its mind.
+ *
+ */
+
+#include "arduino++.h"
+#include "serial.h" // debug
+
+#include <string.h>
+
+class StarBase
+ {
+protected:
+ enum MessageType
+ {
+ // Slave
+ REQUEST_ID = 0x00,
+
+ // Master
+ ALLOCATE_ID = 0x40,
+ OUT_OF_IDS = 0x41,
+ RESET_ID = 0x42,
+ };
+ enum MasterType
+ {
+ };
+ static uint32_t protocolError_;
+ };
+
+template <class Network, class Observer> class StarNode : public StarBase
+ {
+protected:
+ static void sendPacket(byte id, byte type, byte length, const byte *data)
+ {
+ Serial.write('P');
+ if (!Network::canSend())
+ {
+ Observer::cantSend();
+ return;
+ }
+ Network::sendPacket(id, type, length, data);
+ Serial.write('Z');
+ Observer::sentPacket(id, type, length, data);
+ Serial.write('W');
+ }
+ };
+
+template <class Network, class Observer> class StarSlave
+ : public StarNode<Network, Observer>
+ {
+public:
+ // Note that this just keeps a pointer, so you need to make sure
+ // |mac| stays around.
+ static void init(const byte *mac, byte length)
+ {
+ mac_ = mac;
+ length_ = length;
+ Network::init();
+ }
+ static void poll()
+ {
+ if (Network::dataAvailable())
+ processPacket();
+ if (!idSet_)
+ {
+ getID();
+ return;
+ }
+ }
+private:
+ static void processPacket()
+ {
+ Serial.write('A');
+ switch (Network::getType())
+ {
+ case StarBase::ALLOCATE_ID:
+ Serial.write('C');
+ if (Network::getLength() != length_)
+ // Can't be us.
+ break;
+ {
+ const byte *data = Network::getData();
+ // our ID may have come back
+ for (byte n = 0; n < length_; ++n)
+ if (data[n] != mac_[n])
+ return;
+ }
+ id_ = Network::getID();
+ idSet_ = true;
+ break;
+
+ case StarBase::RESET_ID:
+ idSet_ = false;
+ break;
+ }
+ }
+
+ static void getID()
+ {
+ // try (or retry) to get an ID
+ StarNode<Network, Observer>::sendPacket(0, StarBase::REQUEST_ID,
+ length_, mac_);
+ }
+
+ static byte id_;
+ static bool idSet_;
+ static const byte *mac_;
+ static byte length_;
+ };
+
+template <class Network, class Observer> class StarMaster
+ : public StarNode<Network, Observer>
+ {
+public:
+ static void init()
+ {
+ Network::init();
+ resetCount_ = 5;
+ }
+ static void poll()
+ {
+ if (Network::dataAvailable())
+ processPacket();
+ if (resetCount_ > 0)
+ {
+ Serial.write('X');
+ if (!Network::canSend())
+ return;
+ Serial.write('Y');
+ StarNode<Network, Observer>::sendPacket(0, StarBase::RESET_ID, 0,
+ NULL);
+ --resetCount_;
+ return;
+ }
+ }
+ static void processPacket()
+ {
+ Observer::gotPacket(Network::getID(), Network::getType(),
+ Network::getLength(), Network::getData());
+
+ switch (Network::getType())
+ {
+ case StarBase::REQUEST_ID:
+ allocateID();
+ break;
+
+ default:
+ ++StarBase::protocolError_;
+ break;
+ }
+ }
+private:
+ static void allocateID()
+ {
+ if (Network::getLength() > Mac::MAX_MAC)
+ {
+ ++StarBase::protocolError_;
+ return;
+ }
+ byte empty = 0;
+ for (byte n = 0; n < NMACS ; )
+ {
+ if (macs_[n].length() == 0)
+ empty = n;
+ else if (macs_[n].is(Network::getLength(), Network::getData()))
+ {
+ macs_[n].sendID(n);
+ return;
+ }
+ if (++n == 0)
+ break;
+ }
+ if (macs_[empty].length() != 0)
+ {
+ sendPacket(0, StarBase::OUT_OF_IDS, Network::getLength(),
+ Network::getData());
+ return;
+ }
+ macs_[empty].set(Network::getLength(), Network::getData());
+ macs_[empty].sendID(empty);
+ }
+
+ static const byte NMACS = 8;
+ class Mac
+ {
+ public:
+ byte length() const { return length_; }
+ bool is(const byte length, const byte *mac)
+ { return length == length_ && memcmp(mac, mac_, length) == 0; }
+ void set(byte length, const byte *mac)
+ {
+ length_ = length;
+ memcpy(mac_, mac, length_);
+ }
+ void sendID(byte id)
+ {
+ StarMaster::sendPacket(id, StarBase::ALLOCATE_ID, length_, mac_);
+ Observer::idSent(id, length_, mac_);
+ }
+ static const byte MAX_MAC = 8;
+ private:
+ byte length_;
+ byte mac_[MAX_MAC];
+ };
+
+ static Mac macs_[NMACS];
+ static byte resetCount_;
+ };
+
+
+uint32_t StarBase::protocolError_;
+template <class Network, class Observer>
+ typename StarMaster<Network, Observer>::Mac
+ StarMaster<Network, Observer>::macs_[StarMaster<Network, Observer>::NMACS];
+template <class Network, class Observer>
+ byte StarMaster<Network, Observer>::resetCount_;
+template <class Network, class Observer>
+ bool StarSlave<Network, Observer>::idSet_;
+template <class Network, class Observer> byte StarSlave<Network, Observer>::id_;
+template <class Network, class Observer>
+ byte StarSlave<Network, Observer>::length_;
+template <class Network, class Observer>
+ const byte *StarSlave<Network, Observer>::mac_;
View
28 test_rf12_layered.cc
@@ -23,8 +23,8 @@ void get_mcusr(void)
#endif
// You need to set these the other way round for the second test node.
-static const byte id = 1;
-static const byte dest = 2;
+static const byte id = 2;
+static const byte dest = 1;
int main()
{
@@ -47,6 +47,8 @@ int main()
#ifdef WATCHDOG
wdt_enable(WDTO_2S);
#endif
+ uint32_t count = 0;
+ bool wantsAck = false;
for ( ; ; )
{
#ifdef WATCHDOG
@@ -57,6 +59,15 @@ int main()
if (t - last > 100 && RF12B::canSend())
{
last = t;
+ if (wantsAck)
+ {
+ RF12B::sendAckReply();
+ Serial.write('a');
+ wantsAck = false;
+ continue;
+ }
+ if (count % 3 != 0)
+ continue;
char buf[2];
buf[0] = id;
buf[1] = ++seq;
@@ -65,6 +76,14 @@ int main()
Serial.write('s');
Serial.writeHex(RF12B::header());
}
+ else if (++count == 100000)
+ {
+ count = 0;
+ Serial.write('X');
+ Serial.writeDecimal(t);
+ Serial.write(':');
+ Serial.writeDecimal(last);
+ }
if (RF12B::recvDone())
{
@@ -82,10 +101,7 @@ int main()
Serial.write(RF12B::data()[0] + '0');
Serial.writeHex(RF12B::data()[1]);
if (RF12B::wantsAck())
- {
- RF12B::sendAckReply();
- Serial.write('a');
- }
+ wantsAck = true;
}
}
}
View
51 test_star.cc
@@ -0,0 +1,51 @@
+#include "arduino++.h"
+#include "rf12star.h"
+#include "serial.h"
+
+class SerialObserver
+ {
+public:
+ static void cantSend() { Serial.write('.'); }
+ static void gotPacket(byte id, byte type, byte length, const byte *data)
+ {
+ Serial.write("Got packet, id: ");
+ Serial.writeDecimal(id);
+ Serial.write(" type: ");
+ Serial.writeDecimal(type);
+ Serial.write(" data: ");
+ Serial.writeHex(data, length);
+ Serial.write("\r\n");
+ }
+ static void idSent(byte id, byte length, const byte *mac)
+ {
+ Serial.write("ID sent, id: ");
+ Serial.writeDecimal(id);
+ Serial.write(" mac: ");
+ Serial.writeHex(mac, length);
+ Serial.write("\r\n");
+ }
+ static void sentPacket(byte id, byte type, byte length, const byte *data)
+ {
+ Serial.write("Sent packet, id: ");
+ Serial.writeDecimal(id);
+ Serial.write(" type: ");
+ Serial.writeDecimal(type);
+ Serial.write(" data: ");
+ Serial.writeHex(data, length);
+ Serial.write("\r\n");
+ }
+ };
+
+StarMaster<RF12Star, SerialObserver> master;
+
+int main()
+ {
+ Arduino::init();
+ Serial.begin(57600);
+ master.init();
+
+ Serial.write("Start\r\n");
+
+ for ( ; ; )
+ master.poll();
+ }
View
54 test_star_slave.cc
@@ -0,0 +1,54 @@
+// -*- mode: c++; indent-tabs-mode: nil; -*-
+
+#include "nanode/mac.h"
+#include "serial.h"
+#include "rf12star.h"
+
+class SerialObserver
+ {
+public:
+ static void cantSend() { Serial.write('.'); }
+ static void gotPacket(byte id, byte type, byte length, const byte *data)
+ {
+ Serial.write("Got packet, id: ");
+ Serial.writeDecimal(id);
+ Serial.write(" type: ");
+ Serial.writeDecimal(type);
+ Serial.write(" data: ");
+ Serial.writeHex(data, length);
+ Serial.write("\r\n");
+ }
+ static void sentPacket(byte id, byte type, byte length, const byte *data)
+ {
+ Serial.write("Sent packet, id: ");
+ Serial.writeDecimal(id);
+ Serial.write(" type: ");
+ Serial.writeDecimal(type);
+ Serial.write(" data: ");
+ Serial.writeHex(data, length);
+ Serial.write("\r\n");
+ }
+ };
+
+//static NanodeMAC mac;
+
+int main()
+ {
+ Arduino::init();
+ Serial.begin(57600);
+ //Serial.write(mac.ok() ? 'G' : 'B');
+ //for (byte n = 0; n < 6; ++n)
+ //Serial.writeHex(mac[n]);
+ //if (!mac.ok())
+ //return 1;
+
+ StarSlave<RF12Star, SerialObserver> slave;
+ static byte mac[3] = { 1, 2, 3 };
+ //slave.setMac(mac, mac.length());
+ slave.init(mac, sizeof mac);
+
+ for ( ; ; )
+ slave.poll();
+
+ return 0;
+ }

0 comments on commit c02f8e2

Please sign in to comment.
Something went wrong with that request. Please try again.