FlashPrg.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* -----------------------------------------------------------------------------
  2. * Copyright (c) 2004 - 2014 ARM Ltd.
  3. *
  4. * This software is provided 'as-is', without any express or implied warranty.
  5. * In no event will the authors be held liable for any damages arising from
  6. * the use of this software. Permission is granted to anyone to use this
  7. * software for any purpose, including commercial applications, and to alter
  8. * it and redistribute it freely, subject to the following restrictions:
  9. *
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software in
  12. * a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. *
  15. * 2. Altered source versions must be plainly marked as such, and must not be
  16. * misrepresented as being the original software.
  17. *
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. *
  20. *
  21. * $Date: 17. June 2014
  22. * $Revision: V1.01
  23. *
  24. * Project: Flash Device Description for NXP LPC18xx/43xx Flash using IAP
  25. * --------------------------------------------------------------------------- */
  26. #include "..\FlashOS.H" // FlashOS Structures
  27. // Memory Mapping Control
  28. #ifdef LPC18xx43xx
  29. #define BASE_Mx_CLK (*(volatile unsigned long *) (0x4005006C))
  30. #endif
  31. #define BANK_A 0x1A000000
  32. #define BANK_B 0x1B000000
  33. #ifdef LPC18xx43xx
  34. #if defined FLASH_512_BA || FLASH_512_BB
  35. #define END_SECTOR 14
  36. #endif
  37. #if defined FLASH_384_BA || FLASH_384_BB
  38. #define END_SECTOR 12
  39. #endif
  40. #if defined FLASH_256_BA || FLASH_256_BB
  41. #define END_SECTOR 10
  42. #endif
  43. #endif // LPC18xx43xx
  44. unsigned long CCLK; // CCLK in kHz
  45. struct sIAP { // IAP Structure
  46. unsigned long cmd; // Command
  47. unsigned long par[5]; // Parameters
  48. unsigned long stat; // Status
  49. unsigned long res[4]; // Result
  50. } IAP;
  51. /* IAP Call */
  52. typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
  53. #define IAP_Call ((IAP_Entry) *((unsigned long *)0x10400100))
  54. unsigned long base_adr;
  55. unsigned long flash_bank;
  56. /*
  57. * Get Sector Number
  58. * Parameter: adr: Sector Address
  59. * Return Value: Sector Number
  60. */
  61. unsigned long GetSecNum (unsigned long adr) {
  62. unsigned long n;
  63. n = (adr & 0x000FF000) >> 13; // 8kB Sector
  64. if (n >= 0x07) {
  65. n = 0x07 + (n >> 3); // 64kB Sector
  66. }
  67. return (n); // Sector Number
  68. }
  69. /*
  70. * Initialize Flash Programming Functions
  71. * Parameter: adr: Device Base Address
  72. * clk: Clock Frequency (Hz)
  73. * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
  74. * Return Value: 0 - OK, 1 - Failed
  75. */
  76. int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
  77. base_adr = adr; // store Flash Base Address
  78. flash_bank = (adr == BANK_A) ? 0 : 1;
  79. BASE_Mx_CLK = (0x01 << 11) | // Autoblock En
  80. (0x01 << 24) ; // Set clock source to IRC
  81. CCLK = 12000; // 12MHz Internal RC Oscillator
  82. IAP.cmd = 49; // IAP initialization
  83. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  84. IAP.stat = 0; // Note: Some Bootloader versions don't set the status if this command is executed
  85. IAP.cmd = 54; // Read Part ID
  86. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  87. if (IAP.stat) return (1); // Command Failed
  88. return (0);
  89. }
  90. /*
  91. * De-Initialize Flash Programming Functions
  92. * Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
  93. * Return Value: 0 - OK, 1 - Failed
  94. */
  95. int UnInit (unsigned long fnc) {
  96. return (0);
  97. }
  98. /*
  99. * Erase complete Flash Memory
  100. * Return Value: 0 - OK, 1 - Failed
  101. */
  102. int EraseChip (void) {
  103. IAP.cmd = 50; // Prepare Sector for Erase
  104. IAP.par[0] = 0; // Start Sector
  105. IAP.par[1] = END_SECTOR; // End Sector
  106. IAP.par[2] = flash_bank; // Flashbank
  107. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  108. if (IAP.stat) return (1); // Command Failed
  109. IAP.cmd = 52; // Erase Sector
  110. IAP.par[0] = 0; // Start Sector
  111. IAP.par[1] = END_SECTOR; // End Sector
  112. IAP.par[2] = CCLK; // CCLK in kHz
  113. IAP.par[3] = flash_bank; // Flashbank
  114. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  115. if (IAP.stat) return (1); // Command Failed
  116. return (0); // Finished without Errors
  117. }
  118. /*
  119. * Erase Sector in Flash Memory
  120. * Parameter: adr: Sector Address
  121. * Return Value: 0 - OK, 1 - Failed
  122. */
  123. int EraseSector (unsigned long adr) {
  124. unsigned long n;
  125. n = GetSecNum(adr); // Get Sector Number
  126. IAP.cmd = 50; // Prepare Sector for Erase
  127. IAP.par[0] = n; // Start Sector
  128. IAP.par[1] = n; // End Sector
  129. IAP.par[2] = flash_bank; // Flashbank
  130. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  131. if (IAP.stat) return (1); // Command Failed
  132. IAP.cmd = 52; // Erase Sector
  133. IAP.par[0] = n; // Start Sector
  134. IAP.par[1] = n; // End Sector
  135. IAP.par[2] = CCLK; // CCLK in kHz
  136. IAP.par[3] = flash_bank; // Flashbank
  137. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  138. if (IAP.stat) return (1); // Command Failed
  139. return (0); // Finished without Errors
  140. }
  141. /*
  142. * Program Page in Flash Memory
  143. * Parameter: adr: Page Start Address
  144. * sz: Page Size
  145. * buf: Page Data
  146. * Return Value: 0 - OK, 1 - Failed
  147. */
  148. int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
  149. unsigned long n;
  150. unsigned long sig;
  151. n = GetSecNum(adr); // Get Sector Number
  152. IAP.cmd = 50; // Prepare Sector for Write
  153. IAP.par[0] = n; // Start Sector
  154. IAP.par[1] = n; // End Sector
  155. IAP.par[2] = flash_bank; // Flashbank
  156. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  157. if (IAP.stat) return (1); // Command Failed
  158. IAP.cmd = 51; // Copy RAM to Flash
  159. IAP.par[0] = adr; // Destination Flash Address
  160. IAP.par[1] = (unsigned long)buf; // Source RAM Address
  161. IAP.par[2] = 1024; // Fixed Page Size
  162. IAP.par[3] = CCLK; // CCLK in kHz
  163. IAP.par[4] = flash_bank; // Flashbank
  164. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  165. if (IAP.stat) return (1); // Command Failed
  166. /* calculates vectore checksum and more
  167. It is not used because it erases the signature in th eother bank!
  168. This could cause trouble if we want to have valid code or data in the other bank.
  169. Utility ElfDwt.exe must be used to calculate Signatute and stote it in AXF file.
  170. */
  171. // if (adr == base_adr) { // Set active partition to FLASH_BANK if vectors are written
  172. // IAP.cmd = 60; // Set active partition
  173. // IAP.par[0] = FLASH_BANK; // Flashbank
  174. // IAP.par[1] = CCLK; // CCLK in kHz
  175. // IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  176. // if (IAP.stat) return (1); // Command Failed
  177. // }
  178. #if 0
  179. we also removed all special handling about the vector checksum because
  180. it causes more trouble than solving problems. The user must now take
  181. care that only on valid checksum is in the application.
  182. if (adr == BANK_B) {
  183. sig = *((unsigned long *)(BANK_B + 0x00)) +
  184. *((unsigned long *)(BANK_B + 0x04)) +
  185. *((unsigned long *)(BANK_B + 0x08)) +
  186. *((unsigned long *)(BANK_B + 0x0C)) +
  187. *((unsigned long *)(BANK_B + 0x10)) +
  188. *((unsigned long *)(BANK_B + 0x14)) +
  189. *((unsigned long *)(BANK_B + 0x18));
  190. if (*((unsigned long *)(BANK_B + 0x1C)) == (0 - sig)) {
  191. /* we have just written a valid signature to BankB. We assume that we must boot from BankB
  192. check if a valid signature is in BankA. If so delete it. */
  193. sig = *((unsigned long *)(BANK_A + 0x00)) +
  194. *((unsigned long *)(BANK_A + 0x04)) +
  195. *((unsigned long *)(BANK_A + 0x08)) +
  196. *((unsigned long *)(BANK_A + 0x0C)) +
  197. *((unsigned long *)(BANK_A + 0x10)) +
  198. *((unsigned long *)(BANK_A + 0x14)) +
  199. *((unsigned long *)(BANK_A + 0x18));
  200. /* delete signature if a valid signature is found */
  201. if (*((unsigned long *)(BANK_A + 0x1C)) == (0 - sig)) {
  202. for (n = 0; n < (512); n++) {
  203. *(buf + n) = *((unsigned char *)(BANK_A + n)); // copy page to RAM
  204. }
  205. *((unsigned long *)(buf + 0x1C)) = 0; // invalid Signature at Reserved Vector
  206. IAP.cmd = 50; // Prepare Sector for Write
  207. IAP.par[0] = 0; // Start Sector
  208. IAP.par[1] = 0; // End Sector
  209. IAP.par[2] = 0; // Flashbank
  210. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  211. if (IAP.stat) return (1); // Command Failed
  212. IAP.cmd = 59; // Erase Page
  213. IAP.par[0] = BANK_A; // Start Page Address
  214. IAP.par[1] = BANK_A; // End Page Address
  215. IAP.par[2] = CCLK; // CCLK in kHz
  216. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  217. if (IAP.stat) return (1); // Command Failed
  218. IAP.cmd = 50; // Prepare Sector for Write
  219. IAP.par[0] = 0; // Start Sector
  220. IAP.par[1] = 0; // End Sector
  221. IAP.par[2] = 0; // Flashbank
  222. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  223. if (IAP.stat) return (1); // Command Failed
  224. IAP.cmd = 51; // Copy RAM to Flash
  225. IAP.par[0] = BANK_A; // Destination Flash Address
  226. IAP.par[1] = (unsigned long)buf; // Source RAM Address
  227. IAP.par[2] = 512; // Fixed Page Size
  228. IAP.par[3] = CCLK; // CCLK in kHz
  229. IAP.par[4] = 0; // Flashbank
  230. IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
  231. if (IAP.stat) return (1); // Command Failed
  232. }
  233. }
  234. }
  235. #endif
  236. return (0); // Finished without Errors
  237. }