Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
RHGenericDriver.h
00001 // RHGenericDriver.h 00002 // Author: Mike McCauley (mikem@airspayce.com) 00003 // Copyright (C) 2014 Mike McCauley 00004 // $Id: RHGenericDriver.h,v 1.19 2017/03/08 09:30:47 mikem Exp mikem $ 00005 // 00006 // Ported to mbed - support only a single radio - Dan Julio - 5/2017 00007 // 00008 00009 #ifndef RHGenericDriver_h 00010 #define RHGenericDriver_h 00011 00012 #include "RadioHead.h" 00013 #include "mbed.h" 00014 #include "max32630fthr.h" 00015 #include <stdint.h> 00016 00017 // Defines bits of the FLAGS header reserved for use by the RadioHead library and 00018 // the flags available for use by applications 00019 #define RH_FLAGS_RESERVED 0xf0 00020 #define RH_FLAGS_APPLICATION_SPECIFIC 0x0f 00021 #define RH_FLAGS_NONE 0 00022 00023 // Default timeout for waitCAD() in ms 00024 #define RH_CAD_DEFAULT_TIMEOUT 10000 00025 00026 ///////////////////////////////////////////////////////////////////// 00027 /// \class RHGenericDriver RHGenericDriver.h <RHGenericDriver.h> 00028 /// \brief Abstract base class for a RadioHead driver. 00029 /// 00030 /// This class defines the functions that must be provided by any RadioHead driver. 00031 /// Different types of driver will implement all the abstract functions, and will perhaps override 00032 /// other functions in this subclass, or perhaps add new functions specifically required by that driver. 00033 /// Do not directly instantiate this class: it is only to be subclassed by driver classes. 00034 /// 00035 /// Subclasses are expected to implement a half-duplex, unreliable, error checked, unaddressed packet transport. 00036 /// They are expected to carry a message payload with an appropriate maximum length for the transport hardware 00037 /// and to also carry unaltered 4 message headers: TO, FROM, ID, FLAGS 00038 /// 00039 /// \par Headers 00040 /// 00041 /// Each message sent and received by a RadioHead driver includes 4 headers: 00042 /// -TO The node address that the message is being sent to (broadcast RH_BROADCAST_ADDRESS (255) is permitted) 00043 /// -FROM The node address of the sending node 00044 /// -ID A message ID, distinct (over short time scales) for each message sent by a particilar node 00045 /// -FLAGS A bitmask of flags. The most significant 4 bits are reserved for use by RadioHead. The least 00046 /// significant 4 bits are reserved for applications. 00047 class RHGenericDriver 00048 { 00049 public: 00050 /// \brief Defines different operating modes for the transport hardware 00051 /// 00052 /// These are the different values that can be adopted by the _mode variable and 00053 /// returned by the mode() member function, 00054 typedef enum 00055 { 00056 RHModeInitialising = 0, ///< Transport is initialising. Initial default value until init() is called.. 00057 RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported) 00058 RHModeIdle, ///< Transport is idle. 00059 RHModeTx, ///< Transport is in the process of transmitting a message. 00060 RHModeRx, ///< Transport is in the process of receiving a message. 00061 RHModeCad ///< Transport is in the process of detecting channel activity (if supported) 00062 } RHMode; 00063 00064 /// Constructor 00065 RHGenericDriver(); 00066 00067 /// Initialise the Driver transport hardware and software. 00068 /// Make sure the Driver is properly configured before calling init(). 00069 /// \return true if initialisation succeeded. 00070 virtual bool init(); 00071 00072 /// Tests whether a new message is available 00073 /// from the Driver. 00074 /// On most drivers, if there is an uncollected received message, and there is no message 00075 /// currently bing transmitted, this will also put the Driver into RHModeRx mode until 00076 /// a message is actually received by the transport, when it will be returned to RHModeIdle. 00077 /// This can be called multiple times in a timeout loop. 00078 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv(). 00079 virtual bool available() = 0; 00080 00081 /// Turns the receiver on if it not already on. 00082 /// If there is a valid message available, copy it to buf and return true 00083 /// else return false. 00084 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted). 00085 /// You should be sure to call this function frequently enough to not miss any messages 00086 /// It is recommended that you call it in your main loop. 00087 /// \param[in] buf Location to copy the received message 00088 /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied. 00089 /// \return true if a valid message was copied to buf 00090 virtual bool recv(uint8_t* buf, uint8_t* len) = 0; 00091 00092 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent(). 00093 /// Then optionally waits for Channel Activity Detection (CAD) 00094 /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD(). 00095 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length 00096 /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will 00097 /// return false and will not send the message. 00098 /// \param[in] data Array of data to be sent 00099 /// \param[in] len Number of bytes of data to send (> 0) 00100 /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting. 00101 /// \return true if the message length was valid and it was correctly queued for transmit. Return false 00102 /// if CAD was requested and the CAD timeout timed out before clear channel was detected. 00103 virtual bool send(const uint8_t* data, uint8_t len) = 0; 00104 00105 /// Returns the maximum message length 00106 /// available in this Driver. 00107 /// \return The maximum legal message length 00108 virtual uint8_t maxMessageLength() = 0; 00109 00110 /// Starts the receiver and blocks until a valid received 00111 /// message is available. 00112 virtual void waitAvailable(); 00113 00114 /// Blocks until the transmitter 00115 /// is no longer transmitting. 00116 virtual bool waitPacketSent(); 00117 00118 /// Blocks until the transmitter is no longer transmitting. 00119 /// or until the timeout occuers, whichever happens first 00120 /// \param[in] timeout Maximum time to wait in milliseconds. 00121 /// \return true if the radio completed transmission within the timeout period. False if it timed out. 00122 virtual bool waitPacketSent(uint16_t timeout); 00123 00124 /// Starts the receiver and blocks until a received message is available or a timeout 00125 /// \param[in] timeout Maximum time to wait in milliseconds. 00126 /// \return true if a message is available 00127 virtual bool waitAvailableTimeout(uint16_t timeout); 00128 00129 // Bent G Christensen (bentor@gmail.com), 08/15/2016 00130 /// Channel Activity Detection (CAD). 00131 /// Blocks until channel activity is finished or CAD timeout occurs. 00132 /// Uses the radio's CAD function (if supported) to detect channel activity. 00133 /// Implements random delays of 100 to 1000ms while activity is detected and until timeout. 00134 /// Caution: the random() function is not seeded. If you want non-deterministic behaviour, consider 00135 /// using something like randomSeed(analogRead(A0)); in your sketch. 00136 /// Permits the implementation of listen-before-talk mechanism (Collision Avoidance). 00137 /// Calls the isChannelActive() member function for the radio (if supported) 00138 /// to determine if the channel is active. If the radio does not support isChannelActive(), 00139 /// always returns true immediately 00140 /// \return true if the radio-specific CAD (as returned by isChannelActive()) 00141 /// shows the channel is clear within the timeout period (or the timeout period is 0), else returns false. 00142 virtual bool waitCAD(); 00143 00144 /// Sets the Channel Activity Detection timeout in milliseconds to be used by waitCAD(). 00145 /// The default is 0, which means do not wait for CAD detection. 00146 /// CAD detection depends on support for isChannelActive() by your particular radio. 00147 void setCADTimeout(unsigned long cad_timeout); 00148 00149 /// Determine if the currently selected radio channel is active. 00150 /// This is expected to be subclassed by specific radios to implement their Channel Activity Detection 00151 /// if supported. If the radio does not support CAD, returns true immediately. If a RadioHead radio 00152 /// supports isChannelActive() it will be documented in the radio specific documentation. 00153 /// This is called automatically by waitCAD(). 00154 /// \return true if the radio-specific CAD (as returned by override of isChannelActive()) shows the 00155 /// current radio channel as active, else false. If there is no radio-specific CAD, returns false. 00156 virtual bool isChannelActive(); 00157 00158 /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this. 00159 /// This will be used to test the adddress in incoming messages. In non-promiscuous mode, 00160 /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted. 00161 /// In promiscuous mode, all messages will be accepted regardless of the TO header. 00162 /// In a conventional multinode system, all nodes will have a unique address 00163 /// (which you could store in EEPROM). 00164 /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to, 00165 /// allowing the possibilty of address spoofing). 00166 /// \param[in] thisAddress The address of this node. 00167 virtual void setThisAddress(uint8_t thisAddress); 00168 00169 /// Sets the TO header to be sent in all subsequent messages 00170 /// \param[in] to The new TO header value 00171 virtual void setHeaderTo(uint8_t to); 00172 00173 /// Sets the FROM header to be sent in all subsequent messages 00174 /// \param[in] from The new FROM header value 00175 virtual void setHeaderFrom(uint8_t from); 00176 00177 /// Sets the ID header to be sent in all subsequent messages 00178 /// \param[in] id The new ID header value 00179 virtual void setHeaderId(uint8_t id); 00180 00181 /// Sets and clears bits in the FLAGS header to be sent in all subsequent messages 00182 /// First it clears he FLAGS according to the clear argument, then sets the flags according to the 00183 /// set argument. The default for clear always clears the application specific flags. 00184 /// \param[in] set bitmask of bits to be set. Flags are cleared with the clear mask before being set. 00185 /// \param[in] clear bitmask of flags to clear. Defaults to RH_FLAGS_APPLICATION_SPECIFIC 00186 /// which clears the application specific flags, resulting in new application specific flags 00187 /// identical to the set. 00188 virtual void setHeaderFlags(uint8_t set, uint8_t clear = RH_FLAGS_APPLICATION_SPECIFIC); 00189 00190 /// Tells the receiver to accept messages with any TO address, not just messages 00191 /// addressed to thisAddress or the broadcast address 00192 /// \param[in] promiscuous true if you wish to receive messages with any TO address 00193 virtual void setPromiscuous(bool promiscuous); 00194 00195 /// Returns the TO header of the last received message 00196 /// \return The TO header 00197 virtual uint8_t headerTo(); 00198 00199 /// Returns the FROM header of the last received message 00200 /// \return The FROM header 00201 virtual uint8_t headerFrom(); 00202 00203 /// Returns the ID header of the last received message 00204 /// \return The ID header 00205 virtual uint8_t headerId(); 00206 00207 /// Returns the FLAGS header of the last received message 00208 /// \return The FLAGS header 00209 virtual uint8_t headerFlags(); 00210 00211 /// Returns the most recent RSSI (Receiver Signal Strength Indicator). 00212 /// Usually it is the RSSI of the last received message, which is measured when the preamble is received. 00213 /// If you called readRssi() more recently, it will return that more recent value. 00214 /// \return The most recent RSSI measurement in dBm. 00215 int8_t lastRssi(); 00216 00217 /// Returns the operating mode of the library. 00218 /// \return the current mode, one of RF69_MODE_* 00219 RHMode mode(); 00220 00221 /// Sets the operating mode of the transport. 00222 void setMode(RHMode mode); 00223 00224 /// Sets the transport hardware into low-power sleep mode 00225 /// (if supported). May be overridden by specific drivers to initialte sleep mode. 00226 /// If successful, the transport will stay in sleep mode until woken by 00227 /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc) 00228 /// \return true if sleep mode is supported by transport hardware and the RadioHead driver, and if sleep mode 00229 /// was successfully entered. If sleep mode is not suported, return false. 00230 virtual bool sleep(); 00231 00232 /// Prints a data buffer in HEX. 00233 /// For diagnostic use 00234 /// \param[in] prompt string to preface the print 00235 /// \param[in] buf Location of the buffer to print 00236 /// \param[in] len Length of the buffer in octets. 00237 static void printBuffer(const char* prompt, const uint8_t* buf, uint8_t len); 00238 00239 /// Returns the count of the number of bad received packets (ie packets with bad lengths, checksum etc) 00240 /// which were rejected and not delivered to the application. 00241 /// Caution: not all drivers can correctly report this count. Some underlying hardware only report 00242 /// good packets. 00243 /// \return The number of bad packets received. 00244 uint16_t rxBad(); 00245 00246 /// Returns the count of the number of 00247 /// good received packets 00248 /// \return The number of good packets received. 00249 uint16_t rxGood(); 00250 00251 /// Returns the count of the number of 00252 /// packets successfully transmitted (though not necessarily received by the destination) 00253 /// \return The number of packets successfully transmitted 00254 uint16_t txGood(); 00255 00256 protected: 00257 00258 /// The current transport operating mode 00259 volatile RHMode _mode; 00260 00261 /// This node id 00262 uint8_t _thisAddress; 00263 00264 /// Whether the transport is in promiscuous mode 00265 bool _promiscuous; 00266 00267 /// TO header in the last received mesasge 00268 volatile uint8_t _rxHeaderTo; 00269 00270 /// FROM header in the last received mesasge 00271 volatile uint8_t _rxHeaderFrom; 00272 00273 /// ID header in the last received mesasge 00274 volatile uint8_t _rxHeaderId; 00275 00276 /// FLAGS header in the last received mesasge 00277 volatile uint8_t _rxHeaderFlags; 00278 00279 /// TO header to send in all messages 00280 uint8_t _txHeaderTo; 00281 00282 /// FROM header to send in all messages 00283 uint8_t _txHeaderFrom; 00284 00285 /// ID header to send in all messages 00286 uint8_t _txHeaderId; 00287 00288 /// FLAGS header to send in all messages 00289 uint8_t _txHeaderFlags; 00290 00291 /// The value of the last received RSSI value, in some transport specific units 00292 volatile int8_t _lastRssi; 00293 00294 /// Count of the number of bad messages (eg bad checksum etc) received 00295 volatile uint16_t _rxBad; 00296 00297 /// Count of the number of successfully transmitted messaged 00298 volatile uint16_t _rxGood; 00299 00300 /// Count of the number of bad messages (correct checksum etc) received 00301 volatile uint16_t _txGood; 00302 00303 /// Channel activity detected 00304 volatile bool _cad; 00305 00306 /// Channel activity timeout in ms 00307 unsigned int _cad_timeout; 00308 00309 private: 00310 00311 Timer _waitTimer; 00312 00313 }; 00314 00315 00316 #endif
Generated on Wed Jul 13 2022 12:04:17 by
