My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lpc17xx_iap.c 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /**********************************************************************
  2. * $Id$ lpc17xx_iap.c 2012-04-18
  3. *//**
  4. * @file lpc17xx_iap.c
  5. * @brief Contains all functions support for IAP on lpc17xx
  6. * @version 1.0
  7. * @date 18. April. 2012
  8. * @author NXP MCU SW Application Team
  9. *
  10. * Copyright(C) 2011, NXP Semiconductor
  11. * All rights reserved.
  12. *
  13. ***********************************************************************
  14. * Software that is described herein is for illustrative purposes only
  15. * which provides customers with programming information regarding the
  16. * products. This software is supplied "AS IS" without any warranties.
  17. * NXP Semiconductors assumes no responsibility or liability for the
  18. * use of the software, conveys no license or title under any patent,
  19. * copyright, or mask work right to the product. NXP Semiconductors
  20. * reserves the right to make changes in the software without
  21. * notification. NXP Semiconductors also make no representation or
  22. * warranty that such application will be suitable for the specified
  23. * use without further testing or modification.
  24. * Permission to use, copy, modify, and distribute this software and its
  25. * documentation is hereby granted, under NXP Semiconductors'
  26. * relevant copyright in the software, without fee, provided that it
  27. * is used in conjunction with NXP Semiconductors microcontrollers. This
  28. * copyright, permission, and disclaimer notice must appear in all copies of
  29. * this code.
  30. **********************************************************************/
  31. #include "lpc17xx_iap.h"
  32. #include "system_LPC17xx.h"
  33. // IAP Command
  34. typedef void (*IAP)(uint32_t *cmd,uint32_t *result);
  35. IAP iap_entry = (IAP) IAP_LOCATION;
  36. #define IAP_Call iap_entry
  37. /** @addtogroup IAP_Public_Functions IAP Public Function
  38. * @ingroup IAP
  39. * @{
  40. */
  41. /*********************************************************************//**
  42. * @brief Get Sector Number
  43. *
  44. * @param[in] adr Sector Address
  45. *
  46. * @return Sector Number.
  47. *
  48. **********************************************************************/
  49. uint32_t GetSecNum (uint32_t adr)
  50. {
  51. uint32_t n;
  52. n = adr >> 12; // 4kB Sector
  53. if (n >= 0x10) {
  54. n = 0x0E + (n >> 3); // 32kB Sector
  55. }
  56. return (n); // Sector Number
  57. }
  58. /*********************************************************************//**
  59. * @brief Prepare sector(s) for write operation
  60. *
  61. * @param[in] start_sec The number of start sector
  62. * @param[in] end_sec The number of end sector
  63. *
  64. * @return CMD_SUCCESS/BUSY/INVALID_SECTOR.
  65. *
  66. **********************************************************************/
  67. IAP_STATUS_CODE PrepareSector(uint32_t start_sec, uint32_t end_sec)
  68. {
  69. IAP_COMMAND_Type command;
  70. command.cmd = IAP_PREPARE; // Prepare Sector for Write
  71. command.param[0] = start_sec; // Start Sector
  72. command.param[1] = end_sec; // End Sector
  73. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  74. return (IAP_STATUS_CODE)command.status;
  75. }
  76. /*********************************************************************//**
  77. * @brief Copy RAM to Flash
  78. *
  79. * @param[in] dest destination buffer (in Flash memory).
  80. * @param[in] source source buffer (in RAM).
  81. * @param[in] size the write size.
  82. *
  83. * @return CMD_SUCCESS.
  84. * SRC_ADDR_ERROR/DST_ADDR_ERROR
  85. * SRC_ADDR_NOT_MAPPED/DST_ADDR_NOT_MAPPED
  86. * COUNT_ERROR/SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION
  87. * BUSY
  88. *
  89. **********************************************************************/
  90. IAP_STATUS_CODE CopyRAM2Flash(uint8_t * dest, uint8_t* source, IAP_WRITE_SIZE size)
  91. {
  92. uint32_t sec;
  93. IAP_STATUS_CODE status;
  94. IAP_COMMAND_Type command;
  95. // Prepare sectors
  96. sec = GetSecNum((uint32_t)dest);
  97. status = PrepareSector(sec, sec);
  98. if(status != CMD_SUCCESS)
  99. return status;
  100. // write
  101. command.cmd = IAP_COPY_RAM2FLASH; // Copy RAM to Flash
  102. command.param[0] = (uint32_t)dest; // Destination Flash Address
  103. command.param[1] = (uint32_t)source; // Source RAM Address
  104. command.param[2] = size; // Number of bytes
  105. command.param[3] = SystemCoreClock / 1000; // CCLK in kHz
  106. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  107. return (IAP_STATUS_CODE)command.status; // Finished without Errors
  108. }
  109. /*********************************************************************//**
  110. * @brief Erase sector(s)
  111. *
  112. * @param[in] start_sec The number of start sector
  113. * @param[in] end_sec The number of end sector
  114. *
  115. * @return CMD_SUCCESS.
  116. * INVALID_SECTOR
  117. * SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION
  118. * BUSY
  119. *
  120. **********************************************************************/
  121. IAP_STATUS_CODE EraseSector(uint32_t start_sec, uint32_t end_sec)
  122. {
  123. IAP_COMMAND_Type command;
  124. IAP_STATUS_CODE status;
  125. // Prepare sectors
  126. status = PrepareSector(start_sec, end_sec);
  127. if(status != CMD_SUCCESS)
  128. return status;
  129. // Erase sectors
  130. command.cmd = IAP_ERASE; // Prepare Sector for Write
  131. command.param[0] = start_sec; // Start Sector
  132. command.param[1] = end_sec; // End Sector
  133. command.param[2] = SystemCoreClock / 1000; // CCLK in kHz
  134. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  135. return (IAP_STATUS_CODE)command.status;
  136. }
  137. /*********************************************************************//**
  138. * @brief Blank check sector(s)
  139. *
  140. * @param[in] start_sec The number of start sector
  141. * @param[in] end_sec The number of end sector
  142. * @param[out] first_nblank_loc The offset of the first non-blank word
  143. * @param[out] first_nblank_val The value of the first non-blank word
  144. *
  145. * @return CMD_SUCCESS.
  146. * INVALID_SECTOR
  147. * SECTOR_NOT_BLANK
  148. * BUSY
  149. *
  150. **********************************************************************/
  151. IAP_STATUS_CODE BlankCheckSector(uint32_t start_sec, uint32_t end_sec,
  152. uint32_t *first_nblank_loc,
  153. uint32_t *first_nblank_val)
  154. {
  155. IAP_COMMAND_Type command;
  156. command.cmd = IAP_BLANK_CHECK; // Prepare Sector for Write
  157. command.param[0] = start_sec; // Start Sector
  158. command.param[1] = end_sec; // End Sector
  159. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  160. if(command.status == SECTOR_NOT_BLANK)
  161. {
  162. // Update out value
  163. if(first_nblank_loc != NULL)
  164. *first_nblank_loc = command.result[0];
  165. if(first_nblank_val != NULL)
  166. *first_nblank_val = command.result[1];
  167. }
  168. return (IAP_STATUS_CODE)command.status;
  169. }
  170. /*********************************************************************//**
  171. * @brief Read part identification number
  172. *
  173. * @param[out] partID Part ID
  174. *
  175. * @return CMD_SUCCESS
  176. *
  177. **********************************************************************/
  178. IAP_STATUS_CODE ReadPartID(uint32_t *partID)
  179. {
  180. IAP_COMMAND_Type command;
  181. command.cmd = IAP_READ_PART_ID;
  182. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  183. if(command.status == CMD_SUCCESS)
  184. {
  185. if(partID != NULL)
  186. *partID = command.result[0];
  187. }
  188. return (IAP_STATUS_CODE)command.status;
  189. }
  190. /*********************************************************************//**
  191. * @brief Read boot code version. The version is interpreted as <major>.<minor>.
  192. *
  193. * @param[out] major The major
  194. * @param[out] minor The minor
  195. *
  196. * @return CMD_SUCCESS
  197. *
  198. **********************************************************************/
  199. IAP_STATUS_CODE ReadBootCodeVer(uint8_t *major, uint8_t* minor)
  200. {
  201. IAP_COMMAND_Type command;
  202. command.cmd = IAP_READ_BOOT_VER;
  203. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  204. if(command.status == CMD_SUCCESS)
  205. {
  206. if(major != NULL)
  207. *major = (command.result[0] >> 8) & 0xFF;
  208. if(minor != NULL)
  209. *minor = (command.result[0]) & 0xFF;
  210. }
  211. return (IAP_STATUS_CODE)command.status;
  212. }
  213. /*********************************************************************//**
  214. * @brief Read Device serial number.
  215. *
  216. * @param[out] uid Serial number.
  217. *
  218. * @return CMD_SUCCESS
  219. *
  220. **********************************************************************/
  221. IAP_STATUS_CODE ReadDeviceSerialNum(uint32_t *uid)
  222. {
  223. IAP_COMMAND_Type command;
  224. command.cmd = IAP_READ_SERIAL_NUMBER;
  225. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  226. if(command.status == CMD_SUCCESS)
  227. {
  228. if(uid != NULL)
  229. {
  230. uint32_t i = 0;
  231. for(i = 0; i < 4; i++)
  232. uid[i] = command.result[i];
  233. }
  234. }
  235. return (IAP_STATUS_CODE)command.status;
  236. }
  237. /*********************************************************************//**
  238. * @brief compare the memory contents at two locations.
  239. *
  240. * @param[in] addr1 The address of the 1st buffer (in RAM/Flash).
  241. * @param[in] addr2 The address of the 2nd buffer (in RAM/Flash).
  242. * @param[in] size Number of bytes to be compared; should be a multiple of 4.
  243. *
  244. * @return CMD_SUCCESS
  245. * COMPARE_ERROR
  246. * COUNT_ERROR (Byte count is not a multiple of 4)
  247. * ADDR_ERROR
  248. * ADDR_NOT_MAPPED
  249. *
  250. **********************************************************************/
  251. IAP_STATUS_CODE Compare(uint8_t *addr1, uint8_t *addr2, uint32_t size)
  252. {
  253. IAP_COMMAND_Type command;
  254. command.cmd = IAP_COMPARE;
  255. command.param[0] = (uint32_t)addr1;
  256. command.param[1] = (uint32_t)addr2;
  257. command.param[2] = size;
  258. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  259. return (IAP_STATUS_CODE)command.status;
  260. }
  261. /*********************************************************************//**
  262. * @brief Re-invoke ISP.
  263. *
  264. * @param[in] None.
  265. *
  266. * @return None.
  267. *
  268. **********************************************************************/
  269. void InvokeISP(void)
  270. {
  271. IAP_COMMAND_Type command;
  272. command.cmd = IAP_REINVOKE_ISP;
  273. IAP_Call (&command.cmd, &command.status); // Call IAP Command
  274. }
  275. /**
  276. * @}
  277. */