Library for HopeRF RFM22 transceiver module ported to mbed. Original Software from Mike McCauley (mikem@open.com.au) . See http://www.open.com.au/mikem/arduino/RF22/

Fork of RF22 by Karl Zweimüller

Committer:
floha
Date:
Thu Aug 29 21:57:14 2013 +0000
Revision:
9:46fb41f4259d
Parent:
5:0386600f3408
changed the LED default numbers in the RF22 constructor as the former values interfered with pins used on an KL25Z board. The library didn't work with those.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charly 0:79c6d0071c4c 1 // RF22ReliableDatagram.h
charly 0:79c6d0071c4c 2 //
charly 0:79c6d0071c4c 3 // Author: Mike McCauley (mikem@open.com.au)
charly 0:79c6d0071c4c 4 // Copyright (C) 2011 Mike McCauley
charly 5:0386600f3408 5 // $Id: RF22ReliableDatagram.h,v 1.7 2012/05/30 01:51:25 mikem Exp $
charly 0:79c6d0071c4c 6 // ported to mbed by Karl Zweimueller
charly 0:79c6d0071c4c 7
charly 0:79c6d0071c4c 8 #ifndef RF22ReliableDatagram_h
charly 0:79c6d0071c4c 9 #define RF22ReliableDatagram_h
charly 0:79c6d0071c4c 10
charly 0:79c6d0071c4c 11 #include <RF22Datagram.h>
charly 0:79c6d0071c4c 12
charly 0:79c6d0071c4c 13 // The acknowledgement bit in the FLAGS
charly 0:79c6d0071c4c 14 #define RF22_FLAGS_ACK 0x80
charly 0:79c6d0071c4c 15
charly 0:79c6d0071c4c 16 /////////////////////////////////////////////////////////////////////
charly 0:79c6d0071c4c 17 /// \class RF22ReliableDatagram RF22ReliableDatagram.h <RF22ReliableDatagram.h>
charly 0:79c6d0071c4c 18 /// \brief RF22 subclass for sending addressed, acknowledged, retransmitted datagrams.
charly 0:79c6d0071c4c 19 ///
charly 0:79c6d0071c4c 20 /// Extends RF22Datagram to define addressed, reliable datagrams with acknowledgement and retransmission.
charly 0:79c6d0071c4c 21 /// Based on RF22Datagram, adds flags and sequence numbers. RF22ReliableDatagram is reliable in the sense
charly 0:79c6d0071c4c 22 /// that messages are acknowledged, and unacknowledged messages are retransmitted until acknowledged or the
charly 0:79c6d0071c4c 23 /// retries are exhausted.
charly 0:79c6d0071c4c 24 /// When addressed messages are sent (by sendtoWait()), it will wait for an ack, and retransmit
charly 0:79c6d0071c4c 25 /// after timeout until an ack is received or retries are exhausted.
charly 0:79c6d0071c4c 26 /// When addressed messages are collected by the application (by recvfromAck()),
charly 0:79c6d0071c4c 27 /// an acknowledgement is automatically sent.
charly 0:79c6d0071c4c 28 ///
charly 0:79c6d0071c4c 29 /// The retransmit timeout is randomly varied between timeout and timeout*2 to prevent collisions on all
charly 0:79c6d0071c4c 30 /// retries when 2 nodes happen to start sending at the same time .
charly 0:79c6d0071c4c 31 ///
charly 0:79c6d0071c4c 32 /// Each new message sent by sendtoWait() has its ID incremented.
charly 0:79c6d0071c4c 33 ///
charly 0:79c6d0071c4c 34 /// An ack consists of a message with:
charly 0:79c6d0071c4c 35 /// - TO set to the from address of the original message
charly 0:79c6d0071c4c 36 /// - FROM set to this node address
charly 0:79c6d0071c4c 37 /// - ID set to the ID of the original message
charly 0:79c6d0071c4c 38 /// - FLAGS with the RF22_FLAGS_ACK bit set
charly 0:79c6d0071c4c 39 ///
charly 0:79c6d0071c4c 40 /// Part of the Arduino RF22 library for operating with HopeRF RF22 compatible transceivers
charly 0:79c6d0071c4c 41 /// (see http://www.hoperf.com)
charly 0:79c6d0071c4c 42 class RF22ReliableDatagram : public RF22Datagram
charly 0:79c6d0071c4c 43 {
charly 0:79c6d0071c4c 44 public:
charly 0:79c6d0071c4c 45 /// Constructor.
charly 0:79c6d0071c4c 46 /// \param[in] thisAddress The address to assign to this node. Defaults to 0
charly 0:79c6d0071c4c 47 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF22 before
charly 5:0386600f3408 48 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega)
charly 0:79c6d0071c4c 49 /// \param[in] interrupt The interrupt number to use. Default is interrupt 0 (Arduino input pin 2)
charly 0:79c6d0071c4c 50 RF22ReliableDatagram(uint8_t thisAddress ,PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt );
charly 0:79c6d0071c4c 51
charly 0:79c6d0071c4c 52 /// Sets the minimum retransmit timeout. If sendtoWait is waiting for an ack
charly 0:79c6d0071c4c 53 /// longer than this time (in milliseconds),
charly 0:79c6d0071c4c 54 /// it will retransmit the message. Defaults to 200ms. The timeout is measured from the end of
charly 0:79c6d0071c4c 55 /// transmission of the message. It must be at least longer than the the transmit
charly 5:0386600f3408 56 /// time of the acknowledgement (preamble+6 octets) plus the latency/poll time of the receiver.
charly 5:0386600f3408 57 /// For fast modulation schemes you can considerably shorten this time.
charly 0:79c6d0071c4c 58 /// The actual timeout is randomly varied between timeout and timeout*2.
charly 0:79c6d0071c4c 59 /// \param[in] timeout The new timeout period in milliseconds
charly 0:79c6d0071c4c 60 void setTimeout(uint16_t timeout);
charly 0:79c6d0071c4c 61
charly 0:79c6d0071c4c 62 /// Sets the max number of retries. Defaults to 3. If set to 0, the message will only be sent once.
charly 0:79c6d0071c4c 63 /// sendtoWait will give up and return false if there is no ack received after all transmissions time out.
charly 0:79c6d0071c4c 64 /// param[in] retries The maximum number a retries.
charly 0:79c6d0071c4c 65 void setRetries(uint8_t retries);
charly 0:79c6d0071c4c 66
charly 0:79c6d0071c4c 67 /// Send the message and waits for an ack. Returns true if an acknowledgement is received.
charly 0:79c6d0071c4c 68 /// Synchronous: any message other than the desired ACK received while waiting is discarded.
charly 0:79c6d0071c4c 69 /// Blocks until an ACK is received or all retries are exhausted (ie up to retries*timeout milliseconds).
charly 0:79c6d0071c4c 70 /// \param[in] address The address to send the message to.
charly 0:79c6d0071c4c 71 /// \param[in] buf Pointer to the binary message to send
charly 0:79c6d0071c4c 72 /// \param[in] len Number of octets to send
charly 0:79c6d0071c4c 73 /// \return true if the message was transmitted and an acknowledgement was received.
charly 0:79c6d0071c4c 74 boolean sendtoWait(uint8_t* buf, uint8_t len, uint8_t address);
charly 0:79c6d0071c4c 75
charly 0:79c6d0071c4c 76 /// If there is a valid message available for this node, send an acknowledgement to the SRC
charly 0:79c6d0071c4c 77 /// address (blocking until this is complete), then copy the message to buf and return true
charly 0:79c6d0071c4c 78 /// else return false.
charly 0:79c6d0071c4c 79 /// If a message is copied, *len is set to the length..
charly 0:79c6d0071c4c 80 /// If from is not NULL, the SRC address is placed in *from.
charly 0:79c6d0071c4c 81 /// If to is not NULL, the DEST address is placed in *to.
charly 0:79c6d0071c4c 82 /// This is the preferred function for getting messages addressed to this node.
charly 0:79c6d0071c4c 83 /// If the message is not a broadcast, acknowledge to the sender before returning.
charly 0:79c6d0071c4c 84 /// You should be sure to call this function frequently enough to not miss any messages
charly 0:79c6d0071c4c 85 /// It is recommended that you call it in your main loop.
charly 0:79c6d0071c4c 86 /// \param[in] buf Location to copy the received message
charly 0:79c6d0071c4c 87 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
charly 0:79c6d0071c4c 88 /// \param[in] from If present and not NULL, the referenced uint8_t will be set to the SRC address
charly 0:79c6d0071c4c 89 /// \param[in] to If present and not NULL, the referenced uint8_t will be set to the DEST address
charly 0:79c6d0071c4c 90 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
charly 0:79c6d0071c4c 91 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
charly 0:79c6d0071c4c 92 /// (not just those addressed to this node).
charly 0:79c6d0071c4c 93 /// \return true if a valid message was copied to buf
charly 0:79c6d0071c4c 94 boolean recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* from = NULL, uint8_t* to = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
charly 0:79c6d0071c4c 95
charly 0:79c6d0071c4c 96 /// Similar to recvfromAck(), this will block until either a valid message available for this node
charly 0:79c6d0071c4c 97 /// or the timeout expires. Starts the receiver automatically.
charly 0:79c6d0071c4c 98 /// You should be sure to call this function frequently enough to not miss any messages
charly 0:79c6d0071c4c 99 /// It is recommended that you call it in your main loop.
charly 0:79c6d0071c4c 100 /// \param[in] buf Location to copy the received message
charly 0:79c6d0071c4c 101 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
charly 0:79c6d0071c4c 102 /// \param[in] timeout Maximum time to wait in milliseconds
charly 0:79c6d0071c4c 103 /// \param[in] from If present and not NULL, the referenced uint8_t will be set to the SRC address
charly 0:79c6d0071c4c 104 /// \param[in] to If present and not NULL, the referenced uint8_t will be set to the DEST address
charly 0:79c6d0071c4c 105 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
charly 0:79c6d0071c4c 106 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
charly 0:79c6d0071c4c 107 /// (not just those addressed to this node).
charly 0:79c6d0071c4c 108 /// \return true if a valid message was copied to buf
charly 0:79c6d0071c4c 109 boolean recvfromAckTimeout(uint8_t* buf, uint8_t* len, uint16_t timeout, uint8_t* from = NULL, uint8_t* to = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
charly 0:79c6d0071c4c 110
charly 0:79c6d0071c4c 111 /// Returns the number of retransmissions
charly 0:79c6d0071c4c 112 /// we have had to send
charly 0:79c6d0071c4c 113 /// \return The number of retransmissions since initialisation.
charly 0:79c6d0071c4c 114 uint16_t retransmissions();
charly 0:79c6d0071c4c 115
charly 0:79c6d0071c4c 116 protected:
charly 0:79c6d0071c4c 117 /// Send an ACK for the message id to the given from address
charly 0:79c6d0071c4c 118 /// Blocks until the ACK has been sent
charly 0:79c6d0071c4c 119 void acknowledge(uint8_t id, uint8_t from);
charly 0:79c6d0071c4c 120
charly 0:79c6d0071c4c 121 /// Checks whether the message currently in the Rx buffer is a new message, not previously received
charly 0:79c6d0071c4c 122 /// based on the from address and the sequence. If it is new, it is acknowledged and returns true
charly 0:79c6d0071c4c 123 /// \return true if there is a message received and it is a new message
charly 0:79c6d0071c4c 124 boolean haveNewMessage();
charly 0:79c6d0071c4c 125
charly 0:79c6d0071c4c 126 private:
charly 0:79c6d0071c4c 127 /// Count of retransmissions we have had to send
charly 0:79c6d0071c4c 128 uint16_t _retransmissions;
charly 0:79c6d0071c4c 129
charly 0:79c6d0071c4c 130 /// The last sequence number to be used
charly 0:79c6d0071c4c 131 /// Defaults to 0
charly 0:79c6d0071c4c 132 uint8_t _lastSequenceNumber;
charly 0:79c6d0071c4c 133
charly 0:79c6d0071c4c 134 // Retransmit timeout (milliseconds)
charly 0:79c6d0071c4c 135 /// Defaults to 200
charly 0:79c6d0071c4c 136 uint16_t _timeout;
charly 0:79c6d0071c4c 137
charly 0:79c6d0071c4c 138 // Retries (0 means one try only)
charly 0:79c6d0071c4c 139 /// Defaults to 3
charly 0:79c6d0071c4c 140 uint8_t _retries;
charly 0:79c6d0071c4c 141
charly 0:79c6d0071c4c 142 /// Array of the last seen sequence number indexed by node address that sent it
charly 0:79c6d0071c4c 143 /// It is used for duplicate detection. Duplicated messages are re-acknowledged when received
charly 0:79c6d0071c4c 144 /// (this is generally due to lost ACKs, causing the sender to retransmit, even though we have already
charly 0:79c6d0071c4c 145 /// received that message)
charly 0:79c6d0071c4c 146 uint8_t _seenIds[256];
charly 0:79c6d0071c4c 147
charly 0:79c6d0071c4c 148
charly 0:79c6d0071c4c 149 };
charly 0:79c6d0071c4c 150
charly 0:79c6d0071c4c 151 #endif