Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

427 řádky
9.5 KiB

  1. /**********************************************************************
  2. Project: Automatic cat feeder
  3. Date: march 19 2006
  4. Author: Jean-Fran�ois Martel
  5. Target: PIC 18F252
  6. Compiler: Microchip mcc18
  7. Filename: Protocol.c
  8. File description: Communication protocol implementation.
  9. jean-francois.martel@polymtl.ca
  10. **********************************************************************/
  11. #include "define.h"
  12. #include <string.h>
  13. #include "ProtocolDefs.h"
  14. #include "BootloaderProtocol.h"
  15. #include "BootloaderInterface.h"
  16. #include "WiFiCtrl.h"
  17. #include "checksum.h"
  18. //test
  19. unsigned int BootloaderHeader = 0;
  20. unsigned int BootloaderDataSize = 0;
  21. unsigned int BootloaderDataCtr = 0;
  22. unsigned int BootloaderBufPtr = 0;
  23. unsigned int BootloaderCRC = 0;
  24. unsigned int BtldrComputedCRC = CRC_START_32;
  25. unsigned char *BootloaderRxPtr;
  26. unsigned char BootloaderCommand = 0;
  27. unsigned char BootloaderState = BLRxHeader1;
  28. const unsigned char *BootloaderDataStartPtr = &BootloaderBuffer[9];
  29. static char MyDeviceID = ID_SPRINKLER_DEVICE;
  30. void BootloaderProtocolInit(void)
  31. {
  32. BootloaderProtocolResetStateMachine();
  33. }
  34. void BootloaderProtocolStateMachine(unsigned char Data)
  35. {
  36. switch(BootloaderState)
  37. {
  38. case BLInitialization: //Reset all pointers and data...
  39. {
  40. BootloaderDataSize = 0;
  41. BootloaderBufPtr = 0;
  42. BootloaderCommand = 0;
  43. BootloaderCRC = 0;
  44. BootloaderState = BLRxHeader1;
  45. BtldrComputedCRC = CRC_START_32;
  46. break;
  47. }
  48. case BLRxHeader1: //Wait for data header...
  49. {
  50. BootloaderHeader <<= 8;
  51. BootloaderHeader += Data; //0xDE
  52. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  53. if(Data == BOOTLOADER_FRAME_HEADER_1)
  54. {
  55. BootloaderState = BLRxHeader2;
  56. }
  57. else
  58. {
  59. BootloaderProtocolResetStateMachine();
  60. }
  61. break;
  62. }
  63. case BLRxHeader2: //Wait for data header...
  64. {
  65. BootloaderHeader <<= 8;
  66. BootloaderHeader += Data; //0xAD
  67. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  68. if(Data == BOOTLOADER_FRAME_HEADER_2)
  69. {
  70. BootloaderState = BLRxHeader3;
  71. }
  72. else
  73. {
  74. BootloaderProtocolResetStateMachine();
  75. }
  76. break;
  77. }
  78. case BLRxHeader3: //Wait for data header...
  79. {
  80. BootloaderHeader <<= 8;
  81. BootloaderHeader += Data; //0xBE
  82. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  83. if(Data == BOOTLOADER_FRAME_HEADER_3)
  84. {
  85. BootloaderState = BLRxHeader4;
  86. }
  87. else
  88. {
  89. BootloaderProtocolResetStateMachine();
  90. }
  91. break;
  92. }
  93. case BLRxHeader4: //Wait for data header...
  94. {
  95. BootloaderHeader <<= 8;
  96. BootloaderHeader += Data; //0xEF
  97. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  98. if(BootloaderHeader != BOOTLOADER_FRAME_HEADER)
  99. {
  100. //TODO, send NACK?
  101. BootloaderProtocolResetStateMachine();
  102. break;
  103. }
  104. else
  105. {
  106. BootloaderState = BLRxCmd;
  107. }
  108. break;
  109. }
  110. case BLRxCmd:
  111. {
  112. BootloaderCommand = Data;
  113. BootloaderState = BLRxPayloadSize1;
  114. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  115. break;
  116. }
  117. case BLRxPayloadSize1:
  118. {
  119. BootloaderDataSize = Data;
  120. BootloaderState = BLRxPayloadSize2;
  121. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  122. break;
  123. }
  124. case BLRxPayloadSize2:
  125. {
  126. BootloaderDataSize <<= 8;
  127. BootloaderDataSize += Data;
  128. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  129. BootloaderState = BLRxPayloadSize3;
  130. break;
  131. }
  132. case BLRxPayloadSize3:
  133. {
  134. BootloaderDataSize <<= 8;
  135. BootloaderDataSize += Data;
  136. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  137. BootloaderState = BLRxPayloadSize4;
  138. break;
  139. }
  140. case BLRxPayloadSize4:
  141. {
  142. BootloaderDataSize <<= 8;
  143. BootloaderDataSize += Data;
  144. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  145. if(BootloaderDataSize > MAX_BOOTLOADER_PAYLOAD_SIZE+8) //+8 bytes for the size and index data
  146. {
  147. //TODO, send NACK?
  148. BootloaderProtocolResetStateMachine();
  149. break;
  150. }
  151. if(BootloaderDataSize == 0)
  152. {
  153. BootloaderState = BLRxCRC1;
  154. }
  155. else
  156. {
  157. BootloaderState = BLRxPayload;
  158. }
  159. break;
  160. }
  161. case BLRxPayload: //Data size
  162. {
  163. *BootloaderRxPtr = Data;
  164. BootloaderRxPtr++;
  165. BootloaderDataCtr++;
  166. BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
  167. if(BootloaderDataCtr == BootloaderDataSize)
  168. {
  169. BootloaderState = BLRxCRC1;
  170. break;
  171. }
  172. break;
  173. }
  174. case BLRxCRC1: //Data size
  175. {
  176. BootloaderCRC = Data;
  177. BootloaderState = BLRxCRC2;
  178. break;
  179. }
  180. case BLRxCRC2: //Data size
  181. {
  182. BootloaderCRC <<= 8;
  183. BootloaderCRC += Data;
  184. BootloaderState = BLRxCRC3;
  185. break;
  186. }
  187. case BLRxCRC3: //Data size
  188. {
  189. BootloaderCRC <<= 8;
  190. BootloaderCRC += Data;
  191. BootloaderState = BLRxCRC4;
  192. break;
  193. }
  194. case BLRxCRC4: //Data size
  195. {
  196. BootloaderCRC <<= 8;
  197. BootloaderCRC += Data;
  198. //TODO: Compute and Compare CRC.
  199. BtldrComputedCRC ^= 0xffffffffL;
  200. //if(BootloaderCRC != 0xBAADCAFE)
  201. if(BootloaderCRC != BtldrComputedCRC)
  202. {
  203. BootloaderExecuteCmd(BootloaderCommand,0);
  204. BootloaderProtocolResetStateMachine();
  205. return;
  206. }
  207. BootloaderExecuteCmd(BootloaderCommand,1);
  208. BootloaderProtocolResetStateMachine();
  209. break;
  210. }
  211. default:
  212. {
  213. BootloaderProtocolResetStateMachine();
  214. break;
  215. }
  216. }
  217. }
  218. void BootloaderProtocolProtocolAnalyzeNewData(unsigned char *DataBuf, int size)
  219. {
  220. int i;
  221. for(i = 0; i < size; i++)
  222. {
  223. BootloaderProtocolStateMachine(*DataBuf++);
  224. }
  225. }
  226. void BootloaderProtocolResetStateMachine()
  227. {
  228. BootloaderDataSize = 0;
  229. BootloaderHeader = 0;
  230. BootloaderBufPtr = 0;
  231. BootloaderCommand = 0;
  232. BootloaderCRC = 0;
  233. BootloaderState = BLRxHeader1;
  234. BootloaderDataCtr = 0;
  235. BtldrComputedCRC = CRC_START_32;
  236. BootloaderRxPtr = &BootloaderBuffer[0];
  237. }
  238. void BootloaderProtocolSendFrame(unsigned char Cmd, int Size)
  239. {
  240. //Header
  241. BootloaderBuffer[0] = BOOTLOADER_FRAME_HEADER_1; //Header
  242. BootloaderBuffer[1] = BOOTLOADER_FRAME_HEADER_2;
  243. BootloaderBuffer[2] = BOOTLOADER_FRAME_HEADER_3;
  244. BootloaderBuffer[3] = BOOTLOADER_FRAME_HEADER_4;
  245. BootloaderBuffer[4] = Cmd;
  246. char nibble = (char)((Size >> 24) &0x000000FF);
  247. BootloaderBuffer[5] = nibble;
  248. nibble = (char)((Size >> 16) &0x000000FF);
  249. BootloaderBuffer[6] = nibble;
  250. nibble = (char)((Size >> 8) &0x000000FF);
  251. BootloaderBuffer[7] = nibble;
  252. nibble = (char)(Size &0x000000FF);
  253. BootloaderBuffer[8] = nibble;
  254. unsigned int CRC = CRC_START_32;
  255. CRC = crc_32((const unsigned char*)BootloaderBuffer,Size+9);
  256. unsigned char* CRCPtr = (unsigned char*)BootloaderDataStartPtr + Size;
  257. nibble = (char)((CRC >> 24) &0x000000FF);
  258. *CRCPtr++ = nibble;
  259. nibble = (char)((CRC >> 16) &0x000000FF);
  260. *CRCPtr++ = nibble;
  261. nibble = (char)((CRC >> 8) &0x000000FF);
  262. *CRCPtr++ = nibble;
  263. nibble = (char)(CRC &0x000000FF);
  264. *CRCPtr++ = nibble;
  265. // *CRCPtr++ = 0xBA;
  266. // *CRCPtr++ = 0xAD;
  267. // *CRCPtr++ = 0xCA;
  268. // *CRCPtr++ = 0xFE;
  269. SendBootloaderData(&BootloaderBuffer[0],Size + PROTOCOL_INFO_DATA_SIZE);
  270. }
  271. unsigned char *BootloaderProtocolGetDataBufferPtr()
  272. {
  273. return (unsigned char*)BootloaderDataStartPtr;
  274. }
  275. void BootloaderProtocolSendHeartbeat()
  276. {
  277. *BootloaderProtocolGetDataBufferPtr() = BOOTLOADER_ACK;
  278. BootloaderProtocolSendFrame(BOOTLOADER_HEARTBEAT_RESPONSE,1);
  279. }
  280. void BootloaderProtocolSendACK(unsigned char Cmd)
  281. {
  282. *BootloaderProtocolGetDataBufferPtr() = BOOTLOADER_ACK;
  283. BootloaderProtocolSendFrame(Cmd,1);
  284. }
  285. void BootloaderProtocolSendNACK(unsigned char Cmd)
  286. {
  287. *BootloaderProtocolGetDataBufferPtr() = 0;
  288. BootloaderProtocolSendFrame(Cmd,1);
  289. }
  290. void BootloaderProtocolSendInitUploadResponse(char result)
  291. {
  292. int MaxSize = MAX_BOOTLOADER_PAYLOAD_SIZE;
  293. char* DataPtr = BootloaderProtocolGetDataBufferPtr();
  294. *DataPtr++ = result;
  295. if(result == 1)
  296. {
  297. char nibble = (char)((MaxSize >> 24) &0x000000FF);
  298. *DataPtr++ = nibble;
  299. nibble = (char)((MaxSize >> 16) &0x000000FF);
  300. *DataPtr++ = nibble;
  301. nibble = (char)((MaxSize >> 8) &0x000000FF);
  302. *DataPtr++ = nibble;
  303. nibble = (char)(MaxSize &0x000000FF);
  304. *DataPtr++ = nibble;
  305. }
  306. else
  307. {
  308. *DataPtr++ = 0;
  309. *DataPtr++ = 0;
  310. *DataPtr++ = 0;
  311. *DataPtr++ = 0;
  312. }
  313. BootloaderProtocolSendFrame(BOOTLOADER_INIT_UPLOAD_RESPONSE,5);
  314. }
  315. void BootloaderProtocolSendDataChunkResult(char ErrorCode, int ChunkValue)
  316. {
  317. char* DataPtr = BootloaderProtocolGetDataBufferPtr();
  318. *DataPtr++ = ErrorCode;
  319. char nibble = (char)((ChunkValue >> 24) &0x000000FF);
  320. *DataPtr++ = nibble;
  321. nibble = (char)((ChunkValue >> 16) &0x000000FF);
  322. *DataPtr++ = nibble;
  323. nibble = (char)((ChunkValue >> 8) &0x000000FF);
  324. *DataPtr++ = nibble;
  325. nibble = (char)(ChunkValue &0x000000FF);
  326. *DataPtr++ = nibble;
  327. BootloaderProtocolSendFrame(BOOTLOADER_SEND_DATA_CHUNK_RESPONSE,5);
  328. }
  329. void BootloaderProtocolSendBootloaderState(char State)
  330. {
  331. char* DataPtr = BootloaderProtocolGetDataBufferPtr();
  332. *DataPtr++ = State;
  333. BootloaderProtocolSendFrame(BOOTLOADER_GET_STATE_RESPONSE,1);
  334. }
  335. void BootloaderProtocolSendFirmwareUploadResult(char Result)
  336. {
  337. char* DataPtr = BootloaderProtocolGetDataBufferPtr();
  338. *DataPtr++ = Result;
  339. BootloaderProtocolSendFrame(BOOTLOADER_UPLOAD_FINISHED_RESPONSE,1);
  340. }
  341. void BootloaderProtocolSendFlashCheckResult(char Result)
  342. {
  343. char* DataPtr = BootloaderProtocolGetDataBufferPtr();
  344. *DataPtr++ = Result;
  345. BootloaderProtocolSendFrame(BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_RESPONSE,1);
  346. }
  347. void BootloaderProtocolSendStoredFirmwareInfoResponse(unsigned char* FirmwareData, int size)
  348. {
  349. char* DataPtr = BootloaderProtocolGetDataBufferPtr();
  350. int i = 0;
  351. for(i = 0; i < size; i++)
  352. {
  353. *DataPtr++ = *FirmwareData++;
  354. }
  355. BootloaderProtocolSendFrame(BOOTLOADER_GET_STORED_FIRMWARE_INFO_RESPONSE,size);
  356. }