324 lines
6.4 KiB
C
324 lines
6.4 KiB
C
/**********************************************************************
|
||
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 "NetworkInterface.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_LORA_INTERFACE_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(),DataSize); //JFM TODO map to lora interface protocol
|
||
ResetStateMachine();
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
ResetStateMachine();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void ProtocolAnalyzeNewData(unsigned char Data)
|
||
{
|
||
// mRxData[RxPtr] = Data;
|
||
// printf("%X",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];
|
||
} |