This driver is a stripped down version of the Radiohead 1.45 driver, and covers fewer radios. Threading and an event queue have been added to make the ISR's more stable across architectures. Specifically The STM32L4 parts

Dependents:   Threaded_LoRa_Modem

Committer:
davidr99
Date:
Thu Oct 15 01:27:00 2015 +0000
Revision:
0:ab4e012489ef
Messy start, but a port for RadioHead.; Currently the SPI modulus are the only ones that work.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 0:ab4e012489ef 1 // RHGenericDriver.h
davidr99 0:ab4e012489ef 2 // Author: Mike McCauley (mikem@airspayce.com)
davidr99 0:ab4e012489ef 3 // Copyright (C) 2014 Mike McCauley
davidr99 0:ab4e012489ef 4 // $Id: RHGenericDriver.h,v 1.16 2015/01/02 21:38:24 mikem Exp $
davidr99 0:ab4e012489ef 5
davidr99 0:ab4e012489ef 6 #ifndef RHGenericDriver_h
davidr99 0:ab4e012489ef 7 #define RHGenericDriver_h
davidr99 0:ab4e012489ef 8
davidr99 0:ab4e012489ef 9 #include <RadioHead.h>
davidr99 0:ab4e012489ef 10
davidr99 0:ab4e012489ef 11 // Defines bits of the FLAGS header reserved for use by the RadioHead library and
davidr99 0:ab4e012489ef 12 // the flags available for use by applications
davidr99 0:ab4e012489ef 13 #define RH_FLAGS_RESERVED 0xf0
davidr99 0:ab4e012489ef 14 #define RH_FLAGS_APPLICATION_SPECIFIC 0x0f
davidr99 0:ab4e012489ef 15 #define RH_FLAGS_NONE 0
davidr99 0:ab4e012489ef 16
davidr99 0:ab4e012489ef 17 /////////////////////////////////////////////////////////////////////
davidr99 0:ab4e012489ef 18 /// \class RHGenericDriver RHGenericDriver.h <RHGenericDriver.h>
davidr99 0:ab4e012489ef 19 /// \brief Abstract base class for a RadioHead driver.
davidr99 0:ab4e012489ef 20 ///
davidr99 0:ab4e012489ef 21 /// This class defines the functions that must be provided by any RadioHead driver.
davidr99 0:ab4e012489ef 22 /// Different types of driver will implement all the abstract functions, and will perhaps override
davidr99 0:ab4e012489ef 23 /// other functions in this subclass, or perhaps add new functions specifically required by that driver.
davidr99 0:ab4e012489ef 24 /// Do not directly instantiate this class: it is only to be subclassed by driver classes.
davidr99 0:ab4e012489ef 25 ///
davidr99 0:ab4e012489ef 26 /// Subclasses are expected to implement a half-duplex, unreliable, error checked, unaddressed packet transport.
davidr99 0:ab4e012489ef 27 /// They are expected to carry a message payload with an appropriate maximum length for the transport hardware
davidr99 0:ab4e012489ef 28 /// and to also carry unaltered 4 message headers: TO, FROM, ID, FLAGS
davidr99 0:ab4e012489ef 29 ///
davidr99 0:ab4e012489ef 30 /// \par Headers
davidr99 0:ab4e012489ef 31 ///
davidr99 0:ab4e012489ef 32 /// Each message sent and received by a RadioHead driver includes 4 headers:
davidr99 0:ab4e012489ef 33 /// -TO The node address that the message is being sent to (broadcast RH_BROADCAST_ADDRESS (255) is permitted)
davidr99 0:ab4e012489ef 34 /// -FROM The node address of the sending node
davidr99 0:ab4e012489ef 35 /// -ID A message ID, distinct (over short time scales) for each message sent by a particilar node
davidr99 0:ab4e012489ef 36 /// -FLAGS A bitmask of flags. The most significant 4 bits are reserved for use by RadioHead. The least
davidr99 0:ab4e012489ef 37 /// significant 4 bits are reserved for applications.
davidr99 0:ab4e012489ef 38 class RHGenericDriver
davidr99 0:ab4e012489ef 39 {
davidr99 0:ab4e012489ef 40 public:
davidr99 0:ab4e012489ef 41 /// \brief Defines different operating modes for the transport hardware
davidr99 0:ab4e012489ef 42 ///
davidr99 0:ab4e012489ef 43 /// These are the different values that can be adopted by the _mode variable and
davidr99 0:ab4e012489ef 44 /// returned by the mode() member function,
davidr99 0:ab4e012489ef 45 typedef enum
davidr99 0:ab4e012489ef 46 {
davidr99 0:ab4e012489ef 47 RHModeInitialising = 0, ///< Transport is initialising. Initial default value until init() is called..
davidr99 0:ab4e012489ef 48 RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported)
davidr99 0:ab4e012489ef 49 RHModeIdle, ///< Transport is idle.
davidr99 0:ab4e012489ef 50 RHModeTx, ///< Transport is in the process of transmitting a message.
davidr99 0:ab4e012489ef 51 RHModeRx ///< Transport is in the process of receiving a message.
davidr99 0:ab4e012489ef 52 } RHMode;
davidr99 0:ab4e012489ef 53
davidr99 0:ab4e012489ef 54 /// Constructor
davidr99 0:ab4e012489ef 55 RHGenericDriver();
davidr99 0:ab4e012489ef 56
davidr99 0:ab4e012489ef 57 /// Initialise the Driver transport hardware and software.
davidr99 0:ab4e012489ef 58 /// Make sure the Driver is properly configured before calling init().
davidr99 0:ab4e012489ef 59 /// \return true if initialisation succeeded.
davidr99 0:ab4e012489ef 60 virtual bool init();
davidr99 0:ab4e012489ef 61
davidr99 0:ab4e012489ef 62 /// Tests whether a new message is available
davidr99 0:ab4e012489ef 63 /// from the Driver.
davidr99 0:ab4e012489ef 64 /// On most drivers, if there is an uncollected received message, and there is no message
davidr99 0:ab4e012489ef 65 /// currently bing transmitted, this will also put the Driver into RHModeRx mode until
davidr99 0:ab4e012489ef 66 /// a message is actually received by the transport, when it will be returned to RHModeIdle.
davidr99 0:ab4e012489ef 67 /// This can be called multiple times in a timeout loop.
davidr99 0:ab4e012489ef 68 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv().
davidr99 0:ab4e012489ef 69 virtual bool available() = 0;
davidr99 0:ab4e012489ef 70
davidr99 0:ab4e012489ef 71 /// Turns the receiver on if it not already on.
davidr99 0:ab4e012489ef 72 /// If there is a valid message available, copy it to buf and return true
davidr99 0:ab4e012489ef 73 /// else return false.
davidr99 0:ab4e012489ef 74 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
davidr99 0:ab4e012489ef 75 /// You should be sure to call this function frequently enough to not miss any messages
davidr99 0:ab4e012489ef 76 /// It is recommended that you call it in your main loop.
davidr99 0:ab4e012489ef 77 /// \param[in] buf Location to copy the received message
davidr99 0:ab4e012489ef 78 /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
davidr99 0:ab4e012489ef 79 /// \return true if a valid message was copied to buf
davidr99 0:ab4e012489ef 80 virtual bool recv(uint8_t* buf, uint8_t* len) = 0;
davidr99 0:ab4e012489ef 81
davidr99 0:ab4e012489ef 82 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
davidr99 0:ab4e012489ef 83 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
davidr99 0:ab4e012489ef 84 /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will
davidr99 0:ab4e012489ef 85 /// return false and will not send the message.
davidr99 0:ab4e012489ef 86 /// \param[in] data Array of data to be sent
davidr99 0:ab4e012489ef 87 /// \param[in] len Number of bytes of data to send (> 0)
davidr99 0:ab4e012489ef 88 /// \return true if the message length was valid and it was correctly queued for transmit
davidr99 0:ab4e012489ef 89 virtual bool send(const uint8_t* data, uint8_t len) = 0;
davidr99 0:ab4e012489ef 90
davidr99 0:ab4e012489ef 91 /// Returns the maximum message length
davidr99 0:ab4e012489ef 92 /// available in this Driver.
davidr99 0:ab4e012489ef 93 /// \return The maximum legal message length
davidr99 0:ab4e012489ef 94 virtual uint8_t maxMessageLength() = 0;
davidr99 0:ab4e012489ef 95
davidr99 0:ab4e012489ef 96 /// Starts the receiver and blocks until a valid received
davidr99 0:ab4e012489ef 97 /// message is available.
davidr99 0:ab4e012489ef 98 virtual void waitAvailable();
davidr99 0:ab4e012489ef 99
davidr99 0:ab4e012489ef 100 /// Blocks until the transmitter
davidr99 0:ab4e012489ef 101 /// is no longer transmitting.
davidr99 0:ab4e012489ef 102 virtual bool waitPacketSent();
davidr99 0:ab4e012489ef 103
davidr99 0:ab4e012489ef 104 /// Blocks until the transmitter is no longer transmitting.
davidr99 0:ab4e012489ef 105 /// or until the timeout occuers, whichever happens first
davidr99 0:ab4e012489ef 106 /// \param[in] timeout Maximum time to wait in milliseconds.
davidr99 0:ab4e012489ef 107 /// \return true if the RF22 completed transmission within the timeout period. False if it timed out.
davidr99 0:ab4e012489ef 108 virtual bool waitPacketSent(uint16_t timeout);
davidr99 0:ab4e012489ef 109
davidr99 0:ab4e012489ef 110 /// Starts the receiver and blocks until a received message is available or a timeout
davidr99 0:ab4e012489ef 111 /// \param[in] timeout Maximum time to wait in milliseconds.
davidr99 0:ab4e012489ef 112 /// \return true if a message is available
davidr99 0:ab4e012489ef 113 virtual bool waitAvailableTimeout(uint16_t timeout);
davidr99 0:ab4e012489ef 114
davidr99 0:ab4e012489ef 115 /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.
davidr99 0:ab4e012489ef 116 /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,
davidr99 0:ab4e012489ef 117 /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.
davidr99 0:ab4e012489ef 118 /// In promiscuous mode, all messages will be accepted regardless of the TO header.
davidr99 0:ab4e012489ef 119 /// In a conventional multinode system, all nodes will have a unique address
davidr99 0:ab4e012489ef 120 /// (which you could store in EEPROM).
davidr99 0:ab4e012489ef 121 /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,
davidr99 0:ab4e012489ef 122 /// allowing the possibilty of address spoofing).
davidr99 0:ab4e012489ef 123 /// \param[in] thisAddress The address of this node.
davidr99 0:ab4e012489ef 124 virtual void setThisAddress(uint8_t thisAddress);
davidr99 0:ab4e012489ef 125
davidr99 0:ab4e012489ef 126 /// Sets the TO header to be sent in all subsequent messages
davidr99 0:ab4e012489ef 127 /// \param[in] to The new TO header value
davidr99 0:ab4e012489ef 128 virtual void setHeaderTo(uint8_t to);
davidr99 0:ab4e012489ef 129
davidr99 0:ab4e012489ef 130 /// Sets the FROM header to be sent in all subsequent messages
davidr99 0:ab4e012489ef 131 /// \param[in] from The new FROM header value
davidr99 0:ab4e012489ef 132 virtual void setHeaderFrom(uint8_t from);
davidr99 0:ab4e012489ef 133
davidr99 0:ab4e012489ef 134 /// Sets the ID header to be sent in all subsequent messages
davidr99 0:ab4e012489ef 135 /// \param[in] id The new ID header value
davidr99 0:ab4e012489ef 136 virtual void setHeaderId(uint8_t id);
davidr99 0:ab4e012489ef 137
davidr99 0:ab4e012489ef 138 /// Sets and clears bits in the FLAGS header to be sent in all subsequent messages
davidr99 0:ab4e012489ef 139 /// First it clears he FLAGS according to the clear argument, then sets the flags according to the
davidr99 0:ab4e012489ef 140 /// set argument. The default for clear always clears the application specific flags.
davidr99 0:ab4e012489ef 141 /// \param[in] set bitmask of bits to be set. Flags are cleared with the clear mask before being set.
davidr99 0:ab4e012489ef 142 /// \param[in] clear bitmask of flags to clear. Defaults to RH_FLAGS_APPLICATION_SPECIFIC
davidr99 0:ab4e012489ef 143 /// which clears the application specific flags, resultiung in new application specific flags
davidr99 0:ab4e012489ef 144 /// identical to the set.
davidr99 0:ab4e012489ef 145 virtual void setHeaderFlags(uint8_t set, uint8_t clear = RH_FLAGS_APPLICATION_SPECIFIC);
davidr99 0:ab4e012489ef 146
davidr99 0:ab4e012489ef 147 /// Tells the receiver to accept messages with any TO address, not just messages
davidr99 0:ab4e012489ef 148 /// addressed to thisAddress or the broadcast address
davidr99 0:ab4e012489ef 149 /// \param[in] promiscuous true if you wish to receive messages with any TO address
davidr99 0:ab4e012489ef 150 virtual void setPromiscuous(bool promiscuous);
davidr99 0:ab4e012489ef 151
davidr99 0:ab4e012489ef 152 /// Returns the TO header of the last received message
davidr99 0:ab4e012489ef 153 /// \return The TO header
davidr99 0:ab4e012489ef 154 virtual uint8_t headerTo();
davidr99 0:ab4e012489ef 155
davidr99 0:ab4e012489ef 156 /// Returns the FROM header of the last received message
davidr99 0:ab4e012489ef 157 /// \return The FROM header
davidr99 0:ab4e012489ef 158 virtual uint8_t headerFrom();
davidr99 0:ab4e012489ef 159
davidr99 0:ab4e012489ef 160 /// Returns the ID header of the last received message
davidr99 0:ab4e012489ef 161 /// \return The ID header
davidr99 0:ab4e012489ef 162 virtual uint8_t headerId();
davidr99 0:ab4e012489ef 163
davidr99 0:ab4e012489ef 164 /// Returns the FLAGS header of the last received message
davidr99 0:ab4e012489ef 165 /// \return The FLAGS header
davidr99 0:ab4e012489ef 166 virtual uint8_t headerFlags();
davidr99 0:ab4e012489ef 167
davidr99 0:ab4e012489ef 168 /// Returns the most recent RSSI (Receiver Signal Strength Indicator).
davidr99 0:ab4e012489ef 169 /// Usually it is the RSSI of the last received message, which is measured when the preamble is received.
davidr99 0:ab4e012489ef 170 /// If you called readRssi() more recently, it will return that more recent value.
davidr99 0:ab4e012489ef 171 /// \return The most recent RSSI measurement in dBm.
davidr99 0:ab4e012489ef 172 int8_t lastRssi();
davidr99 0:ab4e012489ef 173
davidr99 0:ab4e012489ef 174 /// Returns the operating mode of the library.
davidr99 0:ab4e012489ef 175 /// \return the current mode, one of RF69_MODE_*
davidr99 0:ab4e012489ef 176 RHMode mode();
davidr99 0:ab4e012489ef 177
davidr99 0:ab4e012489ef 178 /// Sets the operating mode of the transport.
davidr99 0:ab4e012489ef 179 void setMode(RHMode mode);
davidr99 0:ab4e012489ef 180
davidr99 0:ab4e012489ef 181 /// Sets the transport hardware into low-power sleep mode
davidr99 0:ab4e012489ef 182 /// (if supported). May be overridden by specific drivers to initialte sleep mode.
davidr99 0:ab4e012489ef 183 /// If successful, the transport will stay in sleep mode until woken by
davidr99 0:ab4e012489ef 184 /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
davidr99 0:ab4e012489ef 185 /// \return true if sleep mode is supported by transport hardware and the RadioHead driver, and if sleep mode
davidr99 0:ab4e012489ef 186 /// was successfully entered. If sleep mode is not suported, return false.
davidr99 0:ab4e012489ef 187 virtual bool sleep();
davidr99 0:ab4e012489ef 188
davidr99 0:ab4e012489ef 189 /// Prints a data buffer in HEX.
davidr99 0:ab4e012489ef 190 /// For diagnostic use
davidr99 0:ab4e012489ef 191 /// \param[in] prompt string to preface the print
davidr99 0:ab4e012489ef 192 /// \param[in] buf Location of the buffer to print
davidr99 0:ab4e012489ef 193 /// \param[in] len Length of the buffer in octets.
davidr99 0:ab4e012489ef 194 static void printBuffer(const char* prompt, const uint8_t* buf, uint8_t len);
davidr99 0:ab4e012489ef 195
davidr99 0:ab4e012489ef 196 /// Returns the count of the number of bad received packets (ie packets with bad lengths, checksum etc)
davidr99 0:ab4e012489ef 197 /// which were rejected and not delivered to the application.
davidr99 0:ab4e012489ef 198 /// Caution: not all drivers can correctly report this count. Some underlying hardware only report
davidr99 0:ab4e012489ef 199 /// good packets.
davidr99 0:ab4e012489ef 200 /// \return The number of bad packets received.
davidr99 0:ab4e012489ef 201 uint16_t rxBad();
davidr99 0:ab4e012489ef 202
davidr99 0:ab4e012489ef 203 /// Returns the count of the number of
davidr99 0:ab4e012489ef 204 /// good received packets
davidr99 0:ab4e012489ef 205 /// \return The number of good packets received.
davidr99 0:ab4e012489ef 206 uint16_t rxGood();
davidr99 0:ab4e012489ef 207
davidr99 0:ab4e012489ef 208 /// Returns the count of the number of
davidr99 0:ab4e012489ef 209 /// packets successfully transmitted (though not necessarily received by the destination)
davidr99 0:ab4e012489ef 210 /// \return The number of packets successfully transmitted
davidr99 0:ab4e012489ef 211 uint16_t txGood();
davidr99 0:ab4e012489ef 212
davidr99 0:ab4e012489ef 213 protected:
davidr99 0:ab4e012489ef 214
davidr99 0:ab4e012489ef 215 /// The current transport operating mode
davidr99 0:ab4e012489ef 216 volatile RHMode _mode;
davidr99 0:ab4e012489ef 217
davidr99 0:ab4e012489ef 218 /// This node id
davidr99 0:ab4e012489ef 219 uint8_t _thisAddress;
davidr99 0:ab4e012489ef 220
davidr99 0:ab4e012489ef 221 /// Whether the transport is in promiscuous mode
davidr99 0:ab4e012489ef 222 bool _promiscuous;
davidr99 0:ab4e012489ef 223
davidr99 0:ab4e012489ef 224 /// TO header in the last received mesasge
davidr99 0:ab4e012489ef 225 volatile uint8_t _rxHeaderTo;
davidr99 0:ab4e012489ef 226
davidr99 0:ab4e012489ef 227 /// FROM header in the last received mesasge
davidr99 0:ab4e012489ef 228 volatile uint8_t _rxHeaderFrom;
davidr99 0:ab4e012489ef 229
davidr99 0:ab4e012489ef 230 /// ID header in the last received mesasge
davidr99 0:ab4e012489ef 231 volatile uint8_t _rxHeaderId;
davidr99 0:ab4e012489ef 232
davidr99 0:ab4e012489ef 233 /// FLAGS header in the last received mesasge
davidr99 0:ab4e012489ef 234 volatile uint8_t _rxHeaderFlags;
davidr99 0:ab4e012489ef 235
davidr99 0:ab4e012489ef 236 /// TO header to send in all messages
davidr99 0:ab4e012489ef 237 uint8_t _txHeaderTo;
davidr99 0:ab4e012489ef 238
davidr99 0:ab4e012489ef 239 /// FROM header to send in all messages
davidr99 0:ab4e012489ef 240 uint8_t _txHeaderFrom;
davidr99 0:ab4e012489ef 241
davidr99 0:ab4e012489ef 242 /// ID header to send in all messages
davidr99 0:ab4e012489ef 243 uint8_t _txHeaderId;
davidr99 0:ab4e012489ef 244
davidr99 0:ab4e012489ef 245 /// FLAGS header to send in all messages
davidr99 0:ab4e012489ef 246 uint8_t _txHeaderFlags;
davidr99 0:ab4e012489ef 247
davidr99 0:ab4e012489ef 248 /// The value of the last received RSSI value, in some transport specific units
davidr99 0:ab4e012489ef 249 volatile int8_t _lastRssi;
davidr99 0:ab4e012489ef 250
davidr99 0:ab4e012489ef 251 /// Count of the number of bad messages (eg bad checksum etc) received
davidr99 0:ab4e012489ef 252 volatile uint16_t _rxBad;
davidr99 0:ab4e012489ef 253
davidr99 0:ab4e012489ef 254 /// Count of the number of successfully transmitted messaged
davidr99 0:ab4e012489ef 255 volatile uint16_t _rxGood;
davidr99 0:ab4e012489ef 256
davidr99 0:ab4e012489ef 257 /// Count of the number of bad messages (correct checksum etc) received
davidr99 0:ab4e012489ef 258 volatile uint16_t _txGood;
davidr99 0:ab4e012489ef 259
davidr99 0:ab4e012489ef 260 private:
davidr99 0:ab4e012489ef 261
davidr99 0:ab4e012489ef 262 };
davidr99 0:ab4e012489ef 263
davidr99 0:ab4e012489ef 264
davidr99 0:ab4e012489ef 265 #endif