APS Lab
/
STM32F4_SmartMesh_QSL
SmartMesh QSL for STM32F4 version
Fork of COG-AD4050_QSL by
Embed:
(wiki syntax)
Show/hide line numbers
dn_serial_mt.c
00001 /* 00002 Copyright (c) 2014, Dust Networks. All rights reserved. 00003 00004 HDLC library. 00005 00006 \license See attached DN_LICENSE.txt. 00007 */ 00008 00009 #include "dn_serial_mt.h" 00010 #include "dn_hdlc.h" 00011 00012 //=========================== variables ======================================= 00013 00014 typedef struct { 00015 // packet IDs 00016 uint8_t txPacketId; 00017 uint8_t rxPacketId; 00018 // reply callback 00019 uint8_t replyCmdId; 00020 dn_serial_reply_cbt replyCb; 00021 // request callback 00022 dn_serial_request_cbt requestCb; 00023 } dn_serial_mt_vars_t; 00024 00025 dn_serial_mt_vars_t dn_serial_mt_vars; 00026 00027 //=========================== prototype ======================================= 00028 00029 void dn_serial_mt_rxHdlcFrame(uint8_t* rxFrame, uint8_t rxFrameLen); 00030 void dn_serial_mt_dispatch_response(uint8_t cmdId, uint8_t *payload, uint8_t length); 00031 void dn_serial_sendReply(uint8_t cmdId, uint8_t rc, uint8_t *payload, uint8_t length); 00032 00033 //=========================== public ========================================== 00034 00035 /** 00036 \brief Setting up the instance. 00037 */ 00038 void dn_serial_mt_init(dn_serial_request_cbt requestCb) { 00039 // reset local variables 00040 memset(&dn_serial_mt_vars, 0, sizeof(dn_serial_mt_vars)); 00041 00042 // initialize variables 00043 dn_serial_mt_vars.txPacketId = DN_SERIAL_PACKETID_NOTSET; 00044 dn_serial_mt_vars.rxPacketId = DN_SERIAL_PACKETID_NOTSET; 00045 dn_serial_mt_vars.requestCb = requestCb; 00046 00047 // initialize the HDLC module 00048 dn_hdlc_init(dn_serial_mt_rxHdlcFrame); 00049 } 00050 00051 dn_err_t dn_serial_mt_sendRequest(uint8_t cmdId, uint8_t extraFlags, uint8_t* payload, uint8_t length, dn_serial_reply_cbt replyCb) { 00052 uint8_t i; 00053 uint8_t flags; 00054 00055 // register reply callback 00056 dn_serial_mt_vars.replyCmdId = cmdId; 00057 dn_serial_mt_vars.replyCb = replyCb; 00058 00059 // calculate the flags 00060 flags = 0; 00061 if (dn_serial_mt_vars.txPacketId==DN_SERIAL_PACKETID_NOTSET) { 00062 dn_serial_mt_vars.txPacketId = 0x00; 00063 flags |= 0x01<<3; // sync bit 00064 flags |= dn_serial_mt_vars.txPacketId<<1; // txPacketId 00065 } else { 00066 flags |= dn_serial_mt_vars.txPacketId<<1; // txPacketId 00067 } 00068 flags |= extraFlags; 00069 00070 // send the frame over serial 00071 dn_hdlc_outputOpen(); 00072 dn_hdlc_outputWrite(cmdId); // cmdId 00073 dn_hdlc_outputWrite(length); // length 00074 dn_hdlc_outputWrite(flags); // flags 00075 for (i=0; i<length; i++) { // payload 00076 dn_hdlc_outputWrite(payload[i]); 00077 } 00078 dn_hdlc_outputClose(); 00079 00080 // toggle the txPacketId 00081 if (dn_serial_mt_vars.txPacketId==0x00) { 00082 dn_serial_mt_vars.txPacketId = 0x01; 00083 } else { 00084 dn_serial_mt_vars.txPacketId = 0x00; 00085 } 00086 00087 return DN_ERR_NONE; 00088 } 00089 00090 //=========================== private ========================================= 00091 00092 void dn_serial_mt_rxHdlcFrame(uint8_t* rxFrame, uint8_t rxFrameLen) { 00093 // fields in the serial API header 00094 uint8_t cmdId; 00095 uint8_t length; 00096 uint8_t flags; 00097 uint8_t isResponse; 00098 uint8_t packetId; 00099 uint8_t isSync; 00100 // misc 00101 uint8_t isRepeatId; 00102 00103 // assert length is OK 00104 if (rxFrameLen<3) { 00105 return; 00106 } 00107 00108 // parse header 00109 cmdId = rxFrame[0]; 00110 length = rxFrame[1]; 00111 flags = rxFrame[2]; 00112 isResponse = ((flags & DN_SERIAL_API_MASK_RESPONSE)!=0); 00113 packetId = ((flags & DN_SERIAL_API_MASK_PACKETID)!=0); 00114 isSync = ((flags & DN_SERIAL_API_MASK_SYNC)!=0); 00115 00116 // check if valid packet ID 00117 if (isResponse) { 00118 // dispatch 00119 00120 dn_serial_mt_dispatch_response(cmdId,&rxFrame[3],length); 00121 } else { 00122 if (isSync || packetId!=dn_serial_mt_vars.rxPacketId) { 00123 isRepeatId = FALSE; 00124 dn_serial_mt_vars.rxPacketId = packetId; 00125 } else { 00126 isRepeatId = TRUE; 00127 } 00128 00129 // ACK 00130 dn_serial_sendReply(cmdId,DN_SERIAL_RC_OK,NULL,0); 00131 00132 // dispatch 00133 if (isRepeatId==FALSE && length>0 && dn_serial_mt_vars.requestCb!=NULL) { 00134 dn_serial_mt_vars.requestCb(cmdId,flags,&rxFrame[3],length); 00135 } 00136 } 00137 } 00138 00139 /** 00140 \note Not public, only used for sending ACK. 00141 */ 00142 void dn_serial_sendReply(uint8_t cmdId, uint8_t rc, uint8_t *payload, uint8_t length) { 00143 uint8_t i; 00144 00145 dn_hdlc_outputOpen(); 00146 dn_hdlc_outputWrite(cmdId); // cmdId 00147 dn_hdlc_outputWrite(length); // length 00148 dn_hdlc_outputWrite(DN_SERIAL_API_MASK_RESPONSE | (dn_serial_mt_vars.rxPacketId<<1)); // flags 00149 dn_hdlc_outputWrite(rc); // rc 00150 for (i=0; i<length; i++) { // payload 00151 dn_hdlc_outputWrite(payload[i]); 00152 } 00153 dn_hdlc_outputClose(); 00154 } 00155 00156 void dn_serial_mt_dispatch_response(uint8_t cmdId, uint8_t* payload, uint8_t length) { 00157 uint8_t rc; 00158 00159 rc = payload[0]; 00160 if (cmdId==dn_serial_mt_vars.replyCmdId && dn_serial_mt_vars.replyCb!=NULL) { 00161 00162 // call the callback 00163 (dn_serial_mt_vars.replyCb)(cmdId,rc,&payload[1],length); 00164 00165 // reset 00166 dn_serial_mt_vars.replyCmdId = 0x00; 00167 dn_serial_mt_vars.replyCb = NULL; 00168 } 00169 } 00170 00171 //=========================== helpers ========================================= 00172
Generated on Tue Jul 12 2022 21:33:36 by 1.7.2