APS Lab
/
STM32F4_SmartMesh_QSL
SmartMesh QSL for STM32F4 version
Fork of COG-AD4050_QSL by
sm_clib/dn_serial_mt.c@1:b909b8399252, 2018-07-12 (annotated)
- 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?
User | Revision | Line number | New 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 |