cybtldr_api2.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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 <string.h>
  8. #include "cybtldr_parse.h"
  9. #include "cybtldr_command.h"
  10. #include "cybtldr_api.h"
  11. #include "cybtldr_api2.h"
  12. unsigned char g_abort;
  13. int CyBtldr_RunAction(CyBtldr_Action action, const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
  14. {
  15. const unsigned long BL_VER_SUPPORT_VERIFY = 0x010214; /* Support for full flash verify added in v2.20 of cy_boot */
  16. const unsigned char INVALID_APP = 0xFF;
  17. unsigned long blVer = 0;
  18. unsigned long siliconId = 0;
  19. unsigned short rowNum = 0;
  20. unsigned short bufSize = 0;
  21. unsigned char siliconRev = 0;
  22. unsigned char chksumtype = SUM_CHECKSUM;
  23. unsigned char checksum = 0;
  24. unsigned char checksum2 = 0;
  25. unsigned char arrayId = 0;
  26. unsigned char appId;
  27. unsigned char isValid;
  28. unsigned char isActive;
  29. unsigned char buffer[MAX_BUFFER_SIZE];
  30. char line[MAX_BUFFER_SIZE];
  31. unsigned int lineLen;
  32. char * app;
  33. int err;
  34. g_abort = 0;
  35. err = CyBtldr_OpenDataFile(file);
  36. if (CYRET_SUCCESS == err)
  37. {
  38. err = CyBtldr_ReadLine(&lineLen, line);
  39. if (CYRET_SUCCESS == err)
  40. err = CyBtldr_ParseHeader(lineLen, line, &siliconId, &siliconRev, &chksumtype);
  41. if (CYRET_SUCCESS == err)
  42. {
  43. CyBtldr_SetCheckSumType(chksumtype);
  44. err = CyBtldr_StartBootloadOperation(comm, siliconId, siliconRev, &blVer);
  45. }
  46. app = strrchr(file, '_');
  47. appId = (app != NULL && '.' == app[2])
  48. ? (CyBtldr_FromHex(app[1]) - 1)
  49. : INVALID_APP;
  50. if (CYRET_SUCCESS == err && INVALID_APP != appId)
  51. {
  52. /* NB: This block of code will still run for single app if file */
  53. /* name format follows same as multi app (e.g. myfile_1.cyacd) */
  54. /* This will return error if bootloader is for single app */
  55. err = CyBtldr_GetApplicationStatus(appId, &isValid, &isActive);
  56. /* Active app can be verified, but not programmed or erased */
  57. if (CYRET_SUCCESS == err && VERIFY != action && isActive)
  58. {
  59. /* This is multi app */
  60. err = CYRET_ERR_ACTIVE;
  61. }
  62. else if (CYBTLDR_STAT_ERR_CMD == (err ^ (int)CYRET_ERR_BTLDR_MASK))
  63. {
  64. /* Single app - restore previous CYRET_SUCCESS */
  65. err = CYRET_SUCCESS;
  66. }
  67. }
  68. if (CYRET_SUCCESS == err)
  69. {
  70. while (CYRET_SUCCESS == err)
  71. {
  72. if (g_abort)
  73. {
  74. err = CYRET_ABORT;
  75. break;
  76. }
  77. err = CyBtldr_ReadLine(&lineLen, line);
  78. if (CYRET_SUCCESS == err)
  79. err = CyBtldr_ParseRowData(lineLen, line, &arrayId, &rowNum, buffer, &bufSize, &checksum);
  80. if (CYRET_SUCCESS == err)
  81. {
  82. switch (action)
  83. {
  84. case ERASE:
  85. err = CyBtldr_EraseRow(arrayId, rowNum);
  86. break;
  87. case PROGRAM:
  88. err = CyBtldr_ProgramRow(arrayId, rowNum, buffer, bufSize);
  89. if (CYRET_SUCCESS != err)
  90. break;
  91. /* Continue on to verify the row that was programmed */
  92. case VERIFY:
  93. checksum2 = (unsigned char)(checksum + arrayId + rowNum + (rowNum >> 8) + bufSize + (bufSize >> 8));
  94. err = CyBtldr_VerifyRow(arrayId, rowNum, checksum2);
  95. break;
  96. }
  97. if (CYRET_SUCCESS == err && NULL != update)
  98. update(arrayId, rowNum);
  99. }
  100. else if (CYRET_ERR_EOF == err)
  101. {
  102. err = CYRET_SUCCESS;
  103. break;
  104. }
  105. }
  106. if (CYRET_SUCCESS == err)
  107. {
  108. /* Set the active application to what was just programmed */
  109. if (PROGRAM == action && INVALID_APP != appId)
  110. {
  111. err = CyBtldr_GetApplicationStatus(appId, &isValid, &isActive);
  112. if (CYRET_SUCCESS == err)
  113. {
  114. /* If valid set the active application to what was just programmed */
  115. /* This is multi app */
  116. err = (0 == isValid)
  117. ? CyBtldr_SetApplicationStatus(appId)
  118. : CYRET_ERR_CHECKSUM;
  119. }
  120. else if (CYBTLDR_STAT_ERR_CMD == (err ^ (int)CYRET_ERR_BTLDR_MASK))
  121. {
  122. /* Single app - restore previous CYRET_SUCCESS */
  123. err = CYRET_SUCCESS;
  124. }
  125. }
  126. /* Verify that the entire application is valid */
  127. else if ((PROGRAM == action || VERIFY == action) && (blVer >= BL_VER_SUPPORT_VERIFY))
  128. err = CyBtldr_VerifyApplication();
  129. }
  130. CyBtldr_EndBootloadOperation();
  131. }
  132. else if (CYRET_ERR_COMM_MASK != (CYRET_ERR_COMM_MASK & err))
  133. CyBtldr_EndBootloadOperation();
  134. CyBtldr_CloseDataFile();
  135. }
  136. return err;
  137. }
  138. int CyBtldr_Program(const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
  139. {
  140. return CyBtldr_RunAction(PROGRAM, file, comm, update);
  141. }
  142. int CyBtldr_Erase(const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
  143. {
  144. return CyBtldr_RunAction(ERASE, file, comm, update);
  145. }
  146. int CyBtldr_Verify(const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
  147. {
  148. return CyBtldr_RunAction(VERIFY, file, comm, update);
  149. }
  150. int CyBtldr_Abort(void)
  151. {
  152. g_abort = 1;
  153. return CYRET_SUCCESS;
  154. }