cybtldr_command.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /*******************************************************************************
  2. * Copyright 2011-2012, Cypress Semiconductor Corporation. All rights reserved.
  3. * You may use this file only in accordance with the license, terms, conditions,
  4. * disclaimers, and limitations in the end user license agreement accompanying
  5. * the software package with which this file was provided.
  6. ********************************************************************************/
  7. #include "cybtldr_command.h"
  8. /* Variable used to store the currently selected packet checksum type */
  9. CyBtldr_ChecksumType CyBtldr_Checksum = SUM_CHECKSUM;
  10. unsigned short CyBtldr_ComputeChecksum(unsigned char* buf, unsigned long size)
  11. {
  12. if (CyBtldr_Checksum == CRC_CHECKSUM)
  13. {
  14. unsigned short crc = 0xffff;
  15. unsigned short tmp;
  16. int i;
  17. if (size == 0)
  18. return (~crc);
  19. do
  20. {
  21. for (i = 0, tmp = 0x00ff & *buf++; i < 8; i++, tmp >>= 1)
  22. {
  23. if ((crc & 0x0001) ^ (tmp & 0x0001))
  24. crc = (crc >> 1) ^ 0x8408;
  25. else
  26. crc >>= 1;
  27. }
  28. }
  29. while (--size);
  30. crc = ~crc;
  31. tmp = crc;
  32. crc = (crc << 8) | (tmp >> 8 & 0xFF);
  33. return crc;
  34. }
  35. else /* SUM_CHECKSUM */
  36. {
  37. unsigned short sum = 0;
  38. while (size-- > 0)
  39. sum += *buf++;
  40. return (1 + ~sum);
  41. }
  42. }
  43. void CyBtldr_SetCheckSumType(CyBtldr_ChecksumType chksumType)
  44. {
  45. CyBtldr_Checksum = chksumType;
  46. }
  47. int CyBtldr_ParseDefaultCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* status)
  48. {
  49. int err = CYRET_SUCCESS;
  50. if (cmdSize != BASE_CMD_SIZE)
  51. err = CYRET_ERR_LENGTH;
  52. else if (cmdBuf[1] != CYRET_SUCCESS)
  53. err = CYRET_ERR_BTLDR_MASK | (*status = cmdBuf[1]);
  54. else if (cmdBuf[0] != CMD_START || cmdBuf[2] != 0 || cmdBuf[3] != 0 || cmdBuf[6] != CMD_STOP)
  55. err = CYRET_ERR_DATA;
  56. else
  57. *status = cmdBuf[1];
  58. return err;
  59. }
  60. int CyBtldr_CreateEnterBootLoaderCmd(unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  61. {
  62. const unsigned long RESULT_DATA_SIZE = 8;
  63. unsigned short checksum;
  64. *resSize = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  65. *cmdSize = BASE_CMD_SIZE;
  66. cmdBuf[0] = CMD_START;
  67. cmdBuf[1] = CMD_ENTER_BOOTLOADER;
  68. cmdBuf[2] = 0;
  69. cmdBuf[3] = 0;
  70. checksum = CyBtldr_ComputeChecksum(cmdBuf, BASE_CMD_SIZE - 3);
  71. cmdBuf[4] = (unsigned char)checksum;
  72. cmdBuf[5] = (unsigned char)(checksum >> 8);
  73. cmdBuf[6] = CMD_STOP;
  74. return CYRET_SUCCESS;
  75. }
  76. int CyBtldr_ParseEnterBootLoaderCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned long* siliconId, unsigned char* siliconRev, unsigned long* blVersion, unsigned char* status)
  77. {
  78. const unsigned long RESULT_DATA_SIZE = 8;
  79. const unsigned long RESULT_SIZE = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  80. int err = CYRET_SUCCESS;
  81. if (cmdSize != RESULT_SIZE)
  82. err = CYRET_ERR_LENGTH;
  83. else if (cmdBuf[1] != CYRET_SUCCESS)
  84. err = CYRET_ERR_BTLDR_MASK | (*status = cmdBuf[1]);
  85. else if (cmdBuf[0] != CMD_START || cmdBuf[2] != RESULT_DATA_SIZE || cmdBuf[3] != (RESULT_DATA_SIZE >> 8) || cmdBuf[RESULT_SIZE - 1] != CMD_STOP)
  86. err = CYRET_ERR_DATA;
  87. else
  88. {
  89. *siliconId = (cmdBuf[7] << 24) | (cmdBuf[6] << 16) | (cmdBuf[5] << 8) | cmdBuf[4];
  90. *siliconRev = cmdBuf[8];
  91. *blVersion = (cmdBuf[11] << 16) | (cmdBuf[10] << 8) | cmdBuf[9];
  92. *status = cmdBuf[1];
  93. }
  94. return err;
  95. }
  96. int CyBtldr_CreateExitBootLoaderCmd(unsigned char resetType, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  97. {
  98. const unsigned long COMMAND_DATA_SIZE = 1;
  99. const unsigned int COMMAND_SIZE = BASE_CMD_SIZE + COMMAND_DATA_SIZE;
  100. unsigned short checksum;
  101. *resSize = BASE_CMD_SIZE;
  102. *cmdSize = COMMAND_SIZE;
  103. cmdBuf[0] = CMD_START;
  104. cmdBuf[1] = CMD_EXIT_BOOTLOADER;
  105. cmdBuf[2] = (unsigned char)COMMAND_DATA_SIZE;
  106. cmdBuf[3] = (unsigned char)(COMMAND_DATA_SIZE >> 8);
  107. cmdBuf[4] = resetType;
  108. checksum = CyBtldr_ComputeChecksum(cmdBuf, COMMAND_SIZE - 3);
  109. cmdBuf[5] = (unsigned char)checksum;
  110. cmdBuf[6] = (unsigned char)(checksum >> 8);
  111. cmdBuf[7] = CMD_STOP;
  112. return CYRET_SUCCESS;
  113. }
  114. int CyBtldr_CreateProgramRowCmd(unsigned char arrayId, unsigned short rowNum, unsigned char* buf, unsigned short size, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  115. {
  116. const unsigned long COMMAND_DATA_SIZE = 3;
  117. unsigned int checksum;
  118. unsigned long i;
  119. *resSize = BASE_CMD_SIZE;
  120. *cmdSize = BASE_CMD_SIZE + COMMAND_DATA_SIZE + size;
  121. cmdBuf[0] = CMD_START;
  122. cmdBuf[1] = CMD_PROGRAM_ROW;
  123. cmdBuf[2] = (unsigned char)(size + COMMAND_DATA_SIZE);
  124. cmdBuf[3] = (unsigned char)((size + COMMAND_DATA_SIZE) >> 8);
  125. cmdBuf[4] = arrayId;
  126. cmdBuf[5] = (unsigned char)rowNum;
  127. cmdBuf[6] = (unsigned char)(rowNum >> 8);
  128. for (i = 0; i < size; i++)
  129. cmdBuf[i + 7] = buf[i];
  130. checksum = CyBtldr_ComputeChecksum(cmdBuf, (*cmdSize) - 3);
  131. cmdBuf[*cmdSize - 3] = (unsigned char)checksum;
  132. cmdBuf[*cmdSize - 2] = (unsigned char)(checksum >> 8);
  133. cmdBuf[*cmdSize - 1] = CMD_STOP;
  134. return CYRET_SUCCESS;
  135. }
  136. int CyBtldr_ParseProgramRowCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* status)
  137. {
  138. return CyBtldr_ParseDefaultCmdResult(cmdBuf, cmdSize, status);
  139. }
  140. int CyBtldr_CreateVerifyRowCmd(unsigned char arrayId, unsigned short rowNum, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  141. {
  142. const unsigned long RESULT_DATA_SIZE = 1;
  143. const unsigned long COMMAND_DATA_SIZE = 3;
  144. const unsigned int COMMAND_SIZE = BASE_CMD_SIZE + COMMAND_DATA_SIZE;
  145. unsigned short checksum;
  146. *resSize = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  147. *cmdSize = COMMAND_SIZE;
  148. cmdBuf[0] = CMD_START;
  149. cmdBuf[1] = CMD_VERIFY_ROW;
  150. cmdBuf[2] = (unsigned char)COMMAND_DATA_SIZE;
  151. cmdBuf[3] = (unsigned char)(COMMAND_DATA_SIZE >> 8);
  152. cmdBuf[4] = arrayId;
  153. cmdBuf[5] = (unsigned char)rowNum;
  154. cmdBuf[6] = (unsigned char)(rowNum >> 8);
  155. checksum = CyBtldr_ComputeChecksum(cmdBuf, COMMAND_SIZE - 3);
  156. cmdBuf[7] = (unsigned char)checksum;
  157. cmdBuf[8] = (unsigned char)(checksum >> 8);
  158. cmdBuf[9] = CMD_STOP;
  159. return CYRET_SUCCESS;
  160. }
  161. int CyBtldr_ParseVerifyRowCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* checksum, unsigned char* status)
  162. {
  163. const unsigned long RESULT_DATA_SIZE = 1;
  164. const unsigned long RESULT_SIZE = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  165. int err = CYRET_SUCCESS;
  166. if (cmdSize != RESULT_SIZE)
  167. err = CYRET_ERR_LENGTH;
  168. else if (cmdBuf[1] != CYRET_SUCCESS)
  169. err = CYRET_ERR_BTLDR_MASK | (*status = cmdBuf[1]);
  170. else if (cmdBuf[0] != CMD_START || cmdBuf[2] != RESULT_DATA_SIZE || cmdBuf[3] != (RESULT_DATA_SIZE >> 8) || cmdBuf[RESULT_SIZE - 1] != CMD_STOP)
  171. err = CYRET_ERR_DATA;
  172. else
  173. {
  174. *checksum = cmdBuf[4];
  175. *status = cmdBuf[1];
  176. }
  177. return err;
  178. }
  179. int CyBtldr_CreateEraseRowCmd(unsigned char arrayId, unsigned short rowNum, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  180. {
  181. const unsigned long COMMAND_DATA_SIZE = 3;
  182. const unsigned int COMMAND_SIZE = BASE_CMD_SIZE + COMMAND_DATA_SIZE;
  183. unsigned short checksum;
  184. *resSize = BASE_CMD_SIZE;
  185. *cmdSize = COMMAND_SIZE;
  186. cmdBuf[0] = CMD_START;
  187. cmdBuf[1] = CMD_ERASE_ROW;
  188. cmdBuf[2] = (unsigned char)COMMAND_DATA_SIZE;
  189. cmdBuf[3] = (unsigned char)(COMMAND_DATA_SIZE >> 8);
  190. cmdBuf[4] = arrayId;
  191. cmdBuf[5] = (unsigned char)rowNum;
  192. cmdBuf[6] = (unsigned char)(rowNum >> 8);
  193. checksum = CyBtldr_ComputeChecksum(cmdBuf, COMMAND_SIZE - 3);
  194. cmdBuf[7] = (unsigned char)checksum;
  195. cmdBuf[8] = (unsigned char)(checksum >> 8);
  196. cmdBuf[9] = CMD_STOP;
  197. return CYRET_SUCCESS;
  198. }
  199. int CyBtldr_ParseEraseRowCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* status)
  200. {
  201. return CyBtldr_ParseDefaultCmdResult(cmdBuf, cmdSize, status);
  202. }
  203. int CyBtldr_CreateVerifyChecksumCmd(unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  204. {
  205. const unsigned long RESULT_DATA_SIZE = 1;
  206. unsigned short checksum;
  207. *resSize = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  208. *cmdSize = BASE_CMD_SIZE;
  209. cmdBuf[0] = CMD_START;
  210. cmdBuf[1] = CMD_VERIFY_CHECKSUM;
  211. cmdBuf[2] = 0;
  212. cmdBuf[3] = 0;
  213. checksum = CyBtldr_ComputeChecksum(cmdBuf, BASE_CMD_SIZE - 3);
  214. cmdBuf[4] = (unsigned char)checksum;
  215. cmdBuf[5] = (unsigned char)(checksum >> 8);
  216. cmdBuf[6] = CMD_STOP;
  217. return CYRET_SUCCESS;
  218. }
  219. int CyBtldr_ParseVerifyChecksumCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* checksumValid, unsigned char* status)
  220. {
  221. const unsigned long RESULT_DATA_SIZE = 1;
  222. const unsigned long RESULT_SIZE = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  223. int err = CYRET_SUCCESS;
  224. if (cmdSize != RESULT_SIZE)
  225. err = CYRET_ERR_LENGTH;
  226. else if (cmdBuf[1] != CYRET_SUCCESS)
  227. err = CYRET_ERR_BTLDR_MASK | (*status = cmdBuf[1]);
  228. else if (cmdBuf[0] != CMD_START || cmdBuf[2] != RESULT_DATA_SIZE || cmdBuf[3] != (RESULT_DATA_SIZE >> 8) || cmdBuf[RESULT_SIZE - 1] != CMD_STOP)
  229. err = CYRET_ERR_DATA;
  230. else
  231. {
  232. *checksumValid = cmdBuf[4];
  233. *status = cmdBuf[1];
  234. }
  235. return err;
  236. }
  237. int CyBtldr_CreateGetFlashSizeCmd(unsigned char arrayId, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  238. {
  239. const unsigned long RESULT_DATA_SIZE = 4;
  240. const unsigned long COMMAND_DATA_SIZE = 1;
  241. const unsigned int COMMAND_SIZE = BASE_CMD_SIZE + COMMAND_DATA_SIZE;
  242. unsigned short checksum;
  243. *resSize = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  244. *cmdSize = COMMAND_SIZE;
  245. cmdBuf[0] = CMD_START;
  246. cmdBuf[1] = CMD_GET_FLASH_SIZE;
  247. cmdBuf[2] = (unsigned char)COMMAND_DATA_SIZE;
  248. cmdBuf[3] = (unsigned char)(COMMAND_DATA_SIZE >> 8);
  249. cmdBuf[4] = arrayId;
  250. checksum = CyBtldr_ComputeChecksum(cmdBuf, COMMAND_SIZE - 3);
  251. cmdBuf[5] = (unsigned char)checksum;
  252. cmdBuf[6] = (unsigned char)(checksum >> 8);
  253. cmdBuf[7] = CMD_STOP;
  254. return CYRET_SUCCESS;
  255. }
  256. int CyBtldr_ParseGetFlashSizeCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned short* startRow, unsigned short* endRow, unsigned char* status)
  257. {
  258. const unsigned long RESULT_DATA_SIZE = 4;
  259. const unsigned long RESULT_SIZE = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  260. int err = CYRET_SUCCESS;
  261. if (cmdSize != RESULT_SIZE)
  262. err = CYRET_ERR_LENGTH;
  263. else if (cmdBuf[1] != CYRET_SUCCESS)
  264. err = CYRET_ERR_BTLDR_MASK | (*status = cmdBuf[1]);
  265. else if (cmdBuf[0] != CMD_START || cmdBuf[2] != RESULT_DATA_SIZE || cmdBuf[3] != (RESULT_DATA_SIZE >> 8) || cmdBuf[RESULT_SIZE - 1] != CMD_STOP)
  266. err = CYRET_ERR_DATA;
  267. else
  268. {
  269. *startRow = (cmdBuf[5] << 8) | cmdBuf[4];
  270. *endRow = (cmdBuf[7] << 8) | cmdBuf[6];
  271. *status = cmdBuf[1];
  272. }
  273. return err;
  274. }
  275. int CyBtldr_CreateSendDataCmd(unsigned char* buf, unsigned short size, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  276. {
  277. unsigned short checksum;
  278. unsigned long i;
  279. *resSize = BASE_CMD_SIZE;
  280. *cmdSize = size + BASE_CMD_SIZE;
  281. cmdBuf[0] = CMD_START;
  282. cmdBuf[1] = CMD_SEND_DATA;
  283. cmdBuf[2] = (unsigned char)size;
  284. cmdBuf[3] = (unsigned char)(size >> 8);
  285. for (i = 0; i < size; i++)
  286. cmdBuf[i + 4] = buf[i];
  287. checksum = CyBtldr_ComputeChecksum(cmdBuf, (*cmdSize) - 3);
  288. cmdBuf[(*cmdSize) - 3] = (unsigned char)checksum;
  289. cmdBuf[(*cmdSize) - 2] = (unsigned char)(checksum >> 8);
  290. cmdBuf[(*cmdSize) - 1] = CMD_STOP;
  291. return CYRET_SUCCESS;
  292. }
  293. int CyBtldr_ParseSendDataCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* status)
  294. {
  295. return CyBtldr_ParseDefaultCmdResult(cmdBuf, cmdSize, status);
  296. }
  297. int CyBtldr_CreateSyncBootLoaderCmd(unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  298. {
  299. unsigned short checksum;
  300. *resSize = BASE_CMD_SIZE;
  301. *cmdSize = BASE_CMD_SIZE;
  302. cmdBuf[0] = CMD_START;
  303. cmdBuf[1] = CMD_SYNC;
  304. cmdBuf[2] = 0;
  305. cmdBuf[3] = 0;
  306. checksum = CyBtldr_ComputeChecksum(cmdBuf, BASE_CMD_SIZE - 3);
  307. cmdBuf[4] = (unsigned char)checksum;
  308. cmdBuf[5] = (unsigned char)(checksum >> 8);
  309. cmdBuf[6] = CMD_STOP;
  310. return CYRET_SUCCESS;
  311. }
  312. int CyBtldr_CreateGetAppStatusCmd(unsigned char appId, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  313. {
  314. const unsigned long RESULT_DATA_SIZE = 2;
  315. const unsigned long COMMAND_DATA_SIZE = 1;
  316. const unsigned int COMMAND_SIZE = BASE_CMD_SIZE + COMMAND_DATA_SIZE;
  317. unsigned short checksum;
  318. *resSize = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  319. *cmdSize = COMMAND_SIZE;
  320. cmdBuf[0] = CMD_START;
  321. cmdBuf[1] = CMD_GET_APP_STATUS;
  322. cmdBuf[2] = (unsigned char)COMMAND_DATA_SIZE;
  323. cmdBuf[3] = (unsigned char)(COMMAND_DATA_SIZE >> 8);
  324. cmdBuf[4] = appId;
  325. checksum = CyBtldr_ComputeChecksum(cmdBuf, COMMAND_SIZE - 3);
  326. cmdBuf[5] = (unsigned char)checksum;
  327. cmdBuf[6] = (unsigned char)(checksum >> 8);
  328. cmdBuf[7] = CMD_STOP;
  329. return CYRET_SUCCESS;
  330. }
  331. int CyBtldr_ParseGetAppStatusCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* isValid, unsigned char* isActive, unsigned char* status)
  332. {
  333. const unsigned long RESULT_DATA_SIZE = 2;
  334. const unsigned long RESULT_SIZE = BASE_CMD_SIZE + RESULT_DATA_SIZE;
  335. int err = CYRET_SUCCESS;
  336. if (cmdSize != RESULT_SIZE)
  337. err = CYRET_ERR_LENGTH;
  338. else if (cmdBuf[1] != CYRET_SUCCESS)
  339. err = CYRET_ERR_BTLDR_MASK | (*status = cmdBuf[1]);
  340. else if (cmdBuf[0] != CMD_START || cmdBuf[2] != RESULT_DATA_SIZE || cmdBuf[3] != (RESULT_DATA_SIZE >> 8) || cmdBuf[RESULT_SIZE - 1] != CMD_STOP)
  341. err = CYRET_ERR_DATA;
  342. else
  343. {
  344. *isValid = cmdBuf[4];
  345. *isActive = cmdBuf[5];
  346. *status = cmdBuf[1];
  347. }
  348. return err;
  349. }
  350. int CyBtldr_CreateSetActiveAppCmd(unsigned char appId, unsigned char* cmdBuf, unsigned long* cmdSize, unsigned long* resSize)
  351. {
  352. const unsigned long COMMAND_DATA_SIZE = 1;
  353. const unsigned int COMMAND_SIZE = BASE_CMD_SIZE + COMMAND_DATA_SIZE;
  354. unsigned short checksum;
  355. *resSize = BASE_CMD_SIZE;
  356. *cmdSize = COMMAND_SIZE;
  357. cmdBuf[0] = CMD_START;
  358. cmdBuf[1] = CMD_SET_ACTIVE_APP;
  359. cmdBuf[2] = (unsigned char)COMMAND_DATA_SIZE;
  360. cmdBuf[3] = (unsigned char)(COMMAND_DATA_SIZE >> 8);
  361. cmdBuf[4] = appId;
  362. checksum = CyBtldr_ComputeChecksum(cmdBuf, COMMAND_SIZE - 3);
  363. cmdBuf[5] = (unsigned char)checksum;
  364. cmdBuf[6] = (unsigned char)(checksum >> 8);
  365. cmdBuf[7] = CMD_STOP;
  366. return CYRET_SUCCESS;
  367. }
  368. int CyBtldr_ParseSetActiveAppCmdResult(unsigned char* cmdBuf, unsigned long cmdSize, unsigned char* status)
  369. {
  370. return CyBtldr_ParseDefaultCmdResult(cmdBuf, cmdSize, status);
  371. }