flashc.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. /* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
  2. /*This file is prepared for Doxygen automatic documentation generation.*/
  3. /*! \file *********************************************************************
  4. *
  5. * \brief FLASHC driver for AVR32 UC3.
  6. *
  7. * AVR32 Flash Controller driver module.
  8. *
  9. * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
  10. * - Supported devices: All AVR32 devices with a FLASHC module can be used.
  11. * - AppNote:
  12. *
  13. * \author Atmel Corporation: http://www.atmel.com \n
  14. * Support and FAQ: http://support.atmel.no/
  15. *
  16. ******************************************************************************/
  17. /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
  18. *
  19. * Redistribution and use in source and binary forms, with or without
  20. * modification, are permitted provided that the following conditions are met:
  21. *
  22. * 1. Redistributions of source code must retain the above copyright notice, this
  23. * list of conditions and the following disclaimer.
  24. *
  25. * 2. Redistributions in binary form must reproduce the above copyright notice,
  26. * this list of conditions and the following disclaimer in the documentation
  27. * and/or other materials provided with the distribution.
  28. *
  29. * 3. The name of Atmel may not be used to endorse or promote products derived
  30. * from this software without specific prior written permission.
  31. *
  32. * 4. This software may only be redistributed and used in connection with an Atmel
  33. * AVR product.
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  37. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  38. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  39. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  42. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
  45. *
  46. */
  47. #include <avr32/io.h>
  48. #include <stddef.h>
  49. #include "compiler.h"
  50. #include "flashc.h"
  51. /*! \name FLASHC Writable Bit-Field Registers
  52. */
  53. //! @{
  54. typedef union
  55. {
  56. unsigned long fcr;
  57. avr32_flashc_fcr_t FCR;
  58. } u_avr32_flashc_fcr_t;
  59. typedef union
  60. {
  61. unsigned long fcmd;
  62. avr32_flashc_fcmd_t FCMD;
  63. } u_avr32_flashc_fcmd_t;
  64. //! @}
  65. /*! \name Flash Properties
  66. */
  67. //! @{
  68. unsigned int flashc_get_flash_size(void)
  69. {
  70. #if (defined AVR32_FLASHC_300_H_INCLUDED)
  71. static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_PR_FSZ_SIZE] =
  72. {
  73. 32 << 10,
  74. 64 << 10,
  75. 128 << 10,
  76. 256 << 10,
  77. 384 << 10,
  78. 512 << 10,
  79. 768 << 10,
  80. 1024 << 10
  81. };
  82. return FLASH_SIZE[(AVR32_FLASHC.pr & AVR32_FLASHC_PR_FSZ_MASK) >> AVR32_FLASHC_PR_FSZ_OFFSET];
  83. #else
  84. static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_FSR_FSZ_SIZE] =
  85. {
  86. 32 << 10,
  87. 64 << 10,
  88. 128 << 10,
  89. 256 << 10,
  90. 384 << 10,
  91. 512 << 10,
  92. 768 << 10,
  93. 1024 << 10
  94. };
  95. return FLASH_SIZE[(AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FSZ_MASK) >> AVR32_FLASHC_FSR_FSZ_OFFSET];
  96. #endif
  97. }
  98. unsigned int flashc_get_page_count(void)
  99. {
  100. return flashc_get_flash_size() / AVR32_FLASHC_PAGE_SIZE;
  101. }
  102. unsigned int flashc_get_page_count_per_region(void)
  103. {
  104. return flashc_get_page_count() / AVR32_FLASHC_REGIONS;
  105. }
  106. unsigned int flashc_get_page_region(int page_number)
  107. {
  108. return ((page_number >= 0) ? page_number : flashc_get_page_number()) / flashc_get_page_count_per_region();
  109. }
  110. unsigned int flashc_get_region_first_page_number(unsigned int region)
  111. {
  112. return region * flashc_get_page_count_per_region();
  113. }
  114. //! @}
  115. /*! \name FLASHC Control
  116. */
  117. //! @{
  118. unsigned int flashc_get_wait_state(void)
  119. {
  120. return (AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FWS_MASK) >> AVR32_FLASHC_FCR_FWS_OFFSET;
  121. }
  122. void flashc_set_wait_state(unsigned int wait_state)
  123. {
  124. u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  125. u_avr32_flashc_fcr.FCR.fws = wait_state;
  126. AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
  127. }
  128. Bool flashc_is_ready_int_enabled(void)
  129. {
  130. return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FRDY_MASK) != 0);
  131. }
  132. void flashc_enable_ready_int(Bool enable)
  133. {
  134. u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  135. u_avr32_flashc_fcr.FCR.frdy = (enable != FALSE);
  136. AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
  137. }
  138. Bool flashc_is_lock_error_int_enabled(void)
  139. {
  140. return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_LOCKE_MASK) != 0);
  141. }
  142. void flashc_enable_lock_error_int(Bool enable)
  143. {
  144. u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  145. u_avr32_flashc_fcr.FCR.locke = (enable != FALSE);
  146. AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
  147. }
  148. Bool flashc_is_prog_error_int_enabled(void)
  149. {
  150. return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_PROGE_MASK) != 0);
  151. }
  152. void flashc_enable_prog_error_int(Bool enable)
  153. {
  154. u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  155. u_avr32_flashc_fcr.FCR.proge = (enable != FALSE);
  156. AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
  157. }
  158. //! @}
  159. /*! \name FLASHC Status
  160. */
  161. //! @{
  162. Bool flashc_is_ready(void)
  163. {
  164. return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK) != 0);
  165. }
  166. void flashc_default_wait_until_ready(void)
  167. {
  168. while (!flashc_is_ready());
  169. }
  170. void (*volatile flashc_wait_until_ready)(void) = flashc_default_wait_until_ready;
  171. /*! \brief Gets the error status of the FLASHC.
  172. *
  173. * \return The error status of the FLASHC built up from
  174. * \c AVR32_FLASHC_FSR_LOCKE_MASK and \c AVR32_FLASHC_FSR_PROGE_MASK.
  175. *
  176. * \warning This hardware error status is cleared by all functions reading the
  177. * Flash Status Register (FSR). This function is therefore not part of
  178. * the driver's API which instead presents \ref flashc_is_lock_error
  179. * and \ref flashc_is_programming_error.
  180. */
  181. static unsigned int flashc_get_error_status(void)
  182. {
  183. return AVR32_FLASHC.fsr & (AVR32_FLASHC_FSR_LOCKE_MASK |
  184. AVR32_FLASHC_FSR_PROGE_MASK);
  185. }
  186. //! Sticky error status of the FLASHC.
  187. //! This variable is updated by functions that issue FLASHC commands. It
  188. //! contains the cumulated FLASHC error status of all the FLASHC commands issued
  189. //! by a function.
  190. static unsigned int flashc_error_status = 0;
  191. Bool flashc_is_lock_error(void)
  192. {
  193. return ((flashc_error_status & AVR32_FLASHC_FSR_LOCKE_MASK) != 0);
  194. }
  195. Bool flashc_is_programming_error(void)
  196. {
  197. return ((flashc_error_status & AVR32_FLASHC_FSR_PROGE_MASK) != 0);
  198. }
  199. //! @}
  200. /*! \name FLASHC Command Control
  201. */
  202. //! @{
  203. unsigned int flashc_get_command(void)
  204. {
  205. return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_CMD_MASK) >> AVR32_FLASHC_FCMD_CMD_OFFSET;
  206. }
  207. unsigned int flashc_get_page_number(void)
  208. {
  209. return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_PAGEN_MASK) >> AVR32_FLASHC_FCMD_PAGEN_OFFSET;
  210. }
  211. void flashc_issue_command(unsigned int command, int page_number)
  212. {
  213. u_avr32_flashc_fcmd_t u_avr32_flashc_fcmd;
  214. flashc_wait_until_ready();
  215. u_avr32_flashc_fcmd.fcmd = AVR32_FLASHC.fcmd;
  216. u_avr32_flashc_fcmd.FCMD.cmd = command;
  217. if (page_number >= 0) u_avr32_flashc_fcmd.FCMD.pagen = page_number;
  218. u_avr32_flashc_fcmd.FCMD.key = AVR32_FLASHC_FCMD_KEY_KEY;
  219. AVR32_FLASHC.fcmd = u_avr32_flashc_fcmd.fcmd;
  220. flashc_error_status = flashc_get_error_status();
  221. flashc_wait_until_ready();
  222. }
  223. //! @}
  224. /*! \name FLASHC Global Commands
  225. */
  226. //! @{
  227. void flashc_no_operation(void)
  228. {
  229. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_NOP, -1);
  230. }
  231. void flashc_erase_all(void)
  232. {
  233. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EA, -1);
  234. }
  235. //! @}
  236. /*! \name FLASHC Protection Mechanisms
  237. */
  238. //! @{
  239. Bool flashc_is_security_bit_active(void)
  240. {
  241. return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_SECURITY_MASK) != 0);
  242. }
  243. void flashc_activate_security_bit(void)
  244. {
  245. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_SSB, -1);
  246. }
  247. unsigned int flashc_get_bootloader_protected_size(void)
  248. {
  249. unsigned int bootprot = (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 -
  250. flashc_read_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET,
  251. AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE);
  252. return (bootprot) ? AVR32_FLASHC_PAGE_SIZE << bootprot : 0;
  253. }
  254. unsigned int flashc_set_bootloader_protected_size(unsigned int bootprot_size)
  255. {
  256. flashc_set_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET,
  257. AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE,
  258. (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 -
  259. ((bootprot_size) ?
  260. 32 - clz((((min(max(bootprot_size, AVR32_FLASHC_PAGE_SIZE << 1),
  261. AVR32_FLASHC_PAGE_SIZE <<
  262. ((1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1)) +
  263. AVR32_FLASHC_PAGE_SIZE - 1) /
  264. AVR32_FLASHC_PAGE_SIZE) << 1) - 1) - 1 :
  265. 0));
  266. return flashc_get_bootloader_protected_size();
  267. }
  268. Bool flashc_is_external_privileged_fetch_locked(void)
  269. {
  270. return (!flashc_read_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_EPFL_OFFSET));
  271. }
  272. void flashc_lock_external_privileged_fetch(Bool lock)
  273. {
  274. flashc_set_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_EPFL_OFFSET, !lock);
  275. }
  276. Bool flashc_is_page_region_locked(int page_number)
  277. {
  278. return flashc_is_region_locked(flashc_get_page_region(page_number));
  279. }
  280. Bool flashc_is_region_locked(unsigned int region)
  281. {
  282. return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_LOCK0_MASK << (region & (AVR32_FLASHC_REGIONS - 1))) != 0);
  283. }
  284. void flashc_lock_page_region(int page_number, Bool lock)
  285. {
  286. flashc_issue_command((lock) ? AVR32_FLASHC_FCMD_CMD_LP : AVR32_FLASHC_FCMD_CMD_UP, page_number);
  287. }
  288. void flashc_lock_region(unsigned int region, Bool lock)
  289. {
  290. flashc_lock_page_region(flashc_get_region_first_page_number(region), lock);
  291. }
  292. void flashc_lock_all_regions(Bool lock)
  293. {
  294. unsigned int error_status = 0;
  295. unsigned int region = AVR32_FLASHC_REGIONS;
  296. while (region)
  297. {
  298. flashc_lock_region(--region, lock);
  299. error_status |= flashc_error_status;
  300. }
  301. flashc_error_status = error_status;
  302. }
  303. //! @}
  304. /*! \name Access to General-Purpose Fuses
  305. */
  306. //! @{
  307. Bool flashc_read_gp_fuse_bit(unsigned int gp_fuse_bit)
  308. {
  309. return ((flashc_read_all_gp_fuses() & 1ULL << (gp_fuse_bit & 0x3F)) != 0);
  310. }
  311. U64 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width)
  312. {
  313. return flashc_read_all_gp_fuses() >> (pos & 0x3F) & ((1ULL << min(width, 64)) - 1);
  314. }
  315. U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte)
  316. {
  317. return flashc_read_all_gp_fuses() >> ((gp_fuse_byte & 0x07) << 3);
  318. }
  319. U64 flashc_read_all_gp_fuses(void)
  320. {
  321. return AVR32_FLASHC.fgpfrlo | (U64)AVR32_FLASHC.fgpfrhi << 32;
  322. }
  323. Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check)
  324. {
  325. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EGPB, gp_fuse_bit & 0x3F);
  326. return (check) ? flashc_read_gp_fuse_bit(gp_fuse_bit) : TRUE;
  327. }
  328. Bool flashc_erase_gp_fuse_bitfield(unsigned int pos, unsigned int width, Bool check)
  329. {
  330. unsigned int error_status = 0;
  331. unsigned int gp_fuse_bit;
  332. pos &= 0x3F;
  333. width = min(width, 64);
  334. for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++)
  335. {
  336. flashc_erase_gp_fuse_bit(gp_fuse_bit, FALSE);
  337. error_status |= flashc_error_status;
  338. }
  339. flashc_error_status = error_status;
  340. return (check) ? (flashc_read_gp_fuse_bitfield(pos, width) == (1ULL << width) - 1) : TRUE;
  341. }
  342. Bool flashc_erase_gp_fuse_byte(unsigned int gp_fuse_byte, Bool check)
  343. {
  344. unsigned int error_status;
  345. unsigned int current_gp_fuse_byte;
  346. U64 value = flashc_read_all_gp_fuses();
  347. flashc_erase_all_gp_fuses(FALSE);
  348. error_status = flashc_error_status;
  349. for (current_gp_fuse_byte = 0; current_gp_fuse_byte < 8; current_gp_fuse_byte++, value >>= 8)
  350. {
  351. if (current_gp_fuse_byte != gp_fuse_byte)
  352. {
  353. flashc_write_gp_fuse_byte(current_gp_fuse_byte, value);
  354. error_status |= flashc_error_status;
  355. }
  356. }
  357. flashc_error_status = error_status;
  358. return (check) ? (flashc_read_gp_fuse_byte(gp_fuse_byte) == 0xFF) : TRUE;
  359. }
  360. Bool flashc_erase_all_gp_fuses(Bool check)
  361. {
  362. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EAGPF, -1);
  363. return (check) ? (flashc_read_all_gp_fuses() == 0xFFFFFFFFFFFFFFFFULL) : TRUE;
  364. }
  365. void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value)
  366. {
  367. if (!value)
  368. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WGPB, gp_fuse_bit & 0x3F);
  369. }
  370. void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value)
  371. {
  372. unsigned int error_status = 0;
  373. unsigned int gp_fuse_bit;
  374. pos &= 0x3F;
  375. width = min(width, 64);
  376. for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1)
  377. {
  378. flashc_write_gp_fuse_bit(gp_fuse_bit, value & 0x01);
  379. error_status |= flashc_error_status;
  380. }
  381. flashc_error_status = error_status;
  382. }
  383. void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value)
  384. {
  385. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_PGPFB, (gp_fuse_byte & 0x07) | value << 3);
  386. }
  387. void flashc_write_all_gp_fuses(U64 value)
  388. {
  389. unsigned int error_status = 0;
  390. unsigned int gp_fuse_byte;
  391. for (gp_fuse_byte = 0; gp_fuse_byte < 8; gp_fuse_byte++, value >>= 8)
  392. {
  393. flashc_write_gp_fuse_byte(gp_fuse_byte, value);
  394. error_status |= flashc_error_status;
  395. }
  396. flashc_error_status = error_status;
  397. }
  398. void flashc_set_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value)
  399. {
  400. if (value)
  401. flashc_erase_gp_fuse_bit(gp_fuse_bit, FALSE);
  402. else
  403. flashc_write_gp_fuse_bit(gp_fuse_bit, FALSE);
  404. }
  405. void flashc_set_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value)
  406. {
  407. unsigned int error_status = 0;
  408. unsigned int gp_fuse_bit;
  409. pos &= 0x3F;
  410. width = min(width, 64);
  411. for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1)
  412. {
  413. flashc_set_gp_fuse_bit(gp_fuse_bit, value & 0x01);
  414. error_status |= flashc_error_status;
  415. }
  416. flashc_error_status = error_status;
  417. }
  418. void flashc_set_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value)
  419. {
  420. unsigned int error_status;
  421. switch (value)
  422. {
  423. case 0xFF:
  424. flashc_erase_gp_fuse_byte(gp_fuse_byte, FALSE);
  425. break;
  426. case 0x00:
  427. flashc_write_gp_fuse_byte(gp_fuse_byte, 0x00);
  428. break;
  429. default:
  430. flashc_erase_gp_fuse_byte(gp_fuse_byte, FALSE);
  431. error_status = flashc_error_status;
  432. flashc_write_gp_fuse_byte(gp_fuse_byte, value);
  433. flashc_error_status |= error_status;
  434. }
  435. }
  436. void flashc_set_all_gp_fuses(U64 value)
  437. {
  438. unsigned int error_status;
  439. switch (value)
  440. {
  441. case 0xFFFFFFFFFFFFFFFFULL:
  442. flashc_erase_all_gp_fuses(FALSE);
  443. break;
  444. case 0x0000000000000000ULL:
  445. flashc_write_all_gp_fuses(0x0000000000000000ULL);
  446. break;
  447. default:
  448. flashc_erase_all_gp_fuses(FALSE);
  449. error_status = flashc_error_status;
  450. flashc_write_all_gp_fuses(value);
  451. flashc_error_status |= error_status;
  452. }
  453. }
  454. //! @}
  455. /*! \name Access to Flash Pages
  456. */
  457. //! @{
  458. void flashc_clear_page_buffer(void)
  459. {
  460. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_CPB, -1);
  461. }
  462. Bool flashc_is_page_erased(void)
  463. {
  464. return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_QPRR_MASK) != 0);
  465. }
  466. Bool flashc_quick_page_read(int page_number)
  467. {
  468. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPR, page_number);
  469. return flashc_is_page_erased();
  470. }
  471. Bool flashc_erase_page(int page_number, Bool check)
  472. {
  473. Bool page_erased = TRUE;
  474. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EP, page_number);
  475. if (check)
  476. {
  477. unsigned int error_status = flashc_error_status;
  478. page_erased = flashc_quick_page_read(-1);
  479. flashc_error_status |= error_status;
  480. }
  481. return page_erased;
  482. }
  483. Bool flashc_erase_all_pages(Bool check)
  484. {
  485. Bool all_pages_erased = TRUE;
  486. unsigned int error_status = 0;
  487. unsigned int page_number = flashc_get_page_count();
  488. while (page_number)
  489. {
  490. all_pages_erased &= flashc_erase_page(--page_number, check);
  491. error_status |= flashc_error_status;
  492. }
  493. flashc_error_status = error_status;
  494. return all_pages_erased;
  495. }
  496. void flashc_write_page(int page_number)
  497. {
  498. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WP, page_number);
  499. }
  500. Bool flashc_quick_user_page_read(void)
  501. {
  502. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPRUP, -1);
  503. return flashc_is_page_erased();
  504. }
  505. Bool flashc_erase_user_page(Bool check)
  506. {
  507. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EUP, -1);
  508. return (check) ? flashc_quick_user_page_read() : TRUE;
  509. }
  510. void flashc_write_user_page(void)
  511. {
  512. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WUP, -1);
  513. }
  514. volatile void *flashc_memset8(volatile void *dst, U8 src, size_t nbytes, Bool erase)
  515. {
  516. return flashc_memset16(dst, src | (U16)src << 8, nbytes, erase);
  517. }
  518. volatile void *flashc_memset16(volatile void *dst, U16 src, size_t nbytes, Bool erase)
  519. {
  520. return flashc_memset32(dst, src | (U32)src << 16, nbytes, erase);
  521. }
  522. volatile void *flashc_memset32(volatile void *dst, U32 src, size_t nbytes, Bool erase)
  523. {
  524. return flashc_memset64(dst, src | (U64)src << 32, nbytes, erase);
  525. }
  526. volatile void *flashc_memset64(volatile void *dst, U64 src, size_t nbytes, Bool erase)
  527. {
  528. // Use aggregated pointers to have several alignments available for a same address.
  529. UnionCVPtr flash_array_end;
  530. UnionVPtr dest;
  531. Union64 source = {0};
  532. StructCVPtr dest_end;
  533. UnionCVPtr flash_page_source_end;
  534. Bool incomplete_flash_page_end;
  535. Union64 flash_dword;
  536. UnionVPtr tmp;
  537. unsigned int error_status = 0;
  538. unsigned int i;
  539. // Reformat arguments.
  540. flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size();
  541. dest.u8ptr = dst;
  542. for (i = (Get_align((U32)dest.u8ptr, sizeof(U64)) - 1) & (sizeof(U64) - 1);
  543. src; i = (i - 1) & (sizeof(U64) - 1))
  544. {
  545. source.u8[i] = src;
  546. src >>= 8;
  547. }
  548. dest_end.u8ptr = dest.u8ptr + nbytes;
  549. // If destination is outside flash, go to next flash page if any.
  550. if (dest.u8ptr < AVR32_FLASH)
  551. {
  552. dest.u8ptr = AVR32_FLASH;
  553. }
  554. else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE)
  555. {
  556. dest.u8ptr = AVR32_FLASHC_USER_PAGE;
  557. }
  558. // If end of destination is outside flash, move it to the end of the previous flash page if any.
  559. if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE)
  560. {
  561. dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE;
  562. }
  563. else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr)
  564. {
  565. dest_end.u8ptr = flash_array_end.u8ptr;
  566. }
  567. // Align each end of destination pointer with its natural boundary.
  568. dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16));
  569. dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32));
  570. dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64));
  571. // While end of destination is not reached...
  572. while (dest.u8ptr < dest_end.u8ptr)
  573. {
  574. // Clear the page buffer in order to prepare data for a flash page write.
  575. flashc_clear_page_buffer();
  576. error_status |= flashc_error_status;
  577. // Determine where the source data will end in the current flash page.
  578. flash_page_source_end.u64ptr =
  579. (U64 *)min((U32)dest_end.u64ptr,
  580. Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE);
  581. // Determine if the current destination page has an incomplete end.
  582. incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >=
  583. Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE));
  584. // Use a flash double-word buffer to manage unaligned accesses.
  585. flash_dword.u64 = source.u64;
  586. // If destination does not point to the beginning of the current flash page...
  587. if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE))
  588. {
  589. // Fill the beginning of the page buffer with the current flash page data.
  590. // This is required by the hardware, even if page erase is not requested,
  591. // in order to be able to write successfully to erased parts of flash
  592. // pages that have already been written to.
  593. for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE);
  594. tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
  595. tmp.u64ptr++)
  596. *tmp.u64ptr = *tmp.u64ptr;
  597. // If destination is not 64-bit aligned...
  598. if (!Test_align((U32)dest.u8ptr, sizeof(U64)))
  599. {
  600. // Fill the beginning of the flash double-word buffer with the current
  601. // flash page data.
  602. // This is required by the hardware, even if page erase is not
  603. // requested, in order to be able to write successfully to erased parts
  604. // of flash pages that have already been written to.
  605. for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++)
  606. flash_dword.u8[i] = *tmp.u8ptr++;
  607. // Align the destination pointer with its 64-bit boundary.
  608. dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
  609. // If the current destination double-word is not the last one...
  610. if (dest.u64ptr < dest_end.u64ptr)
  611. {
  612. // Write the flash double-word buffer to the page buffer and reinitialize it.
  613. *dest.u64ptr++ = flash_dword.u64;
  614. flash_dword.u64 = source.u64;
  615. }
  616. }
  617. }
  618. // Write the source data to the page buffer with 64-bit alignment.
  619. for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
  620. *dest.u64ptr++ = source.u64;
  621. // If the current destination page has an incomplete end...
  622. if (incomplete_flash_page_end)
  623. {
  624. // This is required by the hardware, even if page erase is not requested,
  625. // in order to be able to write successfully to erased parts of flash
  626. // pages that have already been written to.
  627. {
  628. tmp.u8ptr = (volatile U8 *)dest_end.u8ptr;
  629. // If end of destination is not 64-bit aligned...
  630. if (!Test_align((U32)dest_end.u8ptr, sizeof(U64)))
  631. {
  632. // Fill the end of the flash double-word buffer with the current flash page data.
  633. for (i = Get_align((U32)dest_end.u8ptr, sizeof(U64)); i < sizeof(U64); i++)
  634. flash_dword.u8[i] = *tmp.u8ptr++;
  635. // Write the flash double-word buffer to the page buffer.
  636. *dest.u64ptr++ = flash_dword.u64;
  637. }
  638. // Fill the end of the page buffer with the current flash page data.
  639. for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++)
  640. *tmp.u64ptr = *tmp.u64ptr;
  641. }
  642. }
  643. // If the current flash page is in the flash array...
  644. if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE)
  645. {
  646. // Erase the current page if requested and write it from the page buffer.
  647. if (erase)
  648. {
  649. flashc_erase_page(-1, FALSE);
  650. error_status |= flashc_error_status;
  651. }
  652. flashc_write_page(-1);
  653. error_status |= flashc_error_status;
  654. // If the end of the flash array is reached, go to the User page.
  655. if (dest.u8ptr >= flash_array_end.u8ptr)
  656. dest.u8ptr = AVR32_FLASHC_USER_PAGE;
  657. }
  658. // If the current flash page is the User page...
  659. else
  660. {
  661. // Erase the User page if requested and write it from the page buffer.
  662. if (erase)
  663. {
  664. flashc_erase_user_page(FALSE);
  665. error_status |= flashc_error_status;
  666. }
  667. flashc_write_user_page();
  668. error_status |= flashc_error_status;
  669. }
  670. }
  671. // Update the FLASHC error status.
  672. flashc_error_status = error_status;
  673. // Return the initial destination pointer as the standard memset function does.
  674. return dst;
  675. }
  676. volatile void *flashc_memcpy(volatile void *dst, const void *src, size_t nbytes, Bool erase)
  677. {
  678. // Use aggregated pointers to have several alignments available for a same address.
  679. UnionCVPtr flash_array_end;
  680. UnionVPtr dest;
  681. UnionCPtr source;
  682. StructCVPtr dest_end;
  683. UnionCVPtr flash_page_source_end;
  684. Bool incomplete_flash_page_end;
  685. Union64 flash_dword;
  686. Bool flash_dword_pending = FALSE;
  687. UnionVPtr tmp;
  688. unsigned int error_status = 0;
  689. unsigned int i, j;
  690. // Reformat arguments.
  691. flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size();
  692. dest.u8ptr = dst;
  693. source.u8ptr = src;
  694. dest_end.u8ptr = dest.u8ptr + nbytes;
  695. // If destination is outside flash, go to next flash page if any.
  696. if (dest.u8ptr < AVR32_FLASH)
  697. {
  698. source.u8ptr += AVR32_FLASH - dest.u8ptr;
  699. dest.u8ptr = AVR32_FLASH;
  700. }
  701. else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE)
  702. {
  703. source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr;
  704. dest.u8ptr = AVR32_FLASHC_USER_PAGE;
  705. }
  706. // If end of destination is outside flash, move it to the end of the previous flash page if any.
  707. if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE)
  708. {
  709. dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE;
  710. }
  711. else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr)
  712. {
  713. dest_end.u8ptr = flash_array_end.u8ptr;
  714. }
  715. // Align each end of destination pointer with its natural boundary.
  716. dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16));
  717. dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32));
  718. dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64));
  719. // While end of destination is not reached...
  720. while (dest.u8ptr < dest_end.u8ptr)
  721. {
  722. // Clear the page buffer in order to prepare data for a flash page write.
  723. flashc_clear_page_buffer();
  724. error_status |= flashc_error_status;
  725. // Determine where the source data will end in the current flash page.
  726. flash_page_source_end.u64ptr =
  727. (U64 *)min((U32)dest_end.u64ptr,
  728. Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE);
  729. // Determine if the current destination page has an incomplete end.
  730. incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >=
  731. Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE));
  732. // If destination does not point to the beginning of the current flash page...
  733. if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE))
  734. {
  735. // Fill the beginning of the page buffer with the current flash page data.
  736. // This is required by the hardware, even if page erase is not requested,
  737. // in order to be able to write successfully to erased parts of flash
  738. // pages that have already been written to.
  739. for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE);
  740. tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
  741. tmp.u64ptr++)
  742. *tmp.u64ptr = *tmp.u64ptr;
  743. // If destination is not 64-bit aligned...
  744. if (!Test_align((U32)dest.u8ptr, sizeof(U64)))
  745. {
  746. // Fill the beginning of the flash double-word buffer with the current
  747. // flash page data.
  748. // This is required by the hardware, even if page erase is not
  749. // requested, in order to be able to write successfully to erased parts
  750. // of flash pages that have already been written to.
  751. for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++)
  752. flash_dword.u8[i] = *tmp.u8ptr++;
  753. // Fill the end of the flash double-word buffer with the source data.
  754. for (; i < sizeof(U64); i++)
  755. flash_dword.u8[i] = *source.u8ptr++;
  756. // Align the destination pointer with its 64-bit boundary.
  757. dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
  758. // If the current destination double-word is not the last one...
  759. if (dest.u64ptr < dest_end.u64ptr)
  760. {
  761. // Write the flash double-word buffer to the page buffer.
  762. *dest.u64ptr++ = flash_dword.u64;
  763. }
  764. // If the current destination double-word is the last one, the flash
  765. // double-word buffer must be kept for later.
  766. else flash_dword_pending = TRUE;
  767. }
  768. }
  769. // Read the source data with the maximal possible alignment and write it to
  770. // the page buffer with 64-bit alignment.
  771. switch (Get_align((U32)source.u8ptr, sizeof(U32)))
  772. {
  773. case 0:
  774. for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
  775. *dest.u64ptr++ = *source.u64ptr++;
  776. break;
  777. case sizeof(U16):
  778. for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
  779. {
  780. for (j = 0; j < sizeof(U64) / sizeof(U16); j++) flash_dword.u16[j] = *source.u16ptr++;
  781. *dest.u64ptr++ = flash_dword.u64;
  782. }
  783. break;
  784. default:
  785. for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
  786. {
  787. for (j = 0; j < sizeof(U64); j++) flash_dword.u8[j] = *source.u8ptr++;
  788. *dest.u64ptr++ = flash_dword.u64;
  789. }
  790. }
  791. // If the current destination page has an incomplete end...
  792. if (incomplete_flash_page_end)
  793. {
  794. // If the flash double-word buffer is in use, do not initialize it.
  795. if (flash_dword_pending) i = Get_align((U32)dest_end.u8ptr, sizeof(U64));
  796. // If the flash double-word buffer is free...
  797. else
  798. {
  799. // Fill the beginning of the flash double-word buffer with the source data.
  800. for (i = 0; i < Get_align((U32)dest_end.u8ptr, sizeof(U64)); i++)
  801. flash_dword.u8[i] = *source.u8ptr++;
  802. }
  803. // This is required by the hardware, even if page erase is not requested,
  804. // in order to be able to write successfully to erased parts of flash
  805. // pages that have already been written to.
  806. {
  807. tmp.u8ptr = (volatile U8 *)dest_end.u8ptr;
  808. // If end of destination is not 64-bit aligned...
  809. if (!Test_align((U32)dest_end.u8ptr, sizeof(U64)))
  810. {
  811. // Fill the end of the flash double-word buffer with the current flash page data.
  812. for (; i < sizeof(U64); i++)
  813. flash_dword.u8[i] = *tmp.u8ptr++;
  814. // Write the flash double-word buffer to the page buffer.
  815. *dest.u64ptr++ = flash_dword.u64;
  816. }
  817. // Fill the end of the page buffer with the current flash page data.
  818. for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++)
  819. *tmp.u64ptr = *tmp.u64ptr;
  820. }
  821. }
  822. // If the current flash page is in the flash array...
  823. if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE)
  824. {
  825. // Erase the current page if requested and write it from the page buffer.
  826. if (erase)
  827. {
  828. flashc_erase_page(-1, FALSE);
  829. error_status |= flashc_error_status;
  830. }
  831. flashc_write_page(-1);
  832. error_status |= flashc_error_status;
  833. // If the end of the flash array is reached, go to the User page.
  834. if (dest.u8ptr >= flash_array_end.u8ptr)
  835. {
  836. source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr;
  837. dest.u8ptr = AVR32_FLASHC_USER_PAGE;
  838. }
  839. }
  840. // If the current flash page is the User page...
  841. else
  842. {
  843. // Erase the User page if requested and write it from the page buffer.
  844. if (erase)
  845. {
  846. flashc_erase_user_page(FALSE);
  847. error_status |= flashc_error_status;
  848. }
  849. flashc_write_user_page();
  850. error_status |= flashc_error_status;
  851. }
  852. }
  853. // Update the FLASHC error status.
  854. flashc_error_status = error_status;
  855. // Return the initial destination pointer as the standard memcpy function does.
  856. return dst;
  857. }
  858. #if UC3C
  859. void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz)
  860. {
  861. //! Device-specific data
  862. #undef AVR32_FLASHC_FWS_0_MAX_FREQ
  863. #undef AVR32_FLASHC_FWS_1_MAX_FREQ
  864. #undef AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ
  865. #undef AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ
  866. #define AVR32_FLASHC_FWS_0_MAX_FREQ 33000000
  867. #define AVR32_FLASHC_FWS_1_MAX_FREQ 66000000
  868. #define AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ 33000000
  869. #define AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ 72000000
  870. // These defines are missing from or wrong in the toolchain header files uc3cxxx.h
  871. // Put a Bugzilla
  872. if(cpu_f_hz > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ) // > 33MHz
  873. {
  874. // Set a wait-state
  875. flashc_set_wait_state(1);
  876. if(cpu_f_hz <= AVR32_FLASHC_FWS_1_MAX_FREQ) // <= 66MHz and >33Mhz
  877. {
  878. // Disable the high-speed read mode.
  879. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
  880. }
  881. else // > 66Mhz
  882. {
  883. // Enable the high-speed read mode.
  884. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);
  885. }
  886. }
  887. else // <= 33 MHz
  888. {
  889. // Disable wait-state
  890. flashc_set_wait_state(0);
  891. // Disable the high-speed read mode.
  892. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
  893. }
  894. }
  895. #endif // UC3C device-specific implementation
  896. //! @}