/********************************************************************** Project: Automatic cat feeder Date: march 19 2006 Author: Jean-Fran�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 #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]; }