ChaletLora/ChaletLora.X/Source/NetworkProtocol.c

323 lines
6.3 KiB
C
Raw Blame History

/**********************************************************************
Project: Automatic cat feeder
Date: march 19 2006
Author: Jean-Fran<61>ois Martel
Target: PIC 18F252
Compiler: Microchip mcc18
Filename: Protocol.c
File description: Communication protocol implementation.
jean-francois.martel@polymtl.ca
**********************************************************************/
#include "define.h"
#include "NetworkProtocol.h"
#include "Uart.h"
#include <string.h>
#include "ProtocolDefs.h"
#include "MasterCtrlInterface.h"
#include "LoraNetworkInterface.h"
unsigned char mRxData[MAX_MESSAGE_SIZE+10], mTxData[MAX_MESSAGE_SIZE+10];
unsigned int DataSize = 0;
unsigned int DataCtr = 0;
unsigned int BufPtr = 0;
unsigned char RxPtr = 0;
unsigned char Command = 0;
unsigned char State = RxHeader;
unsigned char CRC = 0;
unsigned char SenderID = 0;
unsigned char SenderAddress = 0;
unsigned char Flags = 0;
unsigned char IsUpdating = 0;
unsigned char *BmpDataPtr = 0;
static char MyDeviceID = ID_SPRINKLER_DEVICE;
void ProtocolInit(void)
{
ResetStateMachine();
}
void StateMachine(unsigned char Data)
{
switch(State)
{
case Initialization: //Reset all pointers and data...
{
DataSize = 0;
BufPtr = 0;
RxPtr = 0;
Command = 0;
CRC = 0;
State = RxHeader;
break;
}
case RxHeader: //Wait for data header...
{
if(Data == FRAME_HEADER)
{
mRxData[BufPtr++] = Data;
State = RxAdd;
CRC ^= Data;
}
else
{
DataSize = 0;
ResetStateMachine();
}
break;
}
case RxAdd: //Sender Address.
{
SenderAddress = Data;
mRxData[BufPtr++] = Data;
State = RxID;
CRC ^= Data;
break;
}
case RxID: //Sender ID
{
mRxData[BufPtr++] = Data;
State = RxMyID;
SenderID = Data;
CRC ^= Data;
break;
}
case RxMyID:
{
// if(Data != MyDeviceID && Data != BROADCAST_VALUE) //Message is not for this type of device and it's not a broadcast
// {
// ResetStateMachine();
// break;
// }
mRxData[BufPtr++] = Data;
State = RxMyAddress;
CRC ^= Data;
break;
}
case RxMyAddress:
{
if(Data != MY_DEVICE_ADDRESS && Data != BROADCAST_VALUE) //Message is not for this device address and it's not a broadcast
{
ResetStateMachine();
break;
}
mRxData[BufPtr++] = Data;
State = RxFlags;
CRC ^= Data;
break;
}
case RxFlags:
{
Flags = Data;
mRxData[BufPtr++] = Data;
State = RxCMD;
CRC ^= Data;
break;
}
case RxCMD:
{
Command = Data;
mRxData[BufPtr++] = Data;
State = RxSize1;
CRC ^= Data;
break;
}
case RxSize1: //Data size MSB
{
DataSize = 0;
DataSize = (unsigned int)Data;
DataSize <<= 8;
mRxData[BufPtr++] = Data;
State = RxSize2;
CRC ^= Data;
break;
}
case RxSize2: //Data size
{
DataSize |= (unsigned int)Data;
DataSize <<= 8;
mRxData[BufPtr++] = Data;
State = RxSize3;
CRC ^= Data;
break;
}
case RxSize3: //Data size
{
DataSize |= (unsigned int)Data;
DataSize <<= 8;
mRxData[BufPtr++] = Data;
State = RxSize4;
CRC ^= Data;
break;
}
case RxSize4: //Data size LSB
{
DataSize |= (unsigned int)Data;
mRxData[BufPtr++] = Data;
if(DataSize > MAX_MESSAGE_SIZE)
ResetStateMachine();
if(DataSize == 0)
State = RxCRC;
else
State = RxData;
CRC ^= Data;
break;
}
case RxData:
{
CRC ^= Data;
mRxData[BufPtr++] = Data;
DataCtr++;
if(DataCtr == DataSize)
{
State = RxCRC;
}
break;
}
case RxCRC:
{
if(Data != CRC)
{
ResetStateMachine();
// ProtocolAcknowledge(0,Command,0);
break;
}
// NewMasterMessageReceived(mRxData);
ExecuteMasterCommand(Command,ProtocolMsgDataPtr());
ResetStateMachine();
break;
}
default:
{
ResetStateMachine();
break;
}
}
}
void ProtocolAnalyzeNewData(unsigned char Data)
{
// mRxData[RxPtr] = Data;
StateMachine(Data);
}
void ResetStateMachine(void)
{
DataSize = 0;
BufPtr = 0;
RxPtr = 0;
Command = 0;
CRC = 0;
State = RxHeader;
DataCtr = 0;
Flags = 0;
SenderAddress = 0;
}
void ProtocolExecCmd(void)
{
switch(Command)
{
case RX_GET_STATUS:
{
unsigned char StatusByte =0;
// memcpy(&StatusByte, &IRRemoteStatus, sizeof(IRRemoteStatus));
// ProtocolSendCmd(TX_DEADBOLT_STATUS,&StatusByte,sizeof(StatusByte),1,0);
break;
}
}
}
void ProtocolAcknowledge(unsigned char Answer,unsigned char Cmd, unsigned char Data)
{
unsigned char data[2];
if(Answer == 1)
{
data[0] = PROTOCOL_ACK; //CMD
}
else
{
data[0] = PROTOCOL_NAK; //CMD
}
data[1] = Cmd;
// ProtocolSendCmd(TX_NETWORK_ACK,&data[0],2,1,0);
}
unsigned char ProtocolCalcCrc(unsigned char* Buffer,unsigned char size)
{
unsigned char CRC = 0;
unsigned char i;
for(i = 0; i < size; i++)
CRC ^= Buffer[i];
return CRC;
}
unsigned char ProtocolIsReceiving(void)
{
if(State == RxHeader)
return 0; // Idle...
else
return 1; //receiving from serial port
}
unsigned char* ProtocolGetFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags, int *FrameSize)
{
if(Size > MAX_MESSAGE_SIZE)
{
*FrameSize = 0;
return &mTxData[FRAME_HEADER_INDEX];
}
mTxData[FRAME_HEADER_INDEX] = FRAME_HEADER; //header
mTxData[FRAME_SENDER_ADDRESS_INDEX] = MY_DEVICE_ADDRESS; //My Address
mTxData[FRAME_SENDER_DEVICE_ID_INDEX] = SenderDevice; //My ID
mTxData[FRAME_DEST_DEVICE_ID_INDEX] = DestDevice; //Destination ID
mTxData[FRAME_DEST_ADDRESS_INDEX] = DestAddress ;//Address; //Destination Address
mTxData[FRAME_FLAGS_INDEX] = Flags; //Flags
mTxData[FRAME_COMMAND_INDEX] = Cmd; //Command to send
mTxData[FRAME_SIZE1_INDEX] = (unsigned char)((Size >> 24) & 0xFF);
mTxData[FRAME_SIZE2_INDEX] = (unsigned char)((Size >> 16) & 0xFF);
mTxData[FRAME_SIZE3_INDEX] = (unsigned char)((Size >> 8) & 0xFF);
mTxData[FRAME_SIZE4_INDEX] = (unsigned char)(Size & 0xFF);
memcpy((void*)&mTxData[FRAME_DATA_INDEX],(void*)Data,Size); //Cmd data
mTxData[Size+FRAME_DATA_INDEX] = ProtocolCalcCrc(mTxData,Size + FRAME_DATA_INDEX); // CRC
*FrameSize = Size + FRAME_INDEX_NBR;
return &mTxData[FRAME_HEADER_INDEX];
}
unsigned char *ProtocolMsgDataPtr()
{
return &mRxData[FRAME_DATA_INDEX];
}