flash.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. //*****************************************************************************
  2. //
  3. // flash.c - Driver for programming the on-chip flash.
  4. //
  5. // Copyright (c) 2005-2017 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above copyright
  16. // notice, this list of conditions and the following disclaimer in the
  17. // documentation and/or other materials provided with the
  18. // distribution.
  19. //
  20. // Neither the name of Texas Instruments Incorporated nor the names of
  21. // its contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. //*****************************************************************************
  37. //*****************************************************************************
  38. //
  39. //! \addtogroup flash_api
  40. //! @{
  41. //
  42. //*****************************************************************************
  43. #include "types.h"
  44. #include <stdbool.h>
  45. #include <stdint.h>
  46. #include "inc/hw_flash.h"
  47. #include "inc/hw_sysctl.h"
  48. #include "debug.h"
  49. #include "flash.h"
  50. #include "interrupt.h"
  51. //*****************************************************************************
  52. //
  53. // An array that maps the specified memory bank to the appropriate Flash
  54. // Memory Protection Program Enable (FMPPE) register.
  55. //
  56. //*****************************************************************************
  57. static const uint32_t g_pui32FMPPERegs[] =
  58. {
  59. FLASH_FMPPE0,
  60. FLASH_FMPPE1,
  61. FLASH_FMPPE2,
  62. FLASH_FMPPE3,
  63. FLASH_FMPPE4,
  64. FLASH_FMPPE5,
  65. FLASH_FMPPE6,
  66. FLASH_FMPPE7,
  67. FLASH_FMPPE8,
  68. FLASH_FMPPE9,
  69. FLASH_FMPPE10,
  70. FLASH_FMPPE11,
  71. FLASH_FMPPE12,
  72. FLASH_FMPPE13,
  73. FLASH_FMPPE14,
  74. FLASH_FMPPE15,
  75. };
  76. //*****************************************************************************
  77. //
  78. // An array that maps the specified memory bank to the appropriate Flash
  79. // Memory Protection Read Enable (FMPRE) register.
  80. //
  81. //*****************************************************************************
  82. static const uint32_t g_pui32FMPRERegs[] =
  83. {
  84. FLASH_FMPRE0,
  85. FLASH_FMPRE1,
  86. FLASH_FMPRE2,
  87. FLASH_FMPRE3,
  88. FLASH_FMPRE4,
  89. FLASH_FMPRE5,
  90. FLASH_FMPRE6,
  91. FLASH_FMPRE7,
  92. FLASH_FMPRE8,
  93. FLASH_FMPRE9,
  94. FLASH_FMPRE10,
  95. FLASH_FMPRE11,
  96. FLASH_FMPRE12,
  97. FLASH_FMPRE13,
  98. FLASH_FMPRE14,
  99. FLASH_FMPRE15,
  100. };
  101. //*****************************************************************************
  102. //
  103. //! Erases a block of flash.
  104. //!
  105. //! \param ui32Address is the start address of the flash block to be erased.
  106. //!
  107. //! This function erases a block of the on-chip flash. After erasing, the
  108. //! block is filled with 0xFF bytes. Read-only and execute-only blocks cannot
  109. //! be erased.
  110. //!
  111. //! The flash block size is 16-KB.
  112. //!
  113. //! This function does not return until the block has been erased.
  114. //!
  115. //! \return Returns 0 on success, or -1 if an invalid block address was
  116. //! specified or the block is write-protected.
  117. //
  118. //*****************************************************************************
  119. int32_t
  120. FlashErase(uint32_t ui32Address)
  121. {
  122. //
  123. // Check the arguments.
  124. //
  125. ASSERT(!(ui32Address & (FLASH_ERASE_SIZE - 1)));
  126. //
  127. // Clear the flash access and error interrupts.
  128. //
  129. HWREG(FLASH_FCMISC) = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
  130. FLASH_FCMISC_ERMISC);
  131. //
  132. // Erase the block.
  133. //
  134. HWREG(FLASH_FMA) = ui32Address;
  135. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
  136. //
  137. // Wait until the block has been erased.
  138. //
  139. while (HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
  140. {
  141. }
  142. //
  143. // Return an error if an access violation or erase error occurred.
  144. //
  145. if (HWREG(FLASH_FCRIS) & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
  146. FLASH_FCRIS_ERRIS))
  147. {
  148. return (-1);
  149. }
  150. //
  151. // Success.
  152. //
  153. return (0);
  154. }
  155. //*****************************************************************************
  156. //
  157. //! Programs flash.
  158. //!
  159. //! \param pui32Data is a pointer to the data to be programmed.
  160. //! \param ui32Address is the starting address in flash to be programmed. Must
  161. //! be a multiple of four.
  162. //! \param ui32Count is the number of bytes to be programmed. Must be a
  163. //! multiple of four.
  164. //!
  165. //! This function programs a sequence of words into the on-chip flash.
  166. //! Because the flash is programmed one word at a time, the starting address
  167. //! and byte count must both be multiples of four. It is up to the caller to
  168. //! verify the programmed contents, if such verification is required.
  169. //!
  170. //! This function does not return until the data has been programmed.
  171. //!
  172. //! \return Returns 0 on success, or -1 if a programming error is encountered.
  173. //
  174. //*****************************************************************************
  175. int32_t
  176. FlashProgram(uint32_t *pui32Data, uint32_t ui32Address, uint32_t ui32Count)
  177. {
  178. //
  179. // Check the arguments.
  180. //
  181. ASSERT(!(ui32Address & 3));
  182. ASSERT(!(ui32Count & 3));
  183. //
  184. // Clear the flash access and error interrupts.
  185. //
  186. HWREG(FLASH_FCMISC) = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
  187. FLASH_FCMISC_INVDMISC | FLASH_FCMISC_PROGMISC);
  188. //
  189. // Loop over the words to be programmed.
  190. //
  191. while (ui32Count)
  192. {
  193. //
  194. // Set the address of this block of words.
  195. //
  196. HWREG(FLASH_FMA) = ui32Address & ~(0x7f);
  197. //
  198. // Loop over the words in this 32-word block.
  199. //
  200. while (((ui32Address & 0x7c) || (HWREG(FLASH_FWBVAL) == 0)) &&
  201. (ui32Count != 0))
  202. {
  203. //
  204. // Write this word into the write buffer.
  205. //
  206. HWREG(FLASH_FWBN + (ui32Address & 0x7c)) = *pui32Data++;
  207. ui32Address += 4;
  208. ui32Count -= 4;
  209. }
  210. //
  211. // Program the contents of the write buffer into flash.
  212. //
  213. HWREG(FLASH_FMC2) = FLASH_FMC2_WRKEY | FLASH_FMC2_WRBUF;
  214. //
  215. // Wait until the write buffer has been programmed.
  216. //
  217. while (HWREG(FLASH_FMC2) & FLASH_FMC2_WRBUF)
  218. {
  219. }
  220. }
  221. //
  222. // Return an error if an access violation occurred.
  223. //
  224. if (HWREG(FLASH_FCRIS) & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
  225. FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS))
  226. {
  227. return (-1);
  228. }
  229. //
  230. // Success.
  231. //
  232. return (0);
  233. }
  234. //*****************************************************************************
  235. //
  236. //! Gets the protection setting for a block of flash.
  237. //!
  238. //! \param ui32Address is the start address of the flash block to be queried.
  239. //!
  240. //! This function gets the current protection for the specified block of flash.
  241. //! A block can be read/write, read-only, or execute-only.
  242. //! Read/write blocks can be read, executed, erased, and programmed. Read-only
  243. //! blocks can be read and executed. Execute-only blocks can only be executed;
  244. //! processor and debugger data reads are not allowed.
  245. //!
  246. //! \return Returns the protection setting for this block. See
  247. //! FlashProtectSet() for possible values.
  248. //
  249. //*****************************************************************************
  250. tFlashProtection
  251. FlashProtectGet(uint32_t ui32Address)
  252. {
  253. uint32_t ui32FMPRE, ui32FMPPE;
  254. uint32_t ui32Bank;
  255. //
  256. // Check the argument.
  257. //
  258. ASSERT(!(ui32Address & (FLASH_PROTECT_SIZE - 1)));
  259. //
  260. // Calculate the Flash Bank from Base Address, and mask off the Bank
  261. // from ui32Address for subsequent reference.
  262. //
  263. ui32Bank = (((ui32Address / FLASH_PROTECT_SIZE) / 32) % 4);
  264. ui32Address &= ((FLASH_PROTECT_SIZE * 32) - 1);
  265. //
  266. // Read the appropriate flash protection registers for the specified
  267. // flash bank.
  268. //
  269. ui32FMPRE = HWREG(g_pui32FMPRERegs[ui32Bank]);
  270. ui32FMPPE = HWREG(g_pui32FMPPERegs[ui32Bank]);
  271. //
  272. // Check the appropriate protection bits for the block of memory that
  273. // is specified by the address.
  274. //
  275. switch ((((ui32FMPRE >> (ui32Address / FLASH_PROTECT_SIZE)) & 0x1) << 1) |
  276. ((ui32FMPPE >> (ui32Address / FLASH_PROTECT_SIZE)) & 0x1))
  277. {
  278. //
  279. // This block is marked as execute only (that is, it can not be erased
  280. // or programmed, and the only reads allowed are via the instruction
  281. // fetch interface).
  282. //
  283. case 0:
  284. case 1:
  285. {
  286. return (FlashExecuteOnly);
  287. }
  288. //
  289. // This block is marked as read only (that is, it can not be erased or
  290. // programmed).
  291. //
  292. case 2:
  293. {
  294. return (FlashReadOnly);
  295. }
  296. //
  297. // This block is read/write; it can be read, erased, and programmed.
  298. //
  299. case 3:
  300. default:
  301. {
  302. return (FlashReadWrite);
  303. }
  304. }
  305. }
  306. //*****************************************************************************
  307. //
  308. //! Sets the protection setting for a block of flash.
  309. //!
  310. //! \param ui32Address is the start address of the flash block to be protected.
  311. //! \param eProtect is the protection to be applied to the block. Can be one
  312. //! of \b FlashReadWrite, \b FlashReadOnly, or \b FlashExecuteOnly.
  313. //!
  314. //! This function sets the protection for the specified block of flash.
  315. //! Blocks that are read/write can be made read-only or execute-only.
  316. //! Blocks that are read-only can be made execute-only. Blocks that are
  317. //! execute-only cannot have their protection modified. Attempts to make the
  318. //! block protection less stringent (that is, read-only to read/write)
  319. //! result in a failure (and are prevented by the hardware).
  320. //!
  321. //! Changes to the flash protection are maintained only until the next reset.
  322. //! This protocol allows the application to be executed in the desired flash
  323. //! protection environment to check for inappropriate flash access (via the
  324. //! flash interrupt). To make the flash protection permanent, use the
  325. //! FlashProtectSave() function.
  326. //!
  327. //! \return Returns 0 on success, or -1 if an invalid address or an invalid
  328. //! protection was specified.
  329. //
  330. //*****************************************************************************
  331. int32_t
  332. FlashProtectSet(uint32_t ui32Address, tFlashProtection eProtect)
  333. {
  334. uint32_t ui32ProtectRE, ui32ProtectPE;
  335. uint32_t ui32Bank;
  336. //
  337. // Check the argument.
  338. //
  339. ASSERT(!(ui32Address & (FLASH_PROTECT_SIZE - 1)));
  340. ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
  341. (eProtect == FlashExecuteOnly));
  342. //
  343. // Convert the address into a block number.
  344. //
  345. ui32Address /= FLASH_PROTECT_SIZE;
  346. //
  347. // ui32Address contains a "raw" block number. Derive the Flash Bank from
  348. // the "raw" block number, and convert ui32Address to a "relative"
  349. // block number.
  350. //
  351. ui32Bank = ((ui32Address / 32) % 4);
  352. ui32Address %= 32;
  353. //
  354. // Get the current protection for the specified flash bank.
  355. //
  356. ui32ProtectRE = HWREG(g_pui32FMPRERegs[ui32Bank]);
  357. ui32ProtectPE = HWREG(g_pui32FMPPERegs[ui32Bank]);
  358. //
  359. // Set the protection based on the requested protection.
  360. //
  361. switch (eProtect)
  362. {
  363. //
  364. // Make this block execute only.
  365. //
  366. case FlashExecuteOnly:
  367. {
  368. //
  369. // Turn off the read and program bits for this block.
  370. //
  371. ui32ProtectRE &= ~(0x1 << ui32Address);
  372. ui32ProtectPE &= ~(0x1 << ui32Address);
  373. //
  374. // We're done handling this protection.
  375. //
  376. break;
  377. }
  378. //
  379. // Make this block read only.
  380. //
  381. case FlashReadOnly:
  382. {
  383. //
  384. // The block can not be made read only if it is execute only.
  385. //
  386. if (((ui32ProtectRE >> ui32Address) & 0x1) != 0x1)
  387. {
  388. return (-1);
  389. }
  390. //
  391. // Make this block read only.
  392. //
  393. ui32ProtectPE &= ~(0x1 << ui32Address);
  394. //
  395. // We're done handling this protection.
  396. //
  397. break;
  398. }
  399. //
  400. // Make this block read/write.
  401. //
  402. case FlashReadWrite:
  403. default:
  404. {
  405. //
  406. // The block can not be made read/write if it is not already
  407. // read/write.
  408. //
  409. if ((((ui32ProtectRE >> ui32Address) & 0x1) != 0x1) ||
  410. (((ui32ProtectPE >> ui32Address) & 0x1) != 0x1))
  411. {
  412. return (-1);
  413. }
  414. //
  415. // The block is already read/write, so there is nothing to do.
  416. //
  417. return (0);
  418. }
  419. }
  420. //
  421. // Set the new protection for the specified flash bank.
  422. //
  423. HWREG(g_pui32FMPRERegs[ui32Bank]) = ui32ProtectRE;
  424. HWREG(g_pui32FMPPERegs[ui32Bank]) = ui32ProtectPE;
  425. //
  426. // Success.
  427. //
  428. return (0);
  429. }
  430. //*****************************************************************************
  431. //
  432. //! Saves the flash protection settings.
  433. //!
  434. //! This function makes the currently programmed flash protection settings
  435. //! permanent. This operation is non-reversible; a chip reset or power cycle
  436. //! does not change the flash protection.
  437. //!
  438. //! This function does not return until the protection has been saved.
  439. //!
  440. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  441. //
  442. //*****************************************************************************
  443. int32_t
  444. FlashProtectSave(void)
  445. {
  446. uint32_t ui32Temp;
  447. //
  448. // Save the entire bank of 8 flash protection registers.
  449. //
  450. for (ui32Temp = 0; ui32Temp < 8; ui32Temp++)
  451. {
  452. //
  453. // Tell the flash controller to write the flash protection register.
  454. //
  455. HWREG(FLASH_FMA) = ui32Temp;
  456. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  457. //
  458. // Wait until the write has completed.
  459. //
  460. while (HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  461. {
  462. }
  463. }
  464. //
  465. // Success.
  466. //
  467. return (0);
  468. }
  469. //*****************************************************************************
  470. //
  471. //! Gets the user registers.
  472. //!
  473. //! \param pui32User0 is a pointer to the location to store USER Register 0.
  474. //! \param pui32User1 is a pointer to the location to store USER Register 1.
  475. //!
  476. //! This function reads the contents of user registers 0 and 1, and
  477. //! stores them in the specified locations.
  478. //!
  479. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  480. //
  481. //*****************************************************************************
  482. int32_t
  483. FlashUserGet(uint32_t *pui32User0, uint32_t *pui32User1)
  484. {
  485. //
  486. // Verify that the pointers are valid.
  487. //
  488. ASSERT(pui32User0 != 0);
  489. ASSERT(pui32User1 != 0);
  490. //
  491. // Get and store the current value of the user registers.
  492. //
  493. *pui32User0 = HWREG(FLASH_USERREG0);
  494. *pui32User1 = HWREG(FLASH_USERREG1);
  495. //
  496. // Success.
  497. //
  498. return (0);
  499. }
  500. //*****************************************************************************
  501. //
  502. //! Sets the user registers.
  503. //!
  504. //! \param ui32User0 is the value to store in USER Register 0.
  505. //! \param ui32User1 is the value to store in USER Register 1.
  506. //!
  507. //! This function sets the contents of the user registers 0 and 1 to
  508. //! the specified values.
  509. //!
  510. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  511. //
  512. //*****************************************************************************
  513. int32_t
  514. FlashUserSet(uint32_t ui32User0, uint32_t ui32User1)
  515. {
  516. //
  517. // Save the new values into the user registers.
  518. //
  519. HWREG(FLASH_USERREG0) = ui32User0;
  520. HWREG(FLASH_USERREG1) = ui32User1;
  521. //
  522. // Success.
  523. //
  524. return (0);
  525. }
  526. //*****************************************************************************
  527. //
  528. //! Gets all the user registers.
  529. //!
  530. //! \param pui32User0 is a pointer to the location to store USER Register 0.
  531. //! \param pui32User1 is a pointer to the location to store USER Register 1.
  532. //! \param pui32User2 is a pointer to the location to store USER Register 2.
  533. //! \param pui32User3 is a pointer to the location to store USER Register 3.
  534. //!
  535. //! This function reads the contents of user registers 0, 1, 2 and 3, and
  536. //! stores them in the specified locations.
  537. //!
  538. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  539. //
  540. //*****************************************************************************
  541. int32_t
  542. FlashAllUserRegisterGet(uint32_t *pui32User0, uint32_t *pui32User1,
  543. uint32_t *pui32User2, uint32_t *pui32User3)
  544. {
  545. //
  546. // Verify that the pointers are valid.
  547. //
  548. ASSERT(pui32User0 != 0);
  549. ASSERT(pui32User1 != 0);
  550. ASSERT(pui32User2 != 0);
  551. ASSERT(pui32User3 != 0);
  552. //
  553. // Get and store the current value of the user registers.
  554. //
  555. *pui32User0 = HWREG(FLASH_USERREG0);
  556. *pui32User1 = HWREG(FLASH_USERREG1);
  557. *pui32User2 = HWREG(FLASH_USERREG2);
  558. *pui32User3 = HWREG(FLASH_USERREG3);
  559. //
  560. // Success.
  561. //
  562. return (0);
  563. }
  564. //*****************************************************************************
  565. //
  566. //! Sets the user registers 0 to 3
  567. //!
  568. //! \param ui32User0 is the value to store in USER Register 0.
  569. //! \param ui32User1 is the value to store in USER Register 1.
  570. //! \param ui32User2 is the value to store in USER Register 2.
  571. //! \param ui32User3 is the value to store in USER Register 3.
  572. //!
  573. //! This function sets the contents of the user registers 0, 1, 2 and 3 to
  574. //! the specified values.
  575. //!
  576. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  577. //
  578. //*****************************************************************************
  579. int32_t
  580. FlashAllUserRegisterSet(uint32_t ui32User0, uint32_t ui32User1,
  581. uint32_t ui32User2, uint32_t ui32User3)
  582. {
  583. //
  584. // Save the new values into the user registers.
  585. //
  586. HWREG(FLASH_USERREG0) = ui32User0;
  587. HWREG(FLASH_USERREG1) = ui32User1;
  588. HWREG(FLASH_USERREG2) = ui32User2;
  589. HWREG(FLASH_USERREG3) = ui32User3;
  590. //
  591. // Success.
  592. //
  593. return (0);
  594. }
  595. //*****************************************************************************
  596. //
  597. //! Saves the user registers 0 and 1.
  598. //!
  599. //! This function makes the currently programmed user register 0 and 1 settings
  600. //! permanent. This operation is non-reversible; a chip reset or power cycle
  601. //! does not change the flash protection.
  602. //!
  603. //! This function does not return until the protection has been saved.
  604. //!
  605. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  606. //
  607. //*****************************************************************************
  608. int32_t
  609. FlashUserSave(void)
  610. {
  611. //
  612. // Setting the MSB of FMA will trigger a permanent save of a USER
  613. // register. Bit 0 will indicate User 0 (0) or User 1 (1).
  614. //
  615. HWREG(FLASH_FMA) = 0x80000000;
  616. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  617. //
  618. // Wait until the write has completed.
  619. //
  620. while (HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  621. {
  622. }
  623. //
  624. // Tell the flash controller to write the USER1 Register.
  625. //
  626. HWREG(FLASH_FMA) = 0x80000001;
  627. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  628. //
  629. // Wait until the write has completed.
  630. //
  631. while (HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  632. {
  633. }
  634. //
  635. // Success.
  636. //
  637. return (0);
  638. }
  639. //*****************************************************************************
  640. //
  641. //! Saves the user registers.
  642. //!
  643. //! This function makes the currently programmed user register 0, 1, 2 and 3
  644. //! settings permanent. This operation is non-reversible; a chip reset or
  645. //! power cycle does not change the flash protection.
  646. //!
  647. //! This function does not return until the protection has been saved.
  648. //!
  649. //! \note To ensure data integrity of the user registers, the commits should
  650. //! not be interrupted with a power loss.
  651. //!
  652. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  653. //
  654. //*****************************************************************************
  655. int32_t
  656. FlashAllUserRegisterSave(void)
  657. {
  658. uint32_t ui32Index;
  659. //
  660. // Setting the MSB of FMA will trigger a permanent save of a USER Register.
  661. // The 2 least signigicant bits, specify the exact User Register to save.
  662. // The value of the least significant bits for
  663. // USER Register 0 is 00,
  664. // USER Register 1 is 01,
  665. // USER Register 2 is 10 and
  666. // USER Register 3 is 11.
  667. //
  668. for (ui32Index = 0; ui32Index < 4; ui32Index++)
  669. {
  670. //
  671. // Tell the flash controller to commit a USER Register.
  672. //
  673. HWREG(FLASH_FMA) = (0x80000000 + ui32Index);
  674. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  675. //
  676. // Wait until the write has completed.
  677. //
  678. while (HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  679. {
  680. }
  681. }
  682. //
  683. // Success.
  684. //
  685. return (0);
  686. }
  687. //*****************************************************************************
  688. //
  689. //! Registers an interrupt handler for the flash interrupt.
  690. //!
  691. //! \param pfnHandler is a pointer to the function to be called when the flash
  692. //! interrupt occurs.
  693. //!
  694. //! This function sets the handler to be called when the flash interrupt
  695. //! occurs. The flash controller can generate an interrupt when an invalid
  696. //! flash access occurs, such as trying to program or erase a read-only block,
  697. //! or trying to read from an execute-only block. It can also generate an
  698. //! interrupt when a program or erase operation has completed. The interrupt
  699. //! is automatically enabled when the handler is registered.
  700. //!
  701. //! \sa IntRegister() for important information about registering interrupt
  702. //! handlers.
  703. //!
  704. //! \return None.
  705. //
  706. //*****************************************************************************
  707. void
  708. FlashIntRegister(void (*pfnHandler)(void))
  709. {
  710. //
  711. // Register the interrupt handler, returning an error if an error occurs.
  712. //
  713. IntRegister(INT_FLASH, pfnHandler);
  714. //
  715. // Enable the flash interrupt.
  716. //
  717. IntEnable(INT_FLASH);
  718. }
  719. //*****************************************************************************
  720. //
  721. //! Unregisters the interrupt handler for the flash interrupt.
  722. //!
  723. //! This function clears the handler to be called when the flash interrupt
  724. //! occurs. This function also masks off the interrupt in the interrupt
  725. //! controller so that the interrupt handler is no longer called.
  726. //!
  727. //! \sa IntRegister() for important information about registering interrupt
  728. //! handlers.
  729. //!
  730. //! \return None.
  731. //
  732. //*****************************************************************************
  733. void
  734. FlashIntUnregister(void)
  735. {
  736. //
  737. // Disable the interrupt.
  738. //
  739. IntDisable(INT_FLASH);
  740. //
  741. // Unregister the interrupt handler.
  742. //
  743. IntUnregister(INT_FLASH);
  744. }
  745. //*****************************************************************************
  746. //
  747. //! Enables individual flash controller interrupt sources.
  748. //!
  749. //! \param ui32IntFlags is a bit mask of the interrupt sources to be enabled.
  750. //! The ui32IntFlags parameter can be the logical OR of any of the following
  751. //! values:
  752. //!
  753. //! - \b FLASH_INT_ACCESS occurs when a program or erase action was attempted
  754. //! on a block of flash that is marked as read-only or execute-only.
  755. //! - \b FLASH_INT_PROGRAM occurs when a programming or erase cycle completes.
  756. //! - \b FLASH_INT_EEPROM occurs when an EEPROM interrupt occurs. The source of
  757. //! the EEPROM interrupt can be determined by reading the EEDONE register.
  758. //! - \b FLASH_INT_VOLTAGE_ERR occurs when the voltage was out of spec during
  759. //! the flash operation and the operation was terminated.
  760. //! - \b FLASH_INT_DATA_ERR occurs when an operation attempts to program a bit that
  761. //! contains a 0 to a 1.
  762. //! - \b FLASH_INT_ERASE_ERR occurs when an erase operation fails.
  763. //! - \b FLASH_INT_PROGRAM_ERR occurs when a program operation fails.
  764. //!
  765. //! This function enables the indicated flash controller interrupt sources.
  766. //! Only the sources that are enabled can be reflected to the processor
  767. //! interrupt; disabled sources have no effect on the processor.
  768. //!
  769. //! \return None.
  770. //
  771. //*****************************************************************************
  772. void
  773. FlashIntEnable(uint32_t ui32IntFlags)
  774. {
  775. //
  776. // Enable the specified interrupts.
  777. //
  778. HWREG(FLASH_FCIM) |= ui32IntFlags;
  779. }
  780. //*****************************************************************************
  781. //
  782. //! Disables individual flash controller interrupt sources.
  783. //!
  784. //! \param ui32IntFlags is a bit mask of the interrupt sources to be disabled.
  785. //! The ui32IntFlags parameter can be the logical OR of any of the following
  786. //! values:
  787. //!
  788. //! - \b FLASH_INT_ACCESS occurs when a program or erase action was attempted
  789. //! on a block of flash that is marked as read-only or execute-only.
  790. //! - \b FLASH_INT_PROGRAM occurs when a programming or erase cycle completes.
  791. //! - \b FLASH_INT_EEPROM occurs when an EEPROM interrupt occurs. The source of
  792. //! the EEPROM interrupt can be determined by reading the EEDONE register.
  793. //! - \b FLASH_INT_VOLTAGE_ERR occurs when the voltage was out of spec during
  794. //! the flash operation and the operation was terminated.
  795. //! - \b FLASH_INT_DATA_ERR occurs when an operation attempts to program a bit that
  796. //! contains a 0 to a 1.
  797. //! - \b FLASH_INT_ERASE_ERR occurs when an erase operation fails.
  798. //! - \b FLASH_INT_PROGRAM_ERR occurs when a program operation fails.
  799. //!
  800. //! This function disables the indicated flash controller interrupt sources.
  801. //! Only the sources that are enabled can be reflected to the processor
  802. //! interrupt; disabled sources have no effect on the processor.
  803. //!
  804. //! \return None.
  805. //
  806. //*****************************************************************************
  807. void
  808. FlashIntDisable(uint32_t ui32IntFlags)
  809. {
  810. //
  811. // Disable the specified interrupts.
  812. //
  813. HWREG(FLASH_FCIM) &= ~(ui32IntFlags);
  814. }
  815. //*****************************************************************************
  816. //
  817. //! Gets the current interrupt status.
  818. //!
  819. //! \param bMasked is false if the raw interrupt status is required and true if
  820. //! the masked interrupt status is required.
  821. //!
  822. //! This function returns the interrupt status for the flash controller.
  823. //! Either the raw interrupt status or the status of interrupts that are
  824. //! allowed to reflect to the processor can be returned.
  825. //!
  826. //! \return The current interrupt status, enumerated as a bit field of
  827. //! \b FLASH_INT_ACCESS, \b FLASH_INT_PROGRAM, \b FLASH_INT_EEPROM,
  828. //! FLASH_INT_VOLTAGE_ERR, FLASH_INT_DATA_ERR, FLASH_INT_ERASE_ERR, and
  829. //! FLASH_INT_PROGRAM_ERR.
  830. //
  831. //*****************************************************************************
  832. uint32_t
  833. FlashIntStatus(bool bMasked)
  834. {
  835. //
  836. // Return either the interrupt status or the raw interrupt status as
  837. // requested.
  838. //
  839. if (bMasked)
  840. {
  841. return (HWREG(FLASH_FCMISC));
  842. }
  843. else
  844. {
  845. return (HWREG(FLASH_FCRIS));
  846. }
  847. }
  848. //*****************************************************************************
  849. //
  850. //! Clears flash controller interrupt sources.
  851. //!
  852. //! \param ui32IntFlags is the bit mask of the interrupt sources to be cleared.
  853. //!
  854. //! The specified flash controller interrupt sources are cleared, so that they
  855. //! no longer assert. The
  856. //! ui32IntFlags parameter can be the logical OR of any of the following
  857. //! values:
  858. //!
  859. //! - \b FLASH_INT_ACCESS occurs when a program or erase action was attempted
  860. //! on a block of flash that is marked as read-only or execute-only.
  861. //! - \b FLASH_INT_PROGRAM occurs when a programming or erase cycle completes.
  862. //! - \b FLASH_INT_EEPROM occurs when an EEPROM interrupt occurs. The source of
  863. //! the EEPROM interrupt can be determined by reading the EEDONE register.
  864. //! - \b FLASH_INT_VOLTAGE_ERR occurs when the voltage was out of spec during
  865. //! the flash operation and the operation was terminated.
  866. //! - \b FLASH_INT_DATA_ERR occurs when an operation attempts to program a bit that
  867. //! contains a 0 to a 1.
  868. //! - \b FLASH_INT_ERASE_ERR occurs when an erase operation fails.
  869. //! - \b FLASH_INT_PROGRAM_ERR occurs when a program operation fails.
  870. //!
  871. //! This function must be called in the interrupt handler to keep the
  872. //! interrupt from being triggered again immediately upon exit.
  873. //!
  874. //! \note Because there is a write buffer in the Cortex-M processor, it may
  875. //! take several clock cycles before the interrupt source is actually cleared.
  876. //! Therefore, it is recommended that the interrupt source be cleared early in
  877. //! the interrupt handler (as opposed to the very last action) to avoid
  878. //! returning from the interrupt handler before the interrupt source is
  879. //! actually cleared. Failure to do so may result in the interrupt handler
  880. //! being immediately reentered (because the interrupt controller still sees
  881. //! the interrupt source asserted).
  882. //!
  883. //! \return None.
  884. //
  885. //*****************************************************************************
  886. void
  887. FlashIntClear(uint32_t ui32IntFlags)
  888. {
  889. //
  890. // Clear the flash interrupt.
  891. //
  892. HWREG(FLASH_FCMISC) = ui32IntFlags;
  893. }
  894. //*****************************************************************************
  895. //
  896. // Close the Doxygen group.
  897. //! @}
  898. //
  899. //*****************************************************************************