Daniel Knox / RN2483

Dependents:   rn2483-TestProgram

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RN2483.h Source File

RN2483.h

00001 /*
00002 * Copyright (c) 2016 Dan Knox. All rights reserved.
00003 *
00004 * This file is part of RN2483.
00005 *
00006 * RN2483 is free software: you can redistribute it and/or modify
00007 * it under the terms of the GNU Lesser General Public License as
00008 * published by the Free Software Foundation, either version 3 of
00009 * the License, or(at your option) any later version.
00010 *
00011 * RN2483 is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014 * GNU Lesser General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU Lesser General Public
00017 * License along with RN2483.  If not, see
00018 * <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #ifndef _RN2483_h
00022 #define _RN2483_h
00023 
00024 #include "mbed.h"
00025 #include <stdint.h>
00026 
00027 //#define USE_DYNAMIC_BUFFER
00028 
00029 #define DEFAULT_INPUT_BUFFER_SIZE 64
00030 #define DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE 32
00031 #define DEFAULT_TIMEOUT 120
00032 #define RECEIVE_TIMEOUT 60000
00033 #define DEFAULT_FSB 2
00034 #define DEFAULT_PWR_IDX_868 1
00035 #define DEFAULT_PWR_IDX_915 5
00036 #define DEFAULT_SF_868 7
00037 #define DEFAULT_SF_915 7
00038 
00039 #define ENABLE_SLEEP
00040 
00041 // Available error codes.
00042 enum MacTransmitErrorCodes {
00043     NoError = 0,
00044     NoResponse = 1,
00045     Timedout = 2,
00046     PayloadSizeError = 3,
00047     InternalError = 4,
00048     Busy = 5,
00049     NetworkFatalError = 6,
00050     NotConnected = 7,
00051     NoAcknowledgment = 8,
00052     Silent = 9,
00053 };
00054 
00055 // Provides a simple, abstracted interface to Microchip's RN2483 LoRaWAN module.
00056 
00057 class RN2483
00058 {
00059 public:
00060     
00061     /**
00062     * @brief Create a new instance of the RN2483.
00063     * @param Serial TX pin name.
00064     * @param Serial RX pin name.
00065     */
00066     RN2483(PinName tx, PinName rx);
00067 
00068     /**
00069     * @return Returns the default device baud rate.
00070     */
00071     uint32_t getDefaultBaudRate() {
00072         return 57600;
00073     };
00074 
00075     /**
00076     * @brief Initialise settings and connect to network using Over The Air activation.
00077     * @param devEUI provided by LoRaWAN Network server registration.
00078     * @param appEUI provided by LoRaWAN Network server registration.
00079     * @param appKey provided by LoRaWAN Network server registration.
00080     * @return Returns true if network confirmation and able to save settings.
00081     */
00082     bool initOTA(const uint8_t devEUI[8], const uint8_t appEUI[8], const uint8_t appKey[16], bool adr = true);
00083 
00084     /**
00085     * @brief Initializes the device and connects to the network using Activation By Personalization.
00086     * @param devADDR provided by LoRaWAN Network server registration.
00087     * @param appSKey provided by LoRaWAN Network server registration.
00088     * @param nwkSKey provided by LoRaWAN Network server registration.
00089     * @return Returns true if the parameters were valid and able to save settings.
00090     */
00091     bool initABP(const uint8_t devAddr[4], const uint8_t appSKey[16], const uint8_t nwkSKey[16], bool adr = true);
00092 
00093     /**
00094     * @brief Attempts to connect to the network using Over The Air Activation.
00095     * @return Returns true if able to join network.
00096     */
00097     bool joinOTTA();
00098     
00099     /**
00100     * @brief Attempts to connect to the network using Activation By Personalization.
00101     * @return Returns true if able to join network.
00102     */
00103     bool joinABP();
00104     
00105     /**
00106     * @brief Sends the given payload without acknowledgement.
00107     * @param Port to use for transmission.
00108     * @param Payload buffer
00109     * @param Payload buffer size
00110     * @return Returns 0 (NoError) when data was sucessfully fowarded to radio, otherwise returns MacTransmitErrorCode.
00111     */
00112     uint8_t send(uint8_t port, const uint8_t* payload, uint8_t size);
00113 
00114     /**
00115     * @brief Sends the given payload with acknowledgement.
00116     * @param Port to use for transmission.
00117     * @param Payload buffer
00118     * @param Payload buffer size
00119     * @param Number of transmission retries in event of network transmission failure.
00120     * @return Returns 0 (NoError) when network acks transmission, otherwise returns MacTransmitErrorCode.
00121     */
00122     uint8_t sendReqAck(uint8_t port, const uint8_t* payload, uint8_t size, uint8_t maxRetries);
00123 
00124     /**
00125     * @brief Copies the latest received packet (optionally starting from the "payloadStartPosition" of the payload).
00126     * @param Buffer to read into.
00127     * @param Buffer size.
00128     * @return Returns the number of bytes written or 0 if no packet is received since last transmission.
00129     */
00130     uint16_t receive(uint8_t* buffer, uint16_t size, uint16_t payloadStartPosition = 0);
00131 
00132     /**
00133     * @brief Gets the preprogrammed EUI node address from the module in HEX.
00134     * @param Buffer to read into.
00135     * @param Buffer size.
00136     * @return Returns the number of bytes written or 0 in case of error..
00137     */
00138     uint8_t getHWEUI(uint8_t* buffer, uint8_t size);
00139     
00140    /**
00141     * @brief Informs the RN2483 to do an ADC conversion on the VDD.
00142     * @param Pass pointer to long for conversion to read into.
00143     * @return Returns if a value was sucessfully read into the long.
00144     */
00145     bool getVDD(long *vdd);
00146 
00147     /**
00148     * @brief Enables all the channels that belong to the given Frequency Sub-Band (FSB)
00149     * disables the rest.
00150     * @param FSB is [1, 8] or 0 to enable all channels.
00151     * @return Returns true if all channels were set successfully.
00152     */
00153     bool setFsbChannels(uint8_t fsb);
00154 
00155     /**
00156     * @brief Sets the spreading factor.
00157     * @param Spreading factor parameter.
00158     * @return Returns true if was set successfully.
00159     */
00160     bool setSpreadingFactor(uint8_t spreadingFactor);
00161 
00162     /**
00163     * @brief Sets the power index
00164     * @param 868MHz: 1 to 5 / 915MHz: 5, 7, 8, 9 or 10.
00165     * @return Returns true if succesful.
00166     */
00167     bool setPowerIndex(uint8_t powerIndex);
00168 
00169     /**
00170     * @brief Sets the time interval for the link check process. When the time expires, the next application
00171     * packet will include a link check command to the server.
00172     * @param Decimal number that sets the time interval in seconds, from 0 to 65535. 0 disables link check process.
00173     * @return Returns true if parameter is valid or false if time interval is not valid.
00174     */
00175     bool setLinkCheckInterval(uint8_t linkCheckInterval);
00176 
00177     /**
00178     * @brief Sets the battery level required for the Device Status Answer frame in LoRaWAN Class A Protocol.
00179     * @param temperature Decimal number between 0-255 representing battery level. 0 means external power, 1 means
00180     * low level, 254 means high level, 255 means the device was unable to measure battery level.
00181     * @return Returns true if battery level is valid or false if value not valid.
00182     */
00183     bool setBattery(uint8_t batLvl);
00184 
00185     /**
00186     * @brief Sets the module operation frequency on a given channel ID.
00187     * @param Channel ID from 3 - 15.
00188     * @param Decimal number representing the frequency.
00189     * 863000000 to 870000000 or 433050000 to 434790000 in Hz
00190     * @return Returns true if parameters are valid or false if not.
00191     */
00192     bool setChannelFreq(uint8_t channelID, uint32_t frequency);
00193     
00194     /**
00195     * @brief Sets the duty cycle allowed on the given channel ID.
00196     * @param Channel ID to set duty cycle (0-15),
00197     * @param Duty cycle is 0 - 100% as a float.
00198     * @return Returns true if parameters are valid or false if not.
00199     */
00200     bool setDutyCycle(uint8_t channelID, float dutyCycle);
00201 
00202     /**
00203     * @brief Sets the data rate for a given channel ID.
00204     * Please refer to the LoRaWAN spec for the actual values.
00205     * @param Channel ID from 0 - 15.
00206     * @param Number representing the minimum data rate range from 0 to 7.
00207     * @param Number representing the maximum data rate range from 0 to 7
00208     * @return Returns true if parameters are valid or false if not.
00209     */
00210     bool setDrRange(uint8_t channelID, uint8_t minRange, uint8_t maxRange);
00211     
00212     /**
00213     * @brief Sets a given channel ID to be enabled or disabled.
00214     * @param Channel ID from 0 - 15.
00215     * @param Flag representing if channel is enabled or disabled.
00216     * Warning: duty cycle, frequency and data range must be set for a channel
00217     * before enabling!
00218     * @return Returns true if parameters are valid or false if not.
00219     */
00220     bool setStatus(uint8_t channelID, bool status);
00221     
00222     /**
00223     * @brief The network can issue a command to silence the RN2483. This restores the module. 
00224     * @return Returns true if parameters are valid or false if not.
00225     */
00226     bool forceEnable();
00227     
00228     /**
00229     * @brief Saves configurable parameters to eeprom. 
00230     * @return Returns true if parameters are valid or false if not.
00231     */
00232     bool saveConfiguration();
00233     
00234     /**
00235     * @brief Sends the command together with the given, paramValue (optional)
00236     * @param Command should include a trailing space if paramValue is set. Refer to RN2483 command ref
00237     * @param Command Parameter to send
00238     * @param Size of param buffer
00239     * @return Returns true on success or false if invalid.
00240     */
00241     bool sendCommand(const char* command, const uint8_t* paramValue, uint16_t size);
00242     bool sendCommand(const char* command, uint8_t paramValue);
00243     bool sendCommand(const char* command, const char* paramValue = NULL);
00244 
00245     /**
00246     * @brief Sends the command together with the given paramValue (optional)
00247     * @param MAC param should include a trailing space if paramValue is set. Refer to RN2483 command ref.
00248     * @param Param value to send
00249     * @param Size of Param buffer
00250     * @return Returns true on success or false if invalid.
00251     */
00252     bool setMacParam(const char* paramName, const uint8_t* paramValue, uint16_t size);
00253     bool setMacParam(const char* paramName, uint8_t paramValue);
00254     bool setMacParam(const char* paramName, const char* paramValue);
00255 
00256 #ifdef ENABLE_SLEEP
00257     /**
00258     * @brief Sends a serial line break to wake up the RN2483
00259     */
00260     void wakeUp();
00261 
00262     /**
00263     * @brief Sends the RN2483 to sleep for a finite length of time.
00264     * @param Milliseconds to sleep for, range is 100 to 4294967295
00265     */
00266     void sleep(uint32_t);
00267     
00268     /**
00269     * @brief Sends the RN2483 to sleep for a finite length of time.
00270     * Roughly three days.
00271     */
00272     void sleep();
00273     
00274 #endif
00275 
00276 #ifdef USE_DYNAMIC_BUFFER
00277     // Sets the size of the input buffer.
00278     // Needs to be called before initOTA()/initABP().
00279     void setInputBufferSize(uint16_t value) {
00280         this->inputBufferSize = value;
00281     };
00282 
00283     // Sets the size of the "Received Payload" buffer.
00284     // Needs to be called before initOTA()/initABP().
00285     void setReceivedPayloadBufferSize(uint16_t value) {
00286         this->receivedPayloadBufferSize = value;
00287     };
00288 #endif
00289 
00290 private:
00291 
00292     Serial _RN2483;
00293 
00294     // The size of the input buffer. Equals DEFAULT_INPUT_BUFFER_SIZE
00295     // by default or (optionally) a user-defined value when using USE_DYNAMIC_BUFFER.
00296     uint16_t inputBufferSize;
00297 
00298     // The size of the received payload buffer. Equals DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE
00299     // by default or (optionally) a user-defined value when using USE_DYNAMIC_BUFFER.
00300     uint16_t receivedPayloadBufferSize;
00301 
00302     // Flag used to make sure the received payload buffer is
00303     // current with the latest transmission.
00304     bool packetReceived;
00305 
00306     // Used to distinguise between RN2483 and RN2903.
00307     // Currently only being set during reset().
00308     bool isRN2903;
00309 
00310 #ifdef USE_DYNAMIC_BUFFER
00311     // Flag to make sure the buffers are not allocated more than once.
00312     bool isBufferInitialized;
00313 
00314     char* inputBuffer;
00315     char* receivedPayloadBuffer;
00316 #else
00317     char inputBuffer[DEFAULT_INPUT_BUFFER_SIZE];
00318     char receivedPayloadBuffer[DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE];
00319 #endif
00320 
00321     /**
00322     * @brief Takes care of the init tasks common to both initOTA() and initABP.
00323     */
00324     inline void init();
00325 
00326     /**
00327     * @brief Reads a line from the device serial stream.
00328     * @param Buffer to read into.
00329     * @param Size of buffer.
00330     * @param Position to start from.
00331     * @return Number of bytes read.
00332     */
00333     uint16_t readLn(char* buffer, uint16_t size, uint16_t start = 0);
00334 
00335     /**
00336     * @brief Reads a line from the input buffer
00337     * @return Number of bytes read.
00338     */
00339     uint16_t readLn() {
00340         return readLn(this->inputBuffer, this->inputBufferSize);
00341     };
00342 
00343     /**
00344     * @brief Waits for the given string.
00345     * @param String to look for.
00346     * @param Timeout Period
00347     * @param Position to start from.
00348     * @return Returns true if the string is received before a timeout.
00349     * Returns false if a timeout occurs or if another string is received.
00350     */
00351     bool expectString(const char* str, uint16_t timeout = DEFAULT_TIMEOUT);
00352 
00353     /**
00354     * @brief Looks for an 'OK' response from the RN2483
00355     * @param Timeout Period
00356     * @return Returns true if the string is received before a timeout.
00357     * Returns false if a timeout occurs or if another string is received.
00358     */
00359     bool expectOK(uint16_t timeout = DEFAULT_TIMEOUT);
00360 
00361     /**
00362     * @brief Sends a reset command to the module
00363     * Also sets-up some initial parameters like power index, SF and FSB channels.
00364     * @return Waits for sucess reponse or timeout.
00365     */
00366     bool resetDevice();
00367 
00368     /**
00369     * @brief Sends a join command to the network
00370     * @param Type of join, OTAA or ABP
00371     * @return Returns true on success or false if fail.
00372     */
00373     bool joinNetwork(const char* type);
00374 
00375     /**
00376     * @brief Returns the enum that is mapped to the given "error" message
00377     * @param Error to lookup.
00378     * @return Returns the enum
00379     */
00380     uint8_t lookupMacTransmitError(const char* error);
00381 
00382     /**
00383     * @brief Sends a a payload and blocks until there is a response back,
00384     * or the receive windows have closed or the hard timeout has passed.
00385     * @param Transmit type
00386     * @param Port to use for transmit
00387     * @param Payload buffer
00388     * @param Size of payload buffer
00389     * @return Returns if sucessfull or if a MAC transmit error.
00390     */
00391     uint8_t macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size);
00392 
00393     /**
00394     * @brief Parses the input buffer and copies the received payload into
00395     * the "received payload" buffer when a "mac rx" message has been received.
00396     * @return Returns 0 (NoError) or otherwise one of the MacTransmitErrorCodes.
00397     */
00398     uint8_t onMacRX();
00399 
00400     /**
00401     * @brief Private method to read serial port with timeout
00402     * @param The time to wait for in milliseconds.
00403     * @return Returns character or -1 on timeout
00404     */
00405     int timedRead(int _timeout);
00406 
00407     /**
00408     * @brief Read characters into buffer.
00409     * Terminates if length characters have been read, timeout, or
00410     * if the terminator character has been detected
00411     * @param The terminator character to look for
00412     * @param The buffer to read into.
00413     * @param The size of the buffer.
00414     * @return The number of bytes read. 0 means no valid data found.
00415     */
00416     size_t readBytesUntil(char terminator, char *buffer, size_t length);
00417 };
00418 
00419 #endif // RN2483