APS Lab
/
STM32F4_SmartMesh_QSL
SmartMesh QSL for STM32F4 version
Fork of COG-AD4050_QSL by
sm_clib/dn_serial_mt.c
- Committer:
- APS_Lab
- Date:
- 2018-07-12
- Revision:
- 1:b909b8399252
- Parent:
- 0:8ca1e814a851
File content as of revision 1:b909b8399252:
/* Copyright (c) 2014, Dust Networks. All rights reserved. HDLC library. \license See attached DN_LICENSE.txt. */ #include "dn_serial_mt.h" #include "dn_hdlc.h" //=========================== variables ======================================= typedef struct { // packet IDs uint8_t txPacketId; uint8_t rxPacketId; // reply callback uint8_t replyCmdId; dn_serial_reply_cbt replyCb; // request callback dn_serial_request_cbt requestCb; } dn_serial_mt_vars_t; dn_serial_mt_vars_t dn_serial_mt_vars; //=========================== prototype ======================================= void dn_serial_mt_rxHdlcFrame(uint8_t* rxFrame, uint8_t rxFrameLen); void dn_serial_mt_dispatch_response(uint8_t cmdId, uint8_t *payload, uint8_t length); void dn_serial_sendReply(uint8_t cmdId, uint8_t rc, uint8_t *payload, uint8_t length); //=========================== public ========================================== /** \brief Setting up the instance. */ void dn_serial_mt_init(dn_serial_request_cbt requestCb) { // reset local variables memset(&dn_serial_mt_vars, 0, sizeof(dn_serial_mt_vars)); // initialize variables dn_serial_mt_vars.txPacketId = DN_SERIAL_PACKETID_NOTSET; dn_serial_mt_vars.rxPacketId = DN_SERIAL_PACKETID_NOTSET; dn_serial_mt_vars.requestCb = requestCb; // initialize the HDLC module dn_hdlc_init(dn_serial_mt_rxHdlcFrame); } dn_err_t dn_serial_mt_sendRequest(uint8_t cmdId, uint8_t extraFlags, uint8_t* payload, uint8_t length, dn_serial_reply_cbt replyCb) { uint8_t i; uint8_t flags; // register reply callback dn_serial_mt_vars.replyCmdId = cmdId; dn_serial_mt_vars.replyCb = replyCb; // calculate the flags flags = 0; if (dn_serial_mt_vars.txPacketId==DN_SERIAL_PACKETID_NOTSET) { dn_serial_mt_vars.txPacketId = 0x00; flags |= 0x01<<3; // sync bit flags |= dn_serial_mt_vars.txPacketId<<1; // txPacketId } else { flags |= dn_serial_mt_vars.txPacketId<<1; // txPacketId } flags |= extraFlags; // send the frame over serial dn_hdlc_outputOpen(); dn_hdlc_outputWrite(cmdId); // cmdId dn_hdlc_outputWrite(length); // length dn_hdlc_outputWrite(flags); // flags for (i=0; i<length; i++) { // payload dn_hdlc_outputWrite(payload[i]); } dn_hdlc_outputClose(); // toggle the txPacketId if (dn_serial_mt_vars.txPacketId==0x00) { dn_serial_mt_vars.txPacketId = 0x01; } else { dn_serial_mt_vars.txPacketId = 0x00; } return DN_ERR_NONE; } //=========================== private ========================================= void dn_serial_mt_rxHdlcFrame(uint8_t* rxFrame, uint8_t rxFrameLen) { // fields in the serial API header uint8_t cmdId; uint8_t length; uint8_t flags; uint8_t isResponse; uint8_t packetId; uint8_t isSync; // misc uint8_t isRepeatId; // assert length is OK if (rxFrameLen<3) { return; } // parse header cmdId = rxFrame[0]; length = rxFrame[1]; flags = rxFrame[2]; isResponse = ((flags & DN_SERIAL_API_MASK_RESPONSE)!=0); packetId = ((flags & DN_SERIAL_API_MASK_PACKETID)!=0); isSync = ((flags & DN_SERIAL_API_MASK_SYNC)!=0); // check if valid packet ID if (isResponse) { // dispatch dn_serial_mt_dispatch_response(cmdId,&rxFrame[3],length); } else { if (isSync || packetId!=dn_serial_mt_vars.rxPacketId) { isRepeatId = FALSE; dn_serial_mt_vars.rxPacketId = packetId; } else { isRepeatId = TRUE; } // ACK dn_serial_sendReply(cmdId,DN_SERIAL_RC_OK,NULL,0); // dispatch if (isRepeatId==FALSE && length>0 && dn_serial_mt_vars.requestCb!=NULL) { dn_serial_mt_vars.requestCb(cmdId,flags,&rxFrame[3],length); } } } /** \note Not public, only used for sending ACK. */ void dn_serial_sendReply(uint8_t cmdId, uint8_t rc, uint8_t *payload, uint8_t length) { uint8_t i; dn_hdlc_outputOpen(); dn_hdlc_outputWrite(cmdId); // cmdId dn_hdlc_outputWrite(length); // length dn_hdlc_outputWrite(DN_SERIAL_API_MASK_RESPONSE | (dn_serial_mt_vars.rxPacketId<<1)); // flags dn_hdlc_outputWrite(rc); // rc for (i=0; i<length; i++) { // payload dn_hdlc_outputWrite(payload[i]); } dn_hdlc_outputClose(); } void dn_serial_mt_dispatch_response(uint8_t cmdId, uint8_t* payload, uint8_t length) { uint8_t rc; rc = payload[0]; if (cmdId==dn_serial_mt_vars.replyCmdId && dn_serial_mt_vars.replyCb!=NULL) { // call the callback (dn_serial_mt_vars.replyCb)(cmdId,rc,&payload[1],length); // reset dn_serial_mt_vars.replyCmdId = 0x00; dn_serial_mt_vars.replyCb = NULL; } } //=========================== helpers =========================================