flash.c 27 KB

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