Embedded_codes/libraries/RTTeensyLink/RTTeensyLinkUtils.cpp
2018-02-18 14:02:33 +05:30

176 lines
5.6 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// This file is part of RTTeensyLink
//
// Copyright (c) 2015, richards-tech, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
// Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "RTTeensyLinkUtils.h"
// RTTeensyLinkRXFrameInit initializes the structure for a new frame using frameBuffer for storage
void RTTeensyLinkRXFrameInit(RTTEENSYLINK_RXFRAME *RXFrame, RTTEENSYLINK_FRAME *frameBuffer)
{
RXFrame->complete = false;
RXFrame->length = 0;
RXFrame->bytesLeft = 0;
RXFrame->frameBuffer = frameBuffer;
}
// RTTeensyLinkReassemble takes a sequence of received bytes and tries to complete a frame. It returns true if ok
// false if error. The caller can determine if the frame is complete by checking the complete flag.
bool RTTeensyLinkReassemble(RTTEENSYLINK_RXFRAME *RXFrame, unsigned char data)
{
bool flag = true;
((unsigned char *)(RXFrame->frameBuffer))[RXFrame->length] = data; // save byte in correct place
switch (RXFrame->length) {
case 0: // waiting for sync0
if (RXFrame->frameBuffer->sync0 == RTTEENSYLINK_MESSAGE_SYNC0) {
RXFrame->length = 1;
}
break;
case 1: // waiting for sync1
if (RXFrame->frameBuffer->sync1 == RTTEENSYLINK_MESSAGE_SYNC1) {
RXFrame->length = 2;
} else {
RXFrame->length = 0; // try again if not correct two byte sequence
}
break;
case 2: // should be message length
if (RXFrame->frameBuffer->messageLength <= RTTEENSYLINK_MESSAGE_MAX_LEN) {
RXFrame->length = 3;
RXFrame->bytesLeft = RXFrame->frameBuffer->messageLength + 1; // +1 to allow for the checksum
} else {
RXFrame->length = 0; // discard this and resync frame
flag = false;
}
break;
default:
RXFrame->length++;
RXFrame->bytesLeft--;
if (RXFrame->bytesLeft == 0) { // a complete frame!
if (!RTTeensyLinkCheckChecksum(RXFrame->frameBuffer)) {
RTTeensyLinkRXFrameInit(RXFrame, RXFrame->frameBuffer);
flag = false; // flag the error
} else {
// this is a valid frame (so far)
RXFrame->complete = true;
}
}
break;
}
return flag;
}
// RTTeensyLinkSetChecksum correctly sets the checksum field on an RCP frame prior to transmission
//
void RTTeensyLinkSetChecksum(RTTEENSYLINK_FRAME *frame)
{
int cksm;
int i;
unsigned char *data;
for (i = 0, cksm = 0, data = (unsigned char *)&(frame->message); i < frame->messageLength; i++)
cksm += *data++; // add up checksum
frame->frameChecksum = (255 - cksm) + 1; // 2s complement
}
// RTTeensyLinkCheckChecksum checks a received frame's checksum.
//
// It adds up all the bytes from the nFrameCksm byte to the end of the frame. The result should be 0.
bool RTTeensyLinkCheckChecksum(RTTEENSYLINK_FRAME *frame)
{
int length;
int i;
unsigned char *data;
unsigned char cksm;
length = frame->messageLength + 1;
cksm = 0;
data = (unsigned char *)&(frame->frameChecksum);
for (i = 0; i < length; i++)
cksm += *data++;
return cksm == 0;
}
// UC2 and UC4 Conversion routines
//
long RTTeensyLinkConvertUC4ToLong(RTTEENSYLINK_UC4 UC4)
{
long val;
val = UC4[3];
val += (long)UC4[2] << 8;
val += (long)UC4[1] << 16;
val += (long)UC4[0] << 24;
return val;
}
void RTTeensyLinkConvertLongToUC4(long val, RTTEENSYLINK_UC4 UC4)
{
UC4[3] = val & 0xff;
UC4[2] = (val >> 8) & 0xff;
UC4[1] = (val >> 16) & 0xff;
UC4[0] = (val >> 24) & 0xff;
}
int RTTeensyLinkConvertUC2ToInt(RTTEENSYLINK_UC2 UC2)
{
int val;
val = UC2[1];
val += (int)UC2[0] << 8;
return val;
}
unsigned int RTTeensyLinkConvertUC2ToUInt(RTTEENSYLINK_UC2 UC2)
{
unsigned int val;
val = UC2[1];
val += (unsigned int)UC2[0] << 8;
return val;
}
void RTTeensyLinkConvertIntToUC2(int val, RTTEENSYLINK_UC2 UC2)
{
UC2[1] = val & 0xff;
UC2[0] = (val >> 8) & 0xff;
}
void RTTeensyLinkCopyUC2(RTTEENSYLINK_UC2 destUC2, RTTEENSYLINK_UC2 sourceUC2)
{
destUC2[0] = sourceUC2[0];
destUC2[1] = sourceUC2[1];
}