A mbed library for the RN2483. Heavily based on the Sodaq_RN2483 library for Arduino (https://github.com/SodaqMoja/Sodaq_RN2483). This is currently under-going initial testing, but seems to work! Tested on a NRF51 and FRDM K64F.
Dependents: rn2483-TestProgram
RN2483.h
- Committer:
- azazeal88
- Date:
- 2016-11-21
- Revision:
- 4:0c066401ae12
- Parent:
- 3:ee222a99783c
- Child:
- 5:eb983e9336a7
File content as of revision 4:0c066401ae12:
/* * Copyright (c) 2016 Dan Knox. All rights reserved. * * This file is part of RN2483. * * RN2483 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or(at your option) any later version. * * RN2483 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with RN2483. If not, see * <http://www.gnu.org/licenses/>. */ #ifndef _RN2483_h #define _RN2483_h #include "mbed.h" #include <stdint.h> //#define USE_DYNAMIC_BUFFER #define DEFAULT_INPUT_BUFFER_SIZE 64 #define DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE 32 #define DEFAULT_TIMEOUT 120 #define RECEIVE_TIMEOUT 60000 #define DEFAULT_FSB 2 #define DEFAULT_PWR_IDX_868 1 #define DEFAULT_PWR_IDX_915 5 #define DEFAULT_SF_868 7 #define DEFAULT_SF_915 7 #define ENABLE_SLEEP // Available error codes. enum MacTransmitErrorCodes { NoError = 0, NoResponse = 1, Timedout = 2, PayloadSizeError = 3, InternalError = 4, Busy = 5, NetworkFatalError = 6, NotConnected = 7, NoAcknowledgment = 8, Silent = 9, }; // Provides a simple, abstracted interface to Microchip's RN2483 LoRaWAN module. class RN2483 { public: /** * @brief Create a new instance of the RN2483. * @param Serial TX pin name. * @param Serial RX pin name. */ RN2483(PinName tx, PinName rx); /** * @return Returns the default device baud rate. */ uint32_t getDefaultBaudRate() { return 57600; }; /** * @brief Initialise settings and connect to network using Over The Air activation. * @param devEUI provided by LoRaWAN Network server registration. * @param appEUI provided by LoRaWAN Network server registration. * @param appKey provided by LoRaWAN Network server registration. * @return Returns true if network confirmation and able to save settings. */ bool initOTA(const uint8_t devEUI[8], const uint8_t appEUI[8], const uint8_t appKey[16], bool adr = true); /** * @brief Initializes the device and connects to the network using Activation By Personalization. * @param devADDR provided by LoRaWAN Network server registration. * @param appSKey provided by LoRaWAN Network server registration. * @param nwkSKey provided by LoRaWAN Network server registration. * @return Returns true if the parameters were valid and able to save settings. */ bool initABP(const uint8_t devAddr[4], const uint8_t appSKey[16], const uint8_t nwkSKey[16], bool adr = true); /** * @brief Attempts to connect to the network using Over The Air Activation. * @return Returns true if able to join network. */ bool joinOTTA(); /** * @brief Attempts to connect to the network using Activation By Personalization. * @return Returns true if able to join network. */ bool joinABP(); /** * @brief Sends the given payload without acknowledgement. * @param Port to use for transmission. * @param Payload buffer * @param Payload buffer size * @return Returns 0 (NoError) when data was sucessfully fowarded to radio, otherwise returns MacTransmitErrorCode. */ uint8_t send(uint8_t port, const uint8_t* payload, uint8_t size); /** * @brief Sends the given payload with acknowledgement. * @param Port to use for transmission. * @param Payload buffer * @param Payload buffer size * @param Number of transmission retries in event of network transmission failure. * @return Returns 0 (NoError) when network acks transmission, otherwise returns MacTransmitErrorCode. */ uint8_t sendReqAck(uint8_t port, const uint8_t* payload, uint8_t size, uint8_t maxRetries); /** * @brief Copies the latest received packet (optionally starting from the "payloadStartPosition" of the payload). * @param Buffer to read into. * @param Buffer size. * @return Returns the number of bytes written or 0 if no packet is received since last transmission. */ uint16_t receive(uint8_t* buffer, uint16_t size, uint16_t payloadStartPosition = 0); /** * @brief Gets the preprogrammed EUI node address from the module in HEX. * @param Buffer to read into. * @param Buffer size. * @return Returns the number of bytes written or 0 in case of error.. */ uint8_t getHWEUI(uint8_t* buffer, uint8_t size); /** * @brief Informs the RN2483 to do an ADC conversion on the VDD. * @return Returns mV as a decimal from 0 to 3600. */ bool getVDD(long *vdd); /** * @brief Enables all the channels that belong to the given Frequency Sub-Band (FSB) * disables the rest. * @param FSB is [1, 8] or 0 to enable all channels. * @return Returns true if all channels were set successfully. */ bool setFsbChannels(uint8_t fsb); /** * @brief Sets the spreading factor. * @param Spreading factor parameter. * @return Returns true if was set successfully. */ bool setSpreadingFactor(uint8_t spreadingFactor); /** * @brief Sets the power index * @param 868MHz: 1 to 5 / 915MHz: 5, 7, 8, 9 or 10. * @return Returns true if succesful. */ bool setPowerIndex(uint8_t powerIndex); /** * @brief Sets the time interval for the link check process. When the time expires, the next application * packet will include a link check command to the server. * @param Decimal number that sets the time interval in seconds, from 0 to 65535. 0 disables link check process. * @return Returns true if parameter is valid or false if time interval is not valid. */ bool setLinkCheckInterval(uint8_t linkCheckInterval); /** * @brief Sets the battery level required for the Device Status Answer frame in LoRaWAN Class A Protocol. * @param temperature Decimal number between 0-255 representing battery level. 0 means external power, 1 means * low level, 254 means high level, 255 means the device was unable to measure battery level. * @return Returns true if battery level is valid or false if value not valid. */ bool setBattery(uint8_t batLvl); /** * @brief Sets the module operation frequency on a given channel ID. * @param Channel ID from 3 - 15. * @param Decimal number representing the frequency. * 863000000 to 870000000 or 433050000 to 434790000 in Hz * @return Returns true if parameters are valid or false if not. */ bool setChannelFreq(uint8_t channelID, uint32_t frequency); /** * @brief Sets the duty cycle allowed on the given channel ID. * @param Channel ID to set duty cycle (0-15), * @param Duty cycle is 0 - 100% as a float. * @return Returns true if parameters are valid or false if not. */ bool setDutyCycle(uint8_t channelID, float dutyCycle); /** * @brief Sets the data rate for a given channel ID. * Please refer to the LoRaWAN spec for the actual values. * @param Channel ID from 0 - 15. * @param Number representing the minimum data rate range from 0 to 7. * @param Number representing the maximum data rate range from 0 to 7 * @return Returns true if parameters are valid or false if not. */ bool setDrRange(uint8_t channelID, uint8_t minRange, uint8_t maxRange); /** * @brief Sets a given channel ID to be enabled or disabled. * @param Channel ID from 0 - 15. * @param Flag representing if channel is enabled or disabled. * Warning: duty cycle, frequency and data range must be set for a channel * before enabling! * @return Returns true if parameters are valid or false if not. */ bool setStatus(uint8_t channelID, bool status); /** * @brief The network can issue a command to silence the RN2483. This restores the module. * @return Returns true if parameters are valid or false if not. */ bool forceEnable(); /** * @brief Saves configurable parameters to eeprom. * @return Returns true if parameters are valid or false if not. */ bool saveConfiguration(); /** * @brief Sends the command together with the given, paramValue (optional) * @param Command should include a trailing space if paramValue is set. Refer to RN2483 command ref * @param Command Parameter to send * @param Size of param buffer * @return Returns true on success or false if invalid. */ bool sendCommand(const char* command, const uint8_t* paramValue, uint16_t size); bool sendCommand(const char* command, uint8_t paramValue); bool sendCommand(const char* command, const char* paramValue = NULL); /** * @brief Sends the command together with the given paramValue (optional) * @param MAC param should include a trailing space if paramValue is set. Refer to RN2483 command ref. * @param Param value to send * @param Size of Param buffer * @return Returns true on success or false if invalid. */ bool setMacParam(const char* paramName, const uint8_t* paramValue, uint16_t size); bool setMacParam(const char* paramName, uint8_t paramValue); bool setMacParam(const char* paramName, const char* paramValue); #ifdef ENABLE_SLEEP /** * @brief Sends a serial line break to wake up the RN2483 */ void wakeUp(); /** * @brief Sends the RN2483 to sleep for a finite length of time. * @param Milliseconds to sleep for, range is 100 to 4294967295 */ void sleep(uint32_t); /** * @brief Sends the RN2483 to sleep for a finite length of time. * Roughly three days. */ void sleep(); #endif #ifdef USE_DYNAMIC_BUFFER // Sets the size of the input buffer. // Needs to be called before initOTA()/initABP(). void setInputBufferSize(uint16_t value) { this->inputBufferSize = value; }; // Sets the size of the "Received Payload" buffer. // Needs to be called before initOTA()/initABP(). void setReceivedPayloadBufferSize(uint16_t value) { this->receivedPayloadBufferSize = value; }; #endif private: Serial _RN2483; // The size of the input buffer. Equals DEFAULT_INPUT_BUFFER_SIZE // by default or (optionally) a user-defined value when using USE_DYNAMIC_BUFFER. uint16_t inputBufferSize; // The size of the received payload buffer. Equals DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE // by default or (optionally) a user-defined value when using USE_DYNAMIC_BUFFER. uint16_t receivedPayloadBufferSize; // Flag used to make sure the received payload buffer is // current with the latest transmission. bool packetReceived; // Used to distinguise between RN2483 and RN2903. // Currently only being set during reset(). bool isRN2903; #ifdef USE_DYNAMIC_BUFFER // Flag to make sure the buffers are not allocated more than once. bool isBufferInitialized; char* inputBuffer; char* receivedPayloadBuffer; #else char inputBuffer[DEFAULT_INPUT_BUFFER_SIZE]; char receivedPayloadBuffer[DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE]; #endif /** * @brief Takes care of the init tasks common to both initOTA() and initABP. */ inline void init(); /** * @brief Reads a line from the device serial stream. * @param Buffer to read into. * @param Size of buffer. * @param Position to start from. * @return Number of bytes read. */ uint16_t readLn(char* buffer, uint16_t size, uint16_t start = 0); /** * @brief Reads a line from the input buffer * @return Number of bytes read. */ uint16_t readLn() { return readLn(this->inputBuffer, this->inputBufferSize); }; /** * @brief Waits for the given string. * @param String to look for. * @param Timeout Period * @param Position to start from. * @return Returns true if the string is received before a timeout. * Returns false if a timeout occurs or if another string is received. */ bool expectString(const char* str, uint16_t timeout = DEFAULT_TIMEOUT); /** * @brief Looks for an 'OK' response from the RN2483 * @return Returns true if the string is received before a timeout. * Returns false if a timeout occurs or if another string is received. */ bool expectOK(); /** * @brief Sends a reset command to the module * Also sets-up some initial parameters like power index, SF and FSB channels. * @return Waits for sucess reponse or timeout. */ bool resetDevice(); /** * @brief Sends a join command to the network * @param Type of join, OTAA or ABP * @return Returns true on success or false if fail. */ bool joinNetwork(const char* type); /** * @brief Returns the enum that is mapped to the given "error" message * @param Error to lookup. * @return Returns the enum */ uint8_t lookupMacTransmitError(const char* error); /** * @brief Sends a a payload and blocks until there is a response back, * or the receive windows have closed or the hard timeout has passed. * @param Transmit type * @param Port to use for transmit * @param Payload buffer * @param Size of payload buffer * @return Returns if sucessfull or if a MAC transmit error. */ uint8_t macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size); /** * @brief Parses the input buffer and copies the received payload into * the "received payload" buffer when a "mac rx" message has been received. * @return Returns 0 (NoError) or otherwise one of the MacTransmitErrorCodes. */ uint8_t onMacRX(); /** * @brief Private method to read serial port with timeout * @param The time to wait for in milliseconds. * @return Returns character or -1 on timeout */ int timedRead(int _timeout); /** * @brief Read characters into buffer. * Terminates if length characters have been read, timeout, or * if the terminator character has been detected * @param The terminator character to look for * @param The buffer to read into. * @param The size of the buffer. * @return The number of bytes read. 0 means no valid data found. */ size_t readBytesUntil(char terminator, char *buffer, size_t length); }; #endif // RN2483