The NSL01 library contains all functions for controlling the NSL01 LoRaWAN shield from mCloud System GmbH. The NSL01 is a professional plug & play LoRaWAN shield for a wide range of STM32 Nucleo-64 boards with Arduino Uno Rev 3 connectivity. For more information about the NSL01 LoRaWAN shield: http://www.mcloud-systems.com/nsl01-lorawan-nucleo-arduino-shield

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NSL01_HCI_Layer.cpp Source File

NSL01_HCI_Layer.cpp

00001 /*******************************************************************************
00002  *  Functions for NSL01 class to create a Human Control Interface (HCI) for
00003  *  controlling the onboard RF radio module.
00004  *
00005  *  For more information about the NSL01 LoRaWAN shield:
00006  *      http://www.mcloud-systems.com/nsl01-lorawan-nucleo-arduino-shield
00007  *
00008  *  @note The NSL01_HCI_Layer files are included in the dependencies directory
00009  *        of the project and these files are necessary for the NSL01 class!
00010  *
00011  *  @author  -
00012  *  @version 1.0
00013  *  @date    20-June-2018
00014 *******************************************************************************/
00015 
00016 //------------------------------------------------------------------------------
00017 //
00018 // Include Files
00019 //
00020 //------------------------------------------------------------------------------
00021 
00022 #include "./dependencies/NSL01_HCI_Layer.h"
00023 #include <string.h>
00024 
00025 //------------------------------------------------------------------------------
00026 //
00027 //  Forward Declaration
00028 //
00029 //------------------------------------------------------------------------------
00030 
00031 //--SLIP Message Receiver Callback
00032 static UINT8*   WiMOD_HCI_ProcessRxMessage(UINT8* rxData, int rxLength);
00033 
00034 //------------------------------------------------------------------------------
00035 //
00036 // Declare Layer Instance
00037 //
00038 //------------------------------------------------------------------------------
00039 
00040 typedef struct
00041 {
00042     //--CRC Error counter
00043     UINT32                  CRCErrors;
00044 
00045     //--RxMessage
00046     TWiMOD_HCI_Message*     RxMessage;
00047 
00048     //--Receiver callback
00049     TWiMOD_HCI_CbRxMessage  CbRxMessage;
00050 
00051 }TWiMOD_HCI_MsgLayer;
00052 
00053 //------------------------------------------------------------------------------
00054 //
00055 //  Section RAM
00056 //
00057 //------------------------------------------------------------------------------
00058 
00059 //--Reserve HCI Instance
00060 static TWiMOD_HCI_MsgLayer  HCI;
00061 
00062 //--Reserve one TxBuffer
00063 static UINT8                TxBuffer[sizeof( TWiMOD_HCI_Message ) * 2 + 2];
00064 
00065 //------------------------------------------------------------------------------
00066 //
00067 //  Function: WiMOD_HCI_Init
00068 //
00069 //  @brief Function to initialize Human Control Interface (HCI) message layer.
00070 //
00071 //  @param cbRxMessage : Function pointer
00072 //  @param rxMessage   : Pointer to HCI Rx message struct
00073 //
00074 //------------------------------------------------------------------------------
00075 
00076 void
00077 WiMOD_HCI_Init(TWiMOD_HCI_CbRxMessage   cbRxMessage,    //-HCI msg recv. callback
00078                TWiMOD_HCI_Message*      rxMessage)      //-Initial rxMessage
00079 {
00080     //--Init error counter
00081     HCI.CRCErrors   =   0;
00082 
00083     //--Save receiver callback
00084     HCI.CbRxMessage =   cbRxMessage;
00085 
00086     //--Save RxMessage
00087     HCI.RxMessage   =   rxMessage;
00088 
00089     //--Init SLIP
00090     SLIP_Init(WiMOD_HCI_ProcessRxMessage);
00091 
00092     //--Init first RxBuffer to SAP_ID of HCI message, size without 16-Bit length field
00093     SLIP_SetRxBuffer(&rxMessage->SapID, sizeof(TWiMOD_HCI_Message) - sizeof(UINT16));
00094 
00095     //--Init serial (UART) device
00096     SerialDevice_Open(Baudrate_115200, DataBits_8);
00097 }
00098 
00099 //------------------------------------------------------------------------------
00100 //
00101 //  Function: WiMOD_HCI_SendMessage
00102 //
00103 //  @brief Function to transmit a message via specified Human Control Interface
00104 //         (HCI) with or without payload.
00105 //
00106 //  @param txMessage : Pointer to HCI Tx message struct
00107 //
00108 //  @returns 1 on success, -1 on error
00109 //
00110 //------------------------------------------------------------------------------
00111 
00112 int 
00113 WiMOD_HCI_SendMessage(TWiMOD_HCI_Message* txMessage)
00114 {
00115     //-------------------------------------------------------------
00116     // 1. Check parameter
00117     //-------------------------------------------------------------
00118 
00119     // 1.1 Check ptr
00120     if (!txMessage)
00121     {
00122         //--Error
00123         return -1;
00124     }
00125 
00126     //-------------------------------------------------------------
00127     // 2. Calculate CRC16 over header and optional payload data
00128     //-------------------------------------------------------------
00129 
00130     UINT16 crc16 = CRC16_Calc(&txMessage->SapID,
00131                               txMessage->Length + WIMOD_HCI_MSG_HEADER_SIZE,
00132                               CRC16_INIT_VALUE);
00133 
00134     // 2.1 Get first complement
00135     crc16 = ~crc16;
00136 
00137     // 2.2 Attach CRC16 and correct length, LSB first
00138     txMessage->Payload[txMessage->Length]     = LOBYTE(crc16);
00139     txMessage->Payload[txMessage->Length + 1] = HIBYTE(crc16);
00140 
00141     //-------------------------------------------------------------
00142     // 3. Perform SLIP encoding:
00143     //    - start transmission with SAP_ID
00144     //    - correct length by header size
00145     //-------------------------------------------------------------
00146 
00147     int txLength = SLIP_EncodeData(TxBuffer,
00148                                    sizeof(TxBuffer),
00149                                    &txMessage->SapID,
00150                                    txMessage->Length + WIMOD_HCI_MSG_HEADER_SIZE + WIMOD_HCI_MSG_FCS_SIZE);
00151 
00152     //--Initialize return value
00153     int return_value;
00154 
00155     //--Check if message is okay
00156     if (txLength > 0)
00157     {
00158         //--Transmit wakeup chars
00159         for(int i= 0; i < 40; i++)
00160             SerialDevice_SendByte(SLIP_END);
00161 
00162         //-------------------------------------------------------------
00163         // 4. Transmit octet sequence over serial device
00164         //-------------------------------------------------------------
00165         return_value = SerialDevice_SendData(TxBuffer, txLength);
00166 
00167         #ifdef DEBUG
00168             comm_pc.printf("\r\n Return value SerialDevice_SendData: %i\n\r", return_value);
00169         #endif
00170 
00171         //--Evaluate result
00172         if ( return_value > 0 )
00173         {
00174             //--Return ok
00175             return 1;
00176         }
00177     }
00178 
00179     // Error - SLIP layer couldn't encode message - buffer to small ?
00180     return -1;
00181 }
00182 
00183 //------------------------------------------------------------------------------
00184 //
00185 //  Function: WiMOD_HCI_Process
00186 //
00187 //  @brief Function to read/process incoming serial data, which is a user
00188 //         triggered function without using interrupts.
00189 //
00190 //  @note This function is not necessary at the moment, because the incoming
00191 //        serial data is processed via an Interrupt Service Routine (ISR).
00192 //
00193 //------------------------------------------------------------------------------
00194 
00195 void
00196 WiMOD_HCI_Process()
00197 {
00198     UINT8   rxBuf[20];
00199 
00200     //--Read small chunk of data
00201     int rxLength = SerialDevice_ReadData(rxBuf, sizeof(rxBuf));
00202 
00203     //--Check if data is available
00204     if (rxLength > 0)
00205     {
00206         //--Yes, forward to SLIP decoder, decoded SLIP message will be passed to
00207         //--function "WiMOD_HCI_ProcessRxMessage"
00208         SLIP_DecodeData(rxBuf, rxLength);
00209     }
00210 }
00211 
00212 //------------------------------------------------------------------------------
00213 //
00214 //  Function: WiMOD_HCI_ProcessRxMessage
00215 //
00216 //  @brief Internal function to process received SLIP message and return new
00217 //         Rx buffer.
00218 //
00219 //  @param rxData   : Pointer to Rx message
00220 //  @param rxLength : Length of Rx message
00221 //
00222 //  @returns pointer to first byte of Rx message
00223 //
00224 //------------------------------------------------------------------------------
00225 
00226 static UINT8*
00227 WiMOD_HCI_ProcessRxMessage(UINT8* rxData, int rxLength)
00228 {
00229     //--Check min length
00230     if (rxLength >= (WIMOD_HCI_MSG_HEADER_SIZE + WIMOD_HCI_MSG_FCS_SIZE))
00231     {
00232         if (CRC16_Check(rxData, rxLength, CRC16_INIT_VALUE))
00233         {
00234             //--Check if receiver is registered
00235             if (HCI.CbRxMessage)
00236             {
00237                 //--Yes, complete message info
00238                 HCI.RxMessage->Length = rxLength - (WIMOD_HCI_MSG_HEADER_SIZE + WIMOD_HCI_MSG_FCS_SIZE);
00239 
00240                 //--Call upper layer receiver and save new RxMessage
00241                 HCI.RxMessage = (*HCI.CbRxMessage)(HCI.RxMessage);                
00242             }
00243         }
00244         else
00245         {
00246             HCI.CRCErrors++;
00247         }
00248     }
00249 
00250     //--Check if free HCI message is available
00251     if (HCI.RxMessage)
00252     {
00253         //--Yes, return pointer to first byte
00254         return &HCI.RxMessage->SapID;
00255     }
00256 
00257     //--Error, disable SLIP decoder
00258     return 0;
00259 }
00260 
00261 //------------------------------------------------------------------------------
00262 // end of file
00263 //------------------------------------------------------------------------------