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