RadioHead
Embed:
(wiki syntax)
Show/hide line numbers
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 Mon Jul 18 2022 11:18:50 by
![doxygen](doxygen.png)