Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of COG-AD4050_QSL by
sm_clib/dn_serial_mt.c@0:8ca1e814a851, 2018-05-02 (annotated)
- Committer:
- APS_Lab
- Date:
- Wed May 02 09:26:10 2018 +0000
- Revision:
- 0:8ca1e814a851
version1
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 |
