SmartMesh QSL for STM32F4 version

Fork of COG-AD4050_QSL by APS Lab

Committer:
APS_Lab
Date:
Thu Jul 12 09:19:12 2018 +0000
Revision:
1:b909b8399252
Parent:
0:8ca1e814a851
SmartMesh for STM32F4 version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
APS_Lab 0:8ca1e814a851 1 /*
APS_Lab 0:8ca1e814a851 2 Copyright (c) 2014, Dust Networks. All rights reserved.
APS_Lab 0:8ca1e814a851 3
APS_Lab 0:8ca1e814a851 4 HDLC library.
APS_Lab 0:8ca1e814a851 5
APS_Lab 0:8ca1e814a851 6 \license See attached DN_LICENSE.txt.
APS_Lab 0:8ca1e814a851 7 */
APS_Lab 0:8ca1e814a851 8
APS_Lab 0:8ca1e814a851 9 #include "dn_serial_mt.h"
APS_Lab 0:8ca1e814a851 10 #include "dn_hdlc.h"
APS_Lab 0:8ca1e814a851 11
APS_Lab 0:8ca1e814a851 12 //=========================== variables =======================================
APS_Lab 0:8ca1e814a851 13
APS_Lab 0:8ca1e814a851 14 typedef struct {
APS_Lab 0:8ca1e814a851 15 // packet IDs
APS_Lab 0:8ca1e814a851 16 uint8_t txPacketId;
APS_Lab 0:8ca1e814a851 17 uint8_t rxPacketId;
APS_Lab 0:8ca1e814a851 18 // reply callback
APS_Lab 0:8ca1e814a851 19 uint8_t replyCmdId;
APS_Lab 0:8ca1e814a851 20 dn_serial_reply_cbt replyCb;
APS_Lab 0:8ca1e814a851 21 // request callback
APS_Lab 0:8ca1e814a851 22 dn_serial_request_cbt requestCb;
APS_Lab 0:8ca1e814a851 23 } dn_serial_mt_vars_t;
APS_Lab 0:8ca1e814a851 24
APS_Lab 0:8ca1e814a851 25 dn_serial_mt_vars_t dn_serial_mt_vars;
APS_Lab 0:8ca1e814a851 26
APS_Lab 0:8ca1e814a851 27 //=========================== prototype =======================================
APS_Lab 0:8ca1e814a851 28
APS_Lab 0:8ca1e814a851 29 void dn_serial_mt_rxHdlcFrame(uint8_t* rxFrame, uint8_t rxFrameLen);
APS_Lab 0:8ca1e814a851 30 void dn_serial_mt_dispatch_response(uint8_t cmdId, uint8_t *payload, uint8_t length);
APS_Lab 0:8ca1e814a851 31 void dn_serial_sendReply(uint8_t cmdId, uint8_t rc, uint8_t *payload, uint8_t length);
APS_Lab 0:8ca1e814a851 32
APS_Lab 0:8ca1e814a851 33 //=========================== public ==========================================
APS_Lab 0:8ca1e814a851 34
APS_Lab 0:8ca1e814a851 35 /**
APS_Lab 0:8ca1e814a851 36 \brief Setting up the instance.
APS_Lab 0:8ca1e814a851 37 */
APS_Lab 0:8ca1e814a851 38 void dn_serial_mt_init(dn_serial_request_cbt requestCb) {
APS_Lab 0:8ca1e814a851 39 // reset local variables
APS_Lab 0:8ca1e814a851 40 memset(&dn_serial_mt_vars, 0, sizeof(dn_serial_mt_vars));
APS_Lab 0:8ca1e814a851 41
APS_Lab 0:8ca1e814a851 42 // initialize variables
APS_Lab 0:8ca1e814a851 43 dn_serial_mt_vars.txPacketId = DN_SERIAL_PACKETID_NOTSET;
APS_Lab 0:8ca1e814a851 44 dn_serial_mt_vars.rxPacketId = DN_SERIAL_PACKETID_NOTSET;
APS_Lab 0:8ca1e814a851 45 dn_serial_mt_vars.requestCb = requestCb;
APS_Lab 0:8ca1e814a851 46
APS_Lab 0:8ca1e814a851 47 // initialize the HDLC module
APS_Lab 0:8ca1e814a851 48 dn_hdlc_init(dn_serial_mt_rxHdlcFrame);
APS_Lab 0:8ca1e814a851 49 }
APS_Lab 0:8ca1e814a851 50
APS_Lab 0:8ca1e814a851 51 dn_err_t dn_serial_mt_sendRequest(uint8_t cmdId, uint8_t extraFlags, uint8_t* payload, uint8_t length, dn_serial_reply_cbt replyCb) {
APS_Lab 0:8ca1e814a851 52 uint8_t i;
APS_Lab 0:8ca1e814a851 53 uint8_t flags;
APS_Lab 0:8ca1e814a851 54
APS_Lab 0:8ca1e814a851 55 // register reply callback
APS_Lab 0:8ca1e814a851 56 dn_serial_mt_vars.replyCmdId = cmdId;
APS_Lab 0:8ca1e814a851 57 dn_serial_mt_vars.replyCb = replyCb;
APS_Lab 0:8ca1e814a851 58
APS_Lab 0:8ca1e814a851 59 // calculate the flags
APS_Lab 0:8ca1e814a851 60 flags = 0;
APS_Lab 0:8ca1e814a851 61 if (dn_serial_mt_vars.txPacketId==DN_SERIAL_PACKETID_NOTSET) {
APS_Lab 0:8ca1e814a851 62 dn_serial_mt_vars.txPacketId = 0x00;
APS_Lab 0:8ca1e814a851 63 flags |= 0x01<<3; // sync bit
APS_Lab 0:8ca1e814a851 64 flags |= dn_serial_mt_vars.txPacketId<<1; // txPacketId
APS_Lab 0:8ca1e814a851 65 } else {
APS_Lab 0:8ca1e814a851 66 flags |= dn_serial_mt_vars.txPacketId<<1; // txPacketId
APS_Lab 0:8ca1e814a851 67 }
APS_Lab 0:8ca1e814a851 68 flags |= extraFlags;
APS_Lab 0:8ca1e814a851 69
APS_Lab 0:8ca1e814a851 70 // send the frame over serial
APS_Lab 0:8ca1e814a851 71 dn_hdlc_outputOpen();
APS_Lab 0:8ca1e814a851 72 dn_hdlc_outputWrite(cmdId); // cmdId
APS_Lab 0:8ca1e814a851 73 dn_hdlc_outputWrite(length); // length
APS_Lab 0:8ca1e814a851 74 dn_hdlc_outputWrite(flags); // flags
APS_Lab 0:8ca1e814a851 75 for (i=0; i<length; i++) { // payload
APS_Lab 0:8ca1e814a851 76 dn_hdlc_outputWrite(payload[i]);
APS_Lab 0:8ca1e814a851 77 }
APS_Lab 0:8ca1e814a851 78 dn_hdlc_outputClose();
APS_Lab 0:8ca1e814a851 79
APS_Lab 0:8ca1e814a851 80 // toggle the txPacketId
APS_Lab 0:8ca1e814a851 81 if (dn_serial_mt_vars.txPacketId==0x00) {
APS_Lab 0:8ca1e814a851 82 dn_serial_mt_vars.txPacketId = 0x01;
APS_Lab 0:8ca1e814a851 83 } else {
APS_Lab 0:8ca1e814a851 84 dn_serial_mt_vars.txPacketId = 0x00;
APS_Lab 0:8ca1e814a851 85 }
APS_Lab 0:8ca1e814a851 86
APS_Lab 0:8ca1e814a851 87 return DN_ERR_NONE;
APS_Lab 0:8ca1e814a851 88 }
APS_Lab 0:8ca1e814a851 89
APS_Lab 0:8ca1e814a851 90 //=========================== private =========================================
APS_Lab 0:8ca1e814a851 91
APS_Lab 0:8ca1e814a851 92 void dn_serial_mt_rxHdlcFrame(uint8_t* rxFrame, uint8_t rxFrameLen) {
APS_Lab 0:8ca1e814a851 93 // fields in the serial API header
APS_Lab 0:8ca1e814a851 94 uint8_t cmdId;
APS_Lab 0:8ca1e814a851 95 uint8_t length;
APS_Lab 0:8ca1e814a851 96 uint8_t flags;
APS_Lab 0:8ca1e814a851 97 uint8_t isResponse;
APS_Lab 0:8ca1e814a851 98 uint8_t packetId;
APS_Lab 0:8ca1e814a851 99 uint8_t isSync;
APS_Lab 0:8ca1e814a851 100 // misc
APS_Lab 0:8ca1e814a851 101 uint8_t isRepeatId;
APS_Lab 0:8ca1e814a851 102
APS_Lab 0:8ca1e814a851 103 // assert length is OK
APS_Lab 0:8ca1e814a851 104 if (rxFrameLen<3) {
APS_Lab 0:8ca1e814a851 105 return;
APS_Lab 0:8ca1e814a851 106 }
APS_Lab 0:8ca1e814a851 107
APS_Lab 0:8ca1e814a851 108 // parse header
APS_Lab 0:8ca1e814a851 109 cmdId = rxFrame[0];
APS_Lab 0:8ca1e814a851 110 length = rxFrame[1];
APS_Lab 0:8ca1e814a851 111 flags = rxFrame[2];
APS_Lab 0:8ca1e814a851 112 isResponse = ((flags & DN_SERIAL_API_MASK_RESPONSE)!=0);
APS_Lab 0:8ca1e814a851 113 packetId = ((flags & DN_SERIAL_API_MASK_PACKETID)!=0);
APS_Lab 0:8ca1e814a851 114 isSync = ((flags & DN_SERIAL_API_MASK_SYNC)!=0);
APS_Lab 0:8ca1e814a851 115
APS_Lab 0:8ca1e814a851 116 // check if valid packet ID
APS_Lab 0:8ca1e814a851 117 if (isResponse) {
APS_Lab 0:8ca1e814a851 118 // dispatch
APS_Lab 0:8ca1e814a851 119
APS_Lab 0:8ca1e814a851 120 dn_serial_mt_dispatch_response(cmdId,&rxFrame[3],length);
APS_Lab 0:8ca1e814a851 121 } else {
APS_Lab 0:8ca1e814a851 122 if (isSync || packetId!=dn_serial_mt_vars.rxPacketId) {
APS_Lab 0:8ca1e814a851 123 isRepeatId = FALSE;
APS_Lab 0:8ca1e814a851 124 dn_serial_mt_vars.rxPacketId = packetId;
APS_Lab 0:8ca1e814a851 125 } else {
APS_Lab 0:8ca1e814a851 126 isRepeatId = TRUE;
APS_Lab 0:8ca1e814a851 127 }
APS_Lab 0:8ca1e814a851 128
APS_Lab 0:8ca1e814a851 129 // ACK
APS_Lab 0:8ca1e814a851 130 dn_serial_sendReply(cmdId,DN_SERIAL_RC_OK,NULL,0);
APS_Lab 0:8ca1e814a851 131
APS_Lab 0:8ca1e814a851 132 // dispatch
APS_Lab 0:8ca1e814a851 133 if (isRepeatId==FALSE && length>0 && dn_serial_mt_vars.requestCb!=NULL) {
APS_Lab 0:8ca1e814a851 134 dn_serial_mt_vars.requestCb(cmdId,flags,&rxFrame[3],length);
APS_Lab 0:8ca1e814a851 135 }
APS_Lab 0:8ca1e814a851 136 }
APS_Lab 0:8ca1e814a851 137 }
APS_Lab 0:8ca1e814a851 138
APS_Lab 0:8ca1e814a851 139 /**
APS_Lab 0:8ca1e814a851 140 \note Not public, only used for sending ACK.
APS_Lab 0:8ca1e814a851 141 */
APS_Lab 0:8ca1e814a851 142 void dn_serial_sendReply(uint8_t cmdId, uint8_t rc, uint8_t *payload, uint8_t length) {
APS_Lab 0:8ca1e814a851 143 uint8_t i;
APS_Lab 0:8ca1e814a851 144
APS_Lab 0:8ca1e814a851 145 dn_hdlc_outputOpen();
APS_Lab 0:8ca1e814a851 146 dn_hdlc_outputWrite(cmdId); // cmdId
APS_Lab 0:8ca1e814a851 147 dn_hdlc_outputWrite(length); // length
APS_Lab 0:8ca1e814a851 148 dn_hdlc_outputWrite(DN_SERIAL_API_MASK_RESPONSE | (dn_serial_mt_vars.rxPacketId<<1)); // flags
APS_Lab 0:8ca1e814a851 149 dn_hdlc_outputWrite(rc); // rc
APS_Lab 0:8ca1e814a851 150 for (i=0; i<length; i++) { // payload
APS_Lab 0:8ca1e814a851 151 dn_hdlc_outputWrite(payload[i]);
APS_Lab 0:8ca1e814a851 152 }
APS_Lab 0:8ca1e814a851 153 dn_hdlc_outputClose();
APS_Lab 0:8ca1e814a851 154 }
APS_Lab 0:8ca1e814a851 155
APS_Lab 0:8ca1e814a851 156 void dn_serial_mt_dispatch_response(uint8_t cmdId, uint8_t* payload, uint8_t length) {
APS_Lab 0:8ca1e814a851 157 uint8_t rc;
APS_Lab 0:8ca1e814a851 158
APS_Lab 0:8ca1e814a851 159 rc = payload[0];
APS_Lab 0:8ca1e814a851 160 if (cmdId==dn_serial_mt_vars.replyCmdId && dn_serial_mt_vars.replyCb!=NULL) {
APS_Lab 0:8ca1e814a851 161
APS_Lab 0:8ca1e814a851 162 // call the callback
APS_Lab 0:8ca1e814a851 163 (dn_serial_mt_vars.replyCb)(cmdId,rc,&payload[1],length);
APS_Lab 0:8ca1e814a851 164
APS_Lab 0:8ca1e814a851 165 // reset
APS_Lab 0:8ca1e814a851 166 dn_serial_mt_vars.replyCmdId = 0x00;
APS_Lab 0:8ca1e814a851 167 dn_serial_mt_vars.replyCb = NULL;
APS_Lab 0:8ca1e814a851 168 }
APS_Lab 0:8ca1e814a851 169 }
APS_Lab 0:8ca1e814a851 170
APS_Lab 0:8ca1e814a851 171 //=========================== helpers =========================================
APS_Lab 0:8ca1e814a851 172