flash.c 28 KB

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