The NSL01 library contains the software stack to control 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 have a look at: http://www.mcloud-systems.com/nsl01-lorawan-nucleo-arduino-shield
Fork of NSL01 by
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 //------------------------------------------------------------------------------
Generated on Tue Jul 12 2022 20:20:04 by
1.7.2
