flash.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. //*****************************************************************************
  2. //
  3. // flash.c - Driver for programming the on-chip flash.
  4. //
  5. // Copyright (c) 2005-2009 Luminary Micro, Inc. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
  9. // exclusively on LMI's microcontroller products.
  10. //
  11. // The software is owned by LMI and/or its suppliers, and is protected under
  12. // applicable copyright laws. All rights are reserved. You may not combine
  13. // this software with "viral" open-source software in order to form a larger
  14. // program. Any use in violation of the foregoing restrictions may subject
  15. // the user to criminal sanctions under applicable laws, as well as to civil
  16. // liability for the breach of the terms and conditions of this license.
  17. //
  18. // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
  19. // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
  20. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
  21. // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
  22. // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
  23. //
  24. // This is part of revision 4694 of the Stellaris Peripheral Driver Library.
  25. //
  26. //*****************************************************************************
  27. //*****************************************************************************
  28. //
  29. //! \addtogroup flash_api
  30. //! @{
  31. //
  32. //*****************************************************************************
  33. #include "inc/hw_flash.h"
  34. #include "inc/hw_ints.h"
  35. #include "inc/hw_sysctl.h"
  36. #include "inc/hw_types.h"
  37. #include "driverlib/debug.h"
  38. #include "driverlib/flash.h"
  39. #include "driverlib/interrupt.h"
  40. //*****************************************************************************
  41. //
  42. // An array that maps the specified memory bank to the appropriate Flash
  43. // Memory Protection Program Enable (FMPPE) register.
  44. //
  45. //*****************************************************************************
  46. static const unsigned long g_pulFMPPERegs[] =
  47. {
  48. FLASH_FMPPE,
  49. FLASH_FMPPE1,
  50. FLASH_FMPPE2,
  51. FLASH_FMPPE3
  52. };
  53. //*****************************************************************************
  54. //
  55. // An array that maps the specified memory bank to the appropriate Flash
  56. // Memory Protection Read Enable (FMPRE) register.
  57. //
  58. //*****************************************************************************
  59. static const unsigned long g_pulFMPRERegs[] =
  60. {
  61. FLASH_FMPRE,
  62. FLASH_FMPRE1,
  63. FLASH_FMPRE2,
  64. FLASH_FMPRE3
  65. };
  66. //*****************************************************************************
  67. //
  68. //! Gets the number of processor clocks per micro-second.
  69. //!
  70. //! This function returns the number of clocks per micro-second, as presently
  71. //! known by the flash controller.
  72. //!
  73. //! \return Returns the number of processor clocks per micro-second.
  74. //
  75. //*****************************************************************************
  76. unsigned long
  77. FlashUsecGet(void)
  78. {
  79. //
  80. // Return the number of clocks per micro-second.
  81. //
  82. return(HWREG(FLASH_USECRL) + 1);
  83. }
  84. //*****************************************************************************
  85. //
  86. //! Sets the number of processor clocks per micro-second.
  87. //!
  88. //! \param ulClocks is the number of processor clocks per micro-second.
  89. //!
  90. //! This function is used to tell the flash controller the number of processor
  91. //! clocks per micro-second. This value must be programmed correctly or the
  92. //! flash most likely will not program correctly; it has no affect on reading
  93. //! flash.
  94. //!
  95. //! \return None.
  96. //
  97. //*****************************************************************************
  98. void
  99. FlashUsecSet(unsigned long ulClocks)
  100. {
  101. //
  102. // Set the number of clocks per micro-second.
  103. //
  104. HWREG(FLASH_USECRL) = ulClocks - 1;
  105. }
  106. //*****************************************************************************
  107. //
  108. //! Erases a block of flash.
  109. //!
  110. //! \param ulAddress is the start address of the flash block to be erased.
  111. //!
  112. //! This function will erase a 1 kB block of the on-chip flash. After erasing,
  113. //! the block will be filled with 0xFF bytes. Read-only and execute-only
  114. //! blocks cannot be erased.
  115. //!
  116. //! This function will not return until the block has been erased.
  117. //!
  118. //! \return Returns 0 on success, or -1 if an invalid block address was
  119. //! specified or the block is write-protected.
  120. //
  121. //*****************************************************************************
  122. long
  123. FlashErase(unsigned long ulAddress)
  124. {
  125. //
  126. // Check the arguments.
  127. //
  128. ASSERT(!(ulAddress & (FLASH_ERASE_SIZE - 1)));
  129. //
  130. // Clear the flash access interrupt.
  131. //
  132. HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC;
  133. //
  134. // Erase the block.
  135. //
  136. HWREG(FLASH_FMA) = ulAddress;
  137. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
  138. //
  139. // Wait until the block has been erased.
  140. //
  141. while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
  142. {
  143. }
  144. //
  145. // Return an error if an access violation occurred.
  146. //
  147. if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS)
  148. {
  149. return(-1);
  150. }
  151. //
  152. // Success.
  153. //
  154. return(0);
  155. }
  156. //*****************************************************************************
  157. //
  158. //! Programs flash.
  159. //!
  160. //! \param pulData is a pointer to the data to be programmed.
  161. //! \param ulAddress is the starting address in flash to be programmed. Must
  162. //! be a multiple of four.
  163. //! \param ulCount is the number of bytes to be programmed. Must be a multiple
  164. //! of four.
  165. //!
  166. //! This function will program a sequence of words into the on-chip flash.
  167. //! Programming each location consists of the result of an AND operation
  168. //! of the new data and the existing data; in other words bits that contain
  169. //! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed
  170. //! to 1. Therefore, a word can be programmed multiple times as long as these
  171. //! rules are followed; if a program operation attempts to change a 0 bit to
  172. //! a 1 bit, that bit will not have its value changed.
  173. //!
  174. //! Since the flash is programmed one word at a time, the starting address and
  175. //! byte count must both be multiples of four. It is up to the caller to
  176. //! verify the programmed contents, if such verification is required.
  177. //!
  178. //! This function will not return until the data has been programmed.
  179. //!
  180. //! \return Returns 0 on success, or -1 if a programming error is encountered.
  181. //
  182. //*****************************************************************************
  183. long
  184. FlashProgram(unsigned long *pulData, unsigned long ulAddress,
  185. unsigned long ulCount)
  186. {
  187. //
  188. // Check the arguments.
  189. //
  190. ASSERT(!(ulAddress & 3));
  191. ASSERT(!(ulCount & 3));
  192. //
  193. // Clear the flash access interrupt.
  194. //
  195. HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC;
  196. //
  197. // See if this device has a write buffer.
  198. //
  199. if(HWREG(SYSCTL_NVMSTAT) & SYSCTL_NVMSTAT_FWB)
  200. {
  201. //
  202. // Loop over the words to be programmed.
  203. //
  204. while(ulCount)
  205. {
  206. //
  207. // Set the address of this block of words.
  208. //
  209. HWREG(FLASH_FMA) = ulAddress & ~(0x7f);
  210. //
  211. // Loop over the words in this 32-word block.
  212. //
  213. while(((ulAddress & 0x7c) || (HWREG(FLASH_FWBVAL) == 0)) &&
  214. (ulCount != 0))
  215. {
  216. //
  217. // Write this word into the write buffer.
  218. //
  219. HWREG(FLASH_FWBN + (ulAddress & 0x7c)) = *pulData++;
  220. ulAddress += 4;
  221. ulCount -= 4;
  222. }
  223. //
  224. // Program the contents of the write buffer into flash.
  225. //
  226. HWREG(FLASH_FMC2) = FLASH_FMC2_WRKEY | FLASH_FMC2_WRBUF;
  227. //
  228. // Wait until the write buffer has been programmed.
  229. //
  230. while(HWREG(FLASH_FMC2) & FLASH_FMC2_WRBUF)
  231. {
  232. }
  233. }
  234. }
  235. else
  236. {
  237. //
  238. // Loop over the words to be programmed.
  239. //
  240. while(ulCount)
  241. {
  242. //
  243. // Program the next word.
  244. //
  245. HWREG(FLASH_FMA) = ulAddress;
  246. HWREG(FLASH_FMD) = *pulData;
  247. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
  248. //
  249. // Wait until the word has been programmed.
  250. //
  251. while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
  252. {
  253. }
  254. //
  255. // Increment to the next word.
  256. //
  257. pulData++;
  258. ulAddress += 4;
  259. ulCount -= 4;
  260. }
  261. }
  262. //
  263. // Return an error if an access violation occurred.
  264. //
  265. if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS)
  266. {
  267. return(-1);
  268. }
  269. //
  270. // Success.
  271. //
  272. return(0);
  273. }
  274. //*****************************************************************************
  275. //
  276. //! Gets the protection setting for a block of flash.
  277. //!
  278. //! \param ulAddress is the start address of the flash block to be queried.
  279. //!
  280. //! This function will get the current protection for the specified 2 kB block
  281. //! of flash. Each block can be read/write, read-only, or execute-only.
  282. //! Read/write blocks can be read, executed, erased, and programmed. Read-only
  283. //! blocks can be read and executed. Execute-only blocks can only be executed;
  284. //! processor and debugger data reads are not allowed.
  285. //!
  286. //! \return Returns the protection setting for this block. See
  287. //! FlashProtectSet() for possible values.
  288. //
  289. //*****************************************************************************
  290. tFlashProtection
  291. FlashProtectGet(unsigned long ulAddress)
  292. {
  293. unsigned long ulFMPRE, ulFMPPE;
  294. unsigned long ulBank;
  295. //
  296. // Check the argument.
  297. //
  298. ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
  299. //
  300. // Calculate the Flash Bank from Base Address, and mask off the Bank
  301. // from ulAddress for subsequent reference.
  302. //
  303. ulBank = (((ulAddress / FLASH_PROTECT_SIZE) / 32) % 4);
  304. ulAddress &= ((FLASH_PROTECT_SIZE * 32) - 1);
  305. //
  306. // Read the appropriate flash protection registers for the specified
  307. // flash bank.
  308. //
  309. ulFMPRE = HWREG(g_pulFMPRERegs[ulBank]);
  310. ulFMPPE = HWREG(g_pulFMPPERegs[ulBank]);
  311. //
  312. // For Stellaris Sandstorm-class devices, revision C1 and C2, the upper
  313. // bits of the FMPPE register are used for JTAG protect options, and are
  314. // not available for the FLASH protection scheme. When Querying Block
  315. // Protection, assume these bits are 1.
  316. //
  317. if(CLASS_IS_SANDSTORM && (REVISION_IS_C1 || REVISION_IS_C2))
  318. {
  319. ulFMPRE |= (FLASH_FMP_BLOCK_31 | FLASH_FMP_BLOCK_30);
  320. }
  321. //
  322. // Check the appropriate protection bits for the block of memory that
  323. // is specified by the address.
  324. //
  325. switch((((ulFMPRE >> (ulAddress / FLASH_PROTECT_SIZE)) &
  326. FLASH_FMP_BLOCK_0) << 1) |
  327. ((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0))
  328. {
  329. //
  330. // This block is marked as execute only (that is, it can not be erased
  331. // or programmed, and the only reads allowed are via the instruction
  332. // fetch interface).
  333. //
  334. case 0:
  335. case 1:
  336. {
  337. return(FlashExecuteOnly);
  338. }
  339. //
  340. // This block is marked as read only (that is, it can not be erased or
  341. // programmed).
  342. //
  343. case 2:
  344. {
  345. return(FlashReadOnly);
  346. }
  347. //
  348. // This block is read/write; it can be read, erased, and programmed.
  349. //
  350. case 3:
  351. default:
  352. {
  353. return(FlashReadWrite);
  354. }
  355. }
  356. }
  357. //*****************************************************************************
  358. //
  359. //! Sets the protection setting for a block of flash.
  360. //!
  361. //! \param ulAddress is the start address of the flash block to be protected.
  362. //! \param eProtect is the protection to be applied to the block. Can be one
  363. //! of \b FlashReadWrite, \b FlashReadOnly, or \b FlashExecuteOnly.
  364. //!
  365. //! This function will set the protection for the specified 2 kB block of
  366. //! flash. Blocks which are read/write can be made read-only or execute-only.
  367. //! Blocks which are read-only can be made execute-only. Blocks which are
  368. //! execute-only cannot have their protection modified. Attempts to make the
  369. //! block protection less stringent (that is, read-only to read/write) will
  370. //! result in a failure (and be prevented by the hardware).
  371. //!
  372. //! Changes to the flash protection are maintained only until the next reset.
  373. //! This allows the application to be executed in the desired flash protection
  374. //! environment to check for inappropriate flash access (via the flash
  375. //! interrupt). To make the flash protection permanent, use the
  376. //! FlashProtectSave() function.
  377. //!
  378. //! \return Returns 0 on success, or -1 if an invalid address or an invalid
  379. //! protection was specified.
  380. //
  381. //*****************************************************************************
  382. long
  383. FlashProtectSet(unsigned long ulAddress, tFlashProtection eProtect)
  384. {
  385. unsigned long ulProtectRE, ulProtectPE;
  386. unsigned long ulBank;
  387. //
  388. // Check the argument.
  389. //
  390. ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
  391. ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
  392. (eProtect == FlashExecuteOnly));
  393. //
  394. // Convert the address into a block number.
  395. //
  396. ulAddress /= FLASH_PROTECT_SIZE;
  397. //
  398. // ulAddress contains a "raw" block number. Derive the Flash Bank from
  399. // the "raw" block number, and convert ulAddress to a "relative"
  400. // block number.
  401. //
  402. ulBank = ((ulAddress / 32) % 4);
  403. ulAddress %= 32;
  404. //
  405. // Get the current protection for the specified flash bank.
  406. //
  407. ulProtectRE = HWREG(g_pulFMPRERegs[ulBank]);
  408. ulProtectPE = HWREG(g_pulFMPPERegs[ulBank]);
  409. //
  410. // For Stellaris Sandstorm-class devices, revision C1 and C2, the upper
  411. // bits of the FMPPE register are used for JTAG protect options, and are
  412. // not available for the FLASH protection scheme. When setting protection,
  413. // check to see if block 30 or 31 and protection is FlashExecuteOnly. If
  414. // so, return an error condition.
  415. //
  416. if(CLASS_IS_SANDSTORM && (REVISION_IS_C1 || REVISION_IS_C2))
  417. {
  418. if((ulAddress >= 30) && (eProtect == FlashExecuteOnly))
  419. {
  420. return(-1);
  421. }
  422. }
  423. //
  424. // Set the protection based on the requested proection.
  425. //
  426. switch(eProtect)
  427. {
  428. //
  429. // Make this block execute only.
  430. //
  431. case FlashExecuteOnly:
  432. {
  433. //
  434. // Turn off the read and program bits for this block.
  435. //
  436. ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
  437. ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
  438. //
  439. // We're done handling this protection.
  440. //
  441. break;
  442. }
  443. //
  444. // Make this block read only.
  445. //
  446. case FlashReadOnly:
  447. {
  448. //
  449. // The block can not be made read only if it is execute only.
  450. //
  451. if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
  452. FLASH_FMP_BLOCK_0)
  453. {
  454. return(-1);
  455. }
  456. //
  457. // Make this block read only.
  458. //
  459. ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
  460. //
  461. // We're done handling this protection.
  462. //
  463. break;
  464. }
  465. //
  466. // Make this block read/write.
  467. //
  468. case FlashReadWrite:
  469. default:
  470. {
  471. //
  472. // The block can not be made read/write if it is not already
  473. // read/write.
  474. //
  475. if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
  476. FLASH_FMP_BLOCK_0) ||
  477. (((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
  478. FLASH_FMP_BLOCK_0))
  479. {
  480. return(-1);
  481. }
  482. //
  483. // The block is already read/write, so there is nothing to do.
  484. //
  485. return(0);
  486. }
  487. }
  488. //
  489. // For Stellaris Sandstorm-class devices, revision C1 and C2, the upper
  490. // bits of the FMPPE register are used for JTAG options, and are not
  491. // available for the FLASH protection scheme. When setting block
  492. // protection, ensure that these bits are not altered.
  493. //
  494. if(CLASS_IS_SANDSTORM && (REVISION_IS_C1 || REVISION_IS_C2))
  495. {
  496. ulProtectRE &= ~(FLASH_FMP_BLOCK_31 | FLASH_FMP_BLOCK_30);
  497. ulProtectRE |= (HWREG(g_pulFMPRERegs[ulBank]) &
  498. (FLASH_FMP_BLOCK_31 | FLASH_FMP_BLOCK_30));
  499. }
  500. //
  501. // Set the new protection for the specified flash bank.
  502. //
  503. HWREG(g_pulFMPRERegs[ulBank]) = ulProtectRE;
  504. HWREG(g_pulFMPPERegs[ulBank]) = ulProtectPE;
  505. //
  506. // Success.
  507. //
  508. return(0);
  509. }
  510. //*****************************************************************************
  511. //
  512. //! Saves the flash protection settings.
  513. //!
  514. //! This function will make the currently programmed flash protection settings
  515. //! permanent. This is a non-reversible operation; a chip reset or power cycle
  516. //! will not change the flash protection.
  517. //!
  518. //! This function will not return until the protection has been saved.
  519. //!
  520. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  521. //
  522. //*****************************************************************************
  523. long
  524. FlashProtectSave(void)
  525. {
  526. int ulTemp, ulLimit;
  527. //
  528. // If running on a Sandstorm-class device, only trigger a save of the first
  529. // two protection registers (FMPRE and FMPPE). Otherwise, save the
  530. // entire bank of flash protection registers.
  531. //
  532. ulLimit = CLASS_IS_SANDSTORM ? 2 : 8;
  533. for(ulTemp = 0; ulTemp < ulLimit; ulTemp++)
  534. {
  535. //
  536. // Tell the flash controller to write the flash protection register.
  537. //
  538. HWREG(FLASH_FMA) = ulTemp;
  539. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  540. //
  541. // Wait until the write has completed.
  542. //
  543. while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  544. {
  545. }
  546. }
  547. //
  548. // Success.
  549. //
  550. return(0);
  551. }
  552. //*****************************************************************************
  553. //
  554. //! Gets the user registers.
  555. //!
  556. //! \param pulUser0 is a pointer to the location to store USER Register 0.
  557. //! \param pulUser1 is a pointer to the location to store USER Register 1.
  558. //!
  559. //! This function will read the contents of user registers (0 and 1), and
  560. //! store them in the specified locations.
  561. //!
  562. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  563. //
  564. //*****************************************************************************
  565. long
  566. FlashUserGet(unsigned long *pulUser0, unsigned long *pulUser1)
  567. {
  568. //
  569. // Verify that the pointers are valid.
  570. //
  571. ASSERT(pulUser0 != 0);
  572. ASSERT(pulUser1 != 0);
  573. //
  574. // Verify that hardware supports user registers.
  575. //
  576. if(CLASS_IS_SANDSTORM)
  577. {
  578. return(-1);
  579. }
  580. //
  581. // Get and store the current value of the user registers.
  582. //
  583. *pulUser0 = HWREG(FLASH_USERREG0);
  584. *pulUser1 = HWREG(FLASH_USERREG1);
  585. //
  586. // Success.
  587. //
  588. return(0);
  589. }
  590. //*****************************************************************************
  591. //
  592. //! Sets the user registers.
  593. //!
  594. //! \param ulUser0 is the value to store in USER Register 0.
  595. //! \param ulUser1 is the value to store in USER Register 1.
  596. //!
  597. //! This function will set the contents of the user registers (0 and 1) to
  598. //! the specified values.
  599. //!
  600. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  601. //
  602. //*****************************************************************************
  603. long
  604. FlashUserSet(unsigned long ulUser0, unsigned long ulUser1)
  605. {
  606. //
  607. // Verify that hardware supports user registers.
  608. //
  609. if(CLASS_IS_SANDSTORM)
  610. {
  611. return(-1);
  612. }
  613. //
  614. // Save the new values into the user registers.
  615. //
  616. HWREG(FLASH_USERREG0) = ulUser0;
  617. HWREG(FLASH_USERREG1) = ulUser1;
  618. //
  619. // Success.
  620. //
  621. return(0);
  622. }
  623. //*****************************************************************************
  624. //
  625. //! Saves the user registers.
  626. //!
  627. //! This function will make the currently programmed user register settings
  628. //! permanent. This is a non-reversible operation; a chip reset or power cycle
  629. //! will not change this setting.
  630. //!
  631. //! This function will not return until the protection has been saved.
  632. //!
  633. //! \return Returns 0 on success, or -1 if a hardware error is encountered.
  634. //
  635. //*****************************************************************************
  636. long
  637. FlashUserSave(void)
  638. {
  639. //
  640. // Verify that hardware supports user registers.
  641. //
  642. if(CLASS_IS_SANDSTORM)
  643. {
  644. return(-1);
  645. }
  646. //
  647. // Setting the MSB of FMA will trigger a permanent save of a USER
  648. // register. Bit 0 will indicate User 0 (0) or User 1 (1).
  649. //
  650. HWREG(FLASH_FMA) = 0x80000000;
  651. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  652. //
  653. // Wait until the write has completed.
  654. //
  655. while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  656. {
  657. }
  658. //
  659. // Tell the flash controller to write the USER1 Register.
  660. //
  661. HWREG(FLASH_FMA) = 0x80000001;
  662. HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
  663. //
  664. // Wait until the write has completed.
  665. //
  666. while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
  667. {
  668. }
  669. //
  670. // Success.
  671. //
  672. return(0);
  673. }
  674. //*****************************************************************************
  675. //
  676. //! Registers an interrupt handler for the flash interrupt.
  677. //!
  678. //! \param pfnHandler is a pointer to the function to be called when the flash
  679. //! interrupt occurs.
  680. //!
  681. //! This sets the handler to be called when the flash interrupt occurs. The
  682. //! flash controller can generate an interrupt when an invalid flash access
  683. //! occurs, such as trying to program or erase a read-only block, or trying to
  684. //! read from an execute-only block. It can also generate an interrupt when a
  685. //! program or erase operation has completed. The interrupt will be
  686. //! automatically enabled when the handler is registered.
  687. //!
  688. //! \sa IntRegister() for important information about registering interrupt
  689. //! handlers.
  690. //!
  691. //! \return None.
  692. //
  693. //*****************************************************************************
  694. void
  695. FlashIntRegister(void (*pfnHandler)(void))
  696. {
  697. //
  698. // Register the interrupt handler, returning an error if an error occurs.
  699. //
  700. IntRegister(INT_FLASH, pfnHandler);
  701. //
  702. // Enable the flash interrupt.
  703. //
  704. IntEnable(INT_FLASH);
  705. }
  706. //*****************************************************************************
  707. //
  708. //! Unregisters the interrupt handler for the flash interrupt.
  709. //!
  710. //! This function will clear the handler to be called when the flash interrupt
  711. //! occurs. This will also mask off the interrupt in the interrupt controller
  712. //! so that the interrupt handler is no longer called.
  713. //!
  714. //! \sa IntRegister() for important information about registering interrupt
  715. //! handlers.
  716. //!
  717. //! \return None.
  718. //
  719. //*****************************************************************************
  720. void
  721. FlashIntUnregister(void)
  722. {
  723. //
  724. // Disable the interrupt.
  725. //
  726. IntDisable(INT_FLASH);
  727. //
  728. // Unregister the interrupt handler.
  729. //
  730. IntUnregister(INT_FLASH);
  731. }
  732. //*****************************************************************************
  733. //
  734. //! Enables individual flash controller interrupt sources.
  735. //!
  736. //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
  737. //! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
  738. //!
  739. //! Enables the indicated flash controller interrupt sources. Only the sources
  740. //! that are enabled can be reflected to the processor interrupt; disabled
  741. //! sources have no effect on the processor.
  742. //!
  743. //! \return None.
  744. //
  745. //*****************************************************************************
  746. void
  747. FlashIntEnable(unsigned long ulIntFlags)
  748. {
  749. //
  750. // Enable the specified interrupts.
  751. //
  752. HWREG(FLASH_FCIM) |= ulIntFlags;
  753. }
  754. //*****************************************************************************
  755. //
  756. //! Disables individual flash controller interrupt sources.
  757. //!
  758. //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
  759. //! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
  760. //!
  761. //! Disables the indicated flash controller interrupt sources. Only the
  762. //! sources that are enabled can be reflected to the processor interrupt;
  763. //! disabled sources have no effect on the processor.
  764. //!
  765. //! \return None.
  766. //
  767. //*****************************************************************************
  768. void
  769. FlashIntDisable(unsigned long ulIntFlags)
  770. {
  771. //
  772. // Disable the specified interrupts.
  773. //
  774. HWREG(FLASH_FCIM) &= ~(ulIntFlags);
  775. }
  776. //*****************************************************************************
  777. //
  778. //! Gets the current interrupt status.
  779. //!
  780. //! \param bMasked is false if the raw interrupt status is required and true if
  781. //! the masked interrupt status is required.
  782. //!
  783. //! This returns the interrupt status for the flash controller. Either the raw
  784. //! interrupt status or the status of interrupts that are allowed to reflect to
  785. //! the processor can be returned.
  786. //!
  787. //! \return The current interrupt status, enumerated as a bit field of
  788. //! \b FLASH_FCMISC_PROGRAM and \b FLASH_FCMISC_AMISC.
  789. //
  790. //*****************************************************************************
  791. unsigned long
  792. FlashIntGetStatus(tBoolean bMasked)
  793. {
  794. //
  795. // Return either the interrupt status or the raw interrupt status as
  796. // requested.
  797. //
  798. if(bMasked)
  799. {
  800. return(HWREG(FLASH_FCMISC));
  801. }
  802. else
  803. {
  804. return(HWREG(FLASH_FCRIS));
  805. }
  806. }
  807. //*****************************************************************************
  808. //
  809. //! Clears flash controller interrupt sources.
  810. //!
  811. //! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
  812. //! Can be any of the \b FLASH_FCMISC_PROGRAM or \b FLASH_FCMISC_AMISC values.
  813. //!
  814. //! The specified flash controller interrupt sources are cleared, so that they
  815. //! no longer assert. This must be done in the interrupt handler to keep it
  816. //! from being called again immediately upon exit.
  817. //!
  818. //! \note Since there is a write buffer in the Cortex-M3 processor, it may take
  819. //! several clock cycles before the interrupt source is actually cleared.
  820. //! Therefore, it is recommended that the interrupt source be cleared early in
  821. //! the interrupt handler (as opposed to the very last action) to avoid
  822. //! returning from the interrupt handler before the interrupt source is
  823. //! actually cleared. Failure to do so may result in the interrupt handler
  824. //! being immediately reentered (since NVIC still sees the interrupt source
  825. //! asserted).
  826. //!
  827. //! \return None.
  828. //
  829. //*****************************************************************************
  830. void
  831. FlashIntClear(unsigned long ulIntFlags)
  832. {
  833. //
  834. // Clear the flash interrupt.
  835. //
  836. HWREG(FLASH_FCMISC) = ulIntFlags;
  837. }
  838. //*****************************************************************************
  839. //
  840. // Close the Doxygen group.
  841. //! @}
  842. //
  843. //*****************************************************************************