cybtldr_api.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. #include "cybtldr_api.h"
  9. /* The highest number of flash array for any device */
  10. #define MAX_FLASH_ARRAYS 4
  11. /* The default value if a flash array has not yet received data */
  12. #define NO_FLASH_ARRAY_DATA 0
  13. unsigned long g_validRows[MAX_FLASH_ARRAYS];
  14. static CyBtldr_CommunicationsData* g_comm;
  15. int CyBtldr_TransferData(unsigned char* inBuf, int inSize, unsigned char* outBuf, int outSize)
  16. {
  17. int err = g_comm->WriteData(inBuf, inSize);
  18. if (CYRET_SUCCESS == err)
  19. err = g_comm->ReadData(outBuf, outSize);
  20. if (CYRET_SUCCESS != err)
  21. err |= CYRET_ERR_COMM_MASK;
  22. return err;
  23. }
  24. int CyBtldr_ValidateRow(unsigned char arrayId, unsigned short rowNum)
  25. {
  26. unsigned long inSize;
  27. unsigned long outSize;
  28. unsigned short minRow = 0;
  29. unsigned short maxRow = 0;
  30. unsigned char inBuf[MAX_COMMAND_SIZE];
  31. unsigned char outBuf[MAX_COMMAND_SIZE];
  32. unsigned char status = CYRET_SUCCESS;
  33. int err = CYRET_SUCCESS;
  34. if (arrayId < MAX_FLASH_ARRAYS)
  35. {
  36. if (NO_FLASH_ARRAY_DATA == g_validRows[arrayId])
  37. {
  38. err = CyBtldr_CreateGetFlashSizeCmd(arrayId, inBuf, &inSize, &outSize);
  39. if (CYRET_SUCCESS == err)
  40. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  41. if (CYRET_SUCCESS == err)
  42. err = CyBtldr_ParseGetFlashSizeCmdResult(outBuf, outSize, &minRow, &maxRow, &status);
  43. if (CYRET_SUCCESS != status)
  44. err = status | CYRET_ERR_BTLDR_MASK;
  45. if (CYRET_SUCCESS == err)
  46. {
  47. if (CYRET_SUCCESS == status)
  48. g_validRows[arrayId] = (minRow << 16) + maxRow;
  49. else
  50. err = status | CYRET_ERR_BTLDR_MASK;
  51. }
  52. }
  53. if (CYRET_SUCCESS == err)
  54. {
  55. minRow = (unsigned short)(g_validRows[arrayId] >> 16);
  56. maxRow = (unsigned short)g_validRows[arrayId];
  57. if (rowNum < minRow || rowNum > maxRow)
  58. err = CYRET_ERR_ROW;
  59. }
  60. }
  61. else
  62. err = CYRET_ERR_ARRAY;
  63. return err;
  64. }
  65. int CyBtldr_StartBootloadOperation(CyBtldr_CommunicationsData* comm, unsigned long expSiId, unsigned char expSiRev, unsigned long* blVer)
  66. {
  67. const unsigned long SUPPORTED_BOOTLOADER = 0x010000;
  68. const unsigned long BOOTLOADER_VERSION_MASK = 0xFF0000;
  69. unsigned long i;
  70. unsigned long inSize = 0;
  71. unsigned long outSize = 0;
  72. unsigned long siliconId = 0;
  73. unsigned char inBuf[MAX_COMMAND_SIZE];
  74. unsigned char outBuf[MAX_COMMAND_SIZE];
  75. unsigned char siliconRev = 0;
  76. unsigned char status = CYRET_SUCCESS;
  77. int err;
  78. g_comm = comm;
  79. for (i = 0; i < MAX_FLASH_ARRAYS; i++)
  80. g_validRows[i] = NO_FLASH_ARRAY_DATA;
  81. err = g_comm->OpenConnection();
  82. if (CYRET_SUCCESS != err)
  83. err |= CYRET_ERR_COMM_MASK;
  84. if (CYRET_SUCCESS == err)
  85. err = CyBtldr_CreateEnterBootLoaderCmd(inBuf, &inSize, &outSize);
  86. if (CYRET_SUCCESS == err)
  87. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  88. if (CYRET_SUCCESS == err)
  89. err = CyBtldr_ParseEnterBootLoaderCmdResult(outBuf, outSize, &siliconId, &siliconRev, blVer, &status);
  90. if (CYRET_SUCCESS == err)
  91. {
  92. if (CYRET_SUCCESS != status)
  93. err = status | CYRET_ERR_BTLDR_MASK;
  94. if (expSiId != siliconId || expSiRev != siliconRev)
  95. err = CYRET_ERR_DEVICE;
  96. else if ((*blVer & BOOTLOADER_VERSION_MASK) != SUPPORTED_BOOTLOADER)
  97. err = CYRET_ERR_VERSION;
  98. }
  99. return err;
  100. }
  101. int CyBtldr_GetApplicationStatus(unsigned char appID, unsigned char* isValid, unsigned char* isActive)
  102. {
  103. unsigned long inSize = 0;
  104. unsigned long outSize = 0;
  105. unsigned char inBuf[MAX_COMMAND_SIZE];
  106. unsigned char outBuf[MAX_COMMAND_SIZE];
  107. unsigned char status = CYRET_SUCCESS;
  108. int err;
  109. err = CyBtldr_CreateGetAppStatusCmd(appID, inBuf, &inSize, &outSize);
  110. if (CYRET_SUCCESS == err)
  111. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  112. if (CYRET_SUCCESS == err)
  113. err = CyBtldr_ParseGetAppStatusCmdResult(outBuf, outSize, isValid, isActive, &status);
  114. if (CYRET_SUCCESS == err)
  115. {
  116. if (CYRET_SUCCESS != status)
  117. err = status | CYRET_ERR_BTLDR_MASK;
  118. }
  119. return err;
  120. }
  121. int CyBtldr_SetApplicationStatus(unsigned char appID)
  122. {
  123. unsigned long inSize = 0;
  124. unsigned long outSize = 0;
  125. unsigned char inBuf[MAX_COMMAND_SIZE];
  126. unsigned char outBuf[MAX_COMMAND_SIZE];
  127. unsigned char status = CYRET_SUCCESS;
  128. int err;
  129. err = CyBtldr_CreateSetActiveAppCmd(appID, inBuf, &inSize, &outSize);
  130. if (CYRET_SUCCESS == err)
  131. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  132. if (CYRET_SUCCESS == err)
  133. err = CyBtldr_ParseSetActiveAppCmdResult(outBuf, outSize, &status);
  134. if (CYRET_SUCCESS == err)
  135. {
  136. if (CYRET_SUCCESS != status)
  137. err = status | CYRET_ERR_BTLDR_MASK;
  138. }
  139. return err;
  140. }
  141. int CyBtldr_EndBootloadOperation(void)
  142. {
  143. const unsigned char RESET = 0x00;
  144. unsigned long inSize;
  145. unsigned long outSize;
  146. unsigned char inBuf[MAX_COMMAND_SIZE];
  147. int err = CyBtldr_CreateExitBootLoaderCmd(RESET, inBuf, &inSize, &outSize);
  148. if (CYRET_SUCCESS == err)
  149. {
  150. err = g_comm->WriteData(inBuf, inSize);
  151. if (CYRET_SUCCESS == err)
  152. err = g_comm->CloseConnection();
  153. if (CYRET_SUCCESS != err)
  154. err |= CYRET_ERR_COMM_MASK;
  155. }
  156. g_comm = NULL;
  157. return err;
  158. }
  159. int CyBtldr_ProgramRow(unsigned char arrayID, unsigned short rowNum, unsigned char* buf, unsigned short size)
  160. {
  161. const int TRANSFER_HEADER_SIZE = 11;
  162. unsigned char inBuf[MAX_COMMAND_SIZE];
  163. unsigned char outBuf[MAX_COMMAND_SIZE];
  164. unsigned long inSize;
  165. unsigned long outSize;
  166. unsigned long offset = 0;
  167. unsigned short subBufSize;
  168. unsigned char status = CYRET_SUCCESS;
  169. int err = CyBtldr_ValidateRow(arrayID, rowNum);
  170. //Break row into pieces to ensure we don't send too much for the transfer protocol
  171. while ((CYRET_SUCCESS == err) && ((size - offset + TRANSFER_HEADER_SIZE) > g_comm->MaxTransferSize))
  172. {
  173. subBufSize = (unsigned short)(g_comm->MaxTransferSize - TRANSFER_HEADER_SIZE);
  174. err = CyBtldr_CreateSendDataCmd(&buf[offset], subBufSize, inBuf, &inSize, &outSize);
  175. if (CYRET_SUCCESS == err)
  176. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  177. if (CYRET_SUCCESS == err)
  178. err = CyBtldr_ParseSendDataCmdResult(outBuf, outSize, &status);
  179. if (CYRET_SUCCESS != status)
  180. err = status | CYRET_ERR_BTLDR_MASK;
  181. offset += subBufSize;
  182. }
  183. if (CYRET_SUCCESS == err)
  184. {
  185. subBufSize = (unsigned short)(size - offset);
  186. err = CyBtldr_CreateProgramRowCmd(arrayID, rowNum, &buf[offset], subBufSize, inBuf, &inSize, &outSize);
  187. if (CYRET_SUCCESS == err)
  188. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  189. if (CYRET_SUCCESS == err)
  190. err = CyBtldr_ParseProgramRowCmdResult(outBuf, outSize, &status);
  191. if (CYRET_SUCCESS != status)
  192. err = status | CYRET_ERR_BTLDR_MASK;
  193. }
  194. return err;
  195. }
  196. int CyBtldr_EraseRow(unsigned char arrayID, unsigned short rowNum)
  197. {
  198. unsigned char inBuf[MAX_COMMAND_SIZE];
  199. unsigned char outBuf[MAX_COMMAND_SIZE];
  200. unsigned long inSize = 0;
  201. unsigned long outSize = 0;
  202. unsigned char status = CYRET_SUCCESS;
  203. int err = CyBtldr_ValidateRow(arrayID, rowNum);
  204. if (CYRET_SUCCESS == err)
  205. err = CyBtldr_CreateEraseRowCmd(arrayID, rowNum, inBuf, &inSize, &outSize);
  206. if (CYRET_SUCCESS == err)
  207. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  208. if (CYRET_SUCCESS == err)
  209. err = CyBtldr_ParseEraseRowCmdResult(outBuf, outSize, &status);
  210. if (CYRET_SUCCESS != status)
  211. err = status | CYRET_ERR_BTLDR_MASK;
  212. return err;
  213. }
  214. int CyBtldr_VerifyRow(unsigned char arrayID, unsigned short rowNum, unsigned char checksum)
  215. {
  216. unsigned char inBuf[MAX_COMMAND_SIZE];
  217. unsigned char outBuf[MAX_COMMAND_SIZE];
  218. unsigned long inSize = 0;
  219. unsigned long outSize = 0;
  220. unsigned char rowChecksum = 0;
  221. unsigned char status = CYRET_SUCCESS;
  222. int err = CyBtldr_ValidateRow(arrayID, rowNum);
  223. if (CYRET_SUCCESS == err)
  224. err = CyBtldr_CreateVerifyRowCmd(arrayID, rowNum, inBuf, &inSize, &outSize);
  225. if (CYRET_SUCCESS == err)
  226. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  227. if (CYRET_SUCCESS == err)
  228. err = CyBtldr_ParseVerifyRowCmdResult(outBuf, outSize, &rowChecksum, &status);
  229. if (CYRET_SUCCESS != status)
  230. err = status | CYRET_ERR_BTLDR_MASK;
  231. if ((CYRET_SUCCESS == err) && (rowChecksum != checksum))
  232. err = CYRET_ERR_CHECKSUM;
  233. return err;
  234. }
  235. int CyBtldr_VerifyApplication()
  236. {
  237. unsigned char inBuf[MAX_COMMAND_SIZE];
  238. unsigned char outBuf[MAX_COMMAND_SIZE];
  239. unsigned long inSize = 0;
  240. unsigned long outSize = 0;
  241. unsigned char checksumValid = 0;
  242. unsigned char status = CYRET_SUCCESS;
  243. int err = CyBtldr_CreateVerifyChecksumCmd(inBuf, &inSize, &outSize);
  244. if (CYRET_SUCCESS == err)
  245. err = CyBtldr_TransferData(inBuf, inSize, outBuf, outSize);
  246. if (CYRET_SUCCESS == err)
  247. err = CyBtldr_ParseVerifyChecksumCmdResult(outBuf, outSize, &checksumValid, &status);
  248. if (CYRET_SUCCESS != status)
  249. err = status | CYRET_ERR_BTLDR_MASK;
  250. if ((CYRET_SUCCESS == err) && (!checksumValid))
  251. err = CYRET_ERR_CHECKSUM;
  252. return err;
  253. }