]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4_SimpleLink_CC3220SF_CCS/ti/devices/cc32xx/driverlib/flash.c
Add SimpleLink CC3220SF demo.
[freertos] / FreeRTOS / Demo / CORTEX_M4_SimpleLink_CC3220SF_CCS / ti / devices / cc32xx / driverlib / flash.c
1 /*
2  * -------------------------------------------
3  *    CC3220 SDK - v0.10.00.00 
4  * -------------------------------------------
5  *
6  *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 
7  *  
8  *  Redistribution and use in source and binary forms, with or without 
9  *  modification, are permitted provided that the following conditions 
10  *  are met:
11  *
12  *    Redistributions of source code must retain the above copyright 
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  *    Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the 
17  *    documentation and/or other materials provided with the   
18  *    distribution.
19  *
20  *    Neither the name of Texas Instruments Incorporated nor the names of
21  *    its contributors may be used to endorse or promote products derived
22  *    from this software without specific prior written permission.
23  *
24  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
25  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
26  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
28  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
29  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
30  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
33  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
34  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *  
36  */
37 //*****************************************************************************
38 //
39 //  flash.c
40 //
41 //  Driver for programming the on-chip flash.
42 //
43 //*****************************************************************************
44
45 //*****************************************************************************
46 //
47 //! \addtogroup flash_api
48 //! @{
49 //
50 //*****************************************************************************
51
52 #include "inc/hw_types.h"
53 #include "inc/hw_flash_ctrl.h"
54 #include "inc/hw_memmap.h"
55 #include "inc/hw_ints.h"
56 #include "inc/hw_gprcm.h"
57 #include "inc/hw_hib1p2.h"
58 #include "inc/hw_hib3p3.h"
59 #include "inc/hw_common_reg.h"
60 #include "inc/hw_stack_die_ctrl.h"
61 #include "debug.h"
62 #include "flash.h"
63 #include "utils.h"
64 #include "interrupt.h"
65
66 #define HAVE_WRITE_BUFFER       1
67
68
69
70 //*****************************************************************************
71 //
72 // An array that maps the specified memory bank to the appropriate Flash
73 // Memory Protection Program Enable (FMPPE) register.
74 //
75 //*****************************************************************************
76 static const unsigned long g_pulFMPPERegs[] =
77 {
78     FLASH_FMPPE0,
79     FLASH_FMPPE1,
80     FLASH_FMPPE2,
81     FLASH_FMPPE3,
82     FLASH_FMPPE4,
83     FLASH_FMPPE5,
84     FLASH_FMPPE6,
85     FLASH_FMPPE7,
86     FLASH_FMPPE8,
87     FLASH_FMPPE9,
88     FLASH_FMPPE10,
89     FLASH_FMPPE11,
90     FLASH_FMPPE12,
91     FLASH_FMPPE13,
92     FLASH_FMPPE14,
93     FLASH_FMPPE15
94
95
96 };
97
98 //*****************************************************************************
99 //
100 // An array that maps the specified memory bank to the appropriate Flash
101 // Memory Protection Read Enable (FMPRE) register.
102 //
103 //*****************************************************************************
104 static const unsigned long g_pulFMPRERegs[] =
105 {
106     FLASH_FMPRE0,
107     FLASH_FMPRE1,
108     FLASH_FMPRE2,
109     FLASH_FMPRE3,
110     FLASH_FMPRE4,
111     FLASH_FMPRE5,
112     FLASH_FMPRE6,
113     FLASH_FMPRE7,
114     FLASH_FMPRE8,
115     FLASH_FMPRE9,
116     FLASH_FMPRE10,
117     FLASH_FMPRE11,
118     FLASH_FMPRE12,
119     FLASH_FMPRE13,
120     FLASH_FMPRE14,
121     FLASH_FMPRE15,
122 };
123
124 //*****************************************************************************
125 //
126 //! Flash Disable
127 //!
128 //! This function Disables the internal Flash.
129 //!
130 //! \return None.
131 //
132 //*****************************************************************************
133 void
134 FlashDisable()
135 {
136
137   //
138   // Wait for Flash Busy to get cleared
139   //
140   while((HWREG(GPRCM_BASE + GPRCM_O_TOP_DIE_ENABLE)
141           & GPRCM_TOP_DIE_ENABLE_FLASH_BUSY))
142   {
143
144   }
145
146   //
147   // Assert reset
148   //
149   HWREG(HIB1P2_BASE + HIB1P2_O_PORPOL_SPARE) = 0xFFFF0000;
150
151   //
152   // 50 usec Delay Loop
153   //
154   UtilsDelay((50*80)/3);
155
156   //
157   // Disable TDFlash
158   //
159   HWREG(GPRCM_BASE + GPRCM_O_TOP_DIE_ENABLE) = 0x0;
160
161   //
162   // 50 usec Delay Loop
163   //
164   UtilsDelay((50*80)/3);
165
166   HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
167
168   //
169   // 50 usec Delay Loop
170   //
171   UtilsDelay((50*80)/3);
172 }
173
174
175 //*****************************************************************************
176 //
177 //! Erases a block of flash.
178 //!
179 //! \param ulAddress is the start address of the flash block to be erased.
180 //!
181 //! This function will erase a 2 kB block of the on-chip flash.  After erasing,
182 //! the block will be filled with 0xFF bytes.  Read-only and execute-only
183 //! blocks cannot be erased.
184 //!
185 //! This function will not return until the block has been erased.
186 //!
187 //! \return Returns 0 on success, or -1 if an invalid block address was
188 //! specified or the block is write-protected.
189 //
190 //*****************************************************************************
191 long
192 FlashErase(unsigned long ulAddress)
193 {
194     //
195     // Check the arguments.
196     //
197     ASSERT(!(ulAddress & (FLASH_CTRL_ERASE_SIZE - 1)));
198
199     //
200     // Clear the flash access and error interrupts.
201     //
202     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC)
203       = (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
204                            FLASH_CTRL_FCMISC_ERMISC);
205
206     // Erase the block.
207     //
208     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
209     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC)
210                                 = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_ERASE;
211
212     //
213     // Wait until the block has been erased.
214     //
215     while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) & FLASH_CTRL_FMC_ERASE)
216     {
217     }
218
219     //
220     // Return an error if an access violation or erase error occurred.
221     //
222     if(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS)
223        & (FLASH_CTRL_FCRIS_ARIS | FLASH_CTRL_FCRIS_VOLTRIS |
224                              FLASH_CTRL_FCRIS_ERRIS))
225
226
227     {
228         return(-1);
229     }
230
231     //
232     // Success.
233     //
234     return(0);
235 }
236
237
238 //*****************************************************************************
239 //
240 //! Erases a block of flash but does not wait for completion.
241 //!
242 //! \param ulAddress is the start address of the flash block to be erased.
243 //!
244 //! This function will erase a 2 kB block of the on-chip flash.  After erasing,
245 //! the block will be filled with 0xFF bytes.  Read-only and execute-only
246 //! blocks cannot be erased.
247 //!
248 //! This function will return immediately after commanding the erase operation.
249 //! Applications making use of the function can determine completion state by
250 //! using a flash interrupt handler or by polling FlashIntStatus.
251 //!
252 //! \return None.
253 //
254 //*****************************************************************************
255 void
256 FlashEraseNonBlocking(unsigned long ulAddress)
257 {
258     //
259     // Check the arguments.
260     //
261     ASSERT(!(ulAddress & (FLASH_CTRL_ERASE_SIZE - 1)));
262
263     //
264     // Clear the flash access and error interrupts.
265     //
266     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) =
267       (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
268                            FLASH_CTRL_FCMISC_ERMISC);
269
270     //
271     // Command the flash controller to erase the block.
272     //
273     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
274     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_ERASE;
275 }
276
277
278 //*****************************************************************************
279 //
280 //! Erases a complele flash at shot.
281 //!
282 //! This function erases a complele flash at shot
283 //!
284 //! \return Returns 0 on success, or -1 if the block is write-protected.
285 //
286 //*****************************************************************************
287 long
288 FlashMassErase()
289 {
290     //
291     // Clear the flash access and error interrupts.
292     //
293     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) =
294       (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
295                            FLASH_CTRL_FCMISC_ERMISC);
296
297     //
298     // Command the flash controller for mass erase.
299     //
300     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) =
301       FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_MERASE1;
302
303     //
304     // Wait until mass erase completes.
305     //
306     while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) & FLASH_CTRL_FMC_MERASE1)
307     {
308
309     }
310
311     //
312     // Return an error if an access violation or erase error occurred.
313     //
314     if(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS)
315        & (FLASH_CTRL_FCRIS_ARIS | FLASH_CTRL_FCRIS_VOLTRIS |
316                              FLASH_CTRL_FCRIS_ERRIS))
317     {
318         return -1;
319     }
320
321     //
322     // Success.
323     //
324     return 0;
325 }
326
327 //*****************************************************************************
328 //
329 //! Erases a complele flash at shot but does not wait for completion.
330 //!
331 //!
332 //! This function will not return until the Flash has been erased.
333 //!
334 //! \return None.
335 //
336 //*****************************************************************************
337 void
338 FlashMassEraseNonBlocking()
339 {
340     //
341     // Clear the flash access and error interrupts.
342     //
343     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) =
344       (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
345                            FLASH_CTRL_FCMISC_ERMISC);
346
347     //
348     // Command the flash controller for mass erase.
349     //
350     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) =
351       FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_MERASE1;
352
353 }
354
355 //*****************************************************************************
356 //
357 //! Programs flash.
358 //!
359 //! \param pulData is a pointer to the data to be programmed.
360 //! \param ulAddress is the starting address in flash to be programmed.  Must
361 //! be a multiple of four.
362 //! \param ulCount is the number of bytes to be programmed.  Must be a multiple
363 //! of four.
364 //!
365 //! This function will program a sequence of words into the on-chip flash.
366 //! Each word in a page of flash can only be programmed one time between an
367 //! erase of that page; programming a word multiple times will result in an
368 //! unpredictable value in that word of flash.
369 //!
370 //! Since the flash is programmed one word at a time, the starting address and
371 //! byte count must both be multiples of four.  It is up to the caller to
372 //! verify the programmed contents, if such verification is required.
373 //!
374 //! This function will not return until the data has been programmed.
375 //!
376 //! \return Returns 0 on success, or -1 if a programming error is encountered.
377 //
378 //*****************************************************************************
379 long
380 FlashProgram(unsigned long *pulData, unsigned long ulAddress,
381              unsigned long ulCount)
382 {
383     //
384     // Check the arguments.
385     //
386     ASSERT(!(ulAddress & 3));
387     ASSERT(!(ulCount & 3));
388
389     //
390     // Clear the flash access and error interrupts.
391     //
392     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC)
393       = (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
394                            FLASH_CTRL_FCMISC_INVDMISC | FLASH_CTRL_FCMISC_PROGMISC);
395
396
397     //
398     // See if this device has a write buffer.
399     //
400
401 #if HAVE_WRITE_BUFFER
402     {
403         //
404         // Loop over the words to be programmed.
405         //
406         while(ulCount)
407         {
408             //
409             // Set the address of this block of words. for 1 MB
410             //
411             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress & ~(0x7F);
412
413             //
414             // Loop over the words in this 32-word block.
415             //
416             while(((ulAddress & 0x7C) ||
417                    (HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBVAL) == 0)) &&
418                   (ulCount != 0))
419             {
420                 //
421                 // Write this word into the write buffer.
422                 //
423                 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBN
424                       + (ulAddress & 0x7C)) = *pulData++;
425                 ulAddress += 4;
426                 ulCount -= 4;
427             }
428
429             //
430             // Program the contents of the write buffer into flash.
431             //
432             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC2)
433               = FLASH_CTRL_FMC2_WRKEY | FLASH_CTRL_FMC2_WRBUF;
434
435             //
436             // Wait until the write buffer has been programmed.
437             //
438             while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC2) & FLASH_CTRL_FMC2_WRBUF)
439             {
440             }
441         }
442     }
443 #else
444     {
445         //
446         // Loop over the words to be programmed.
447         //
448         while(ulCount)
449         {
450             //
451             // Program the next word.
452             //
453             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
454             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMD) = *pulData;
455             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_WRITE;
456
457             //
458             // Wait until the word has been programmed.
459             //
460             while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) & FLASH_CTRL_FMC_WRITE)
461             {
462             }
463
464             //
465             // Increment to the next word.
466             //
467             pulData++;
468             ulAddress += 4;
469             ulCount -= 4;
470         }
471     }
472 #endif
473     //
474     // Return an error if an access violation occurred.
475     //
476
477     if(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS) & (FLASH_CTRL_FCRIS_ARIS | FLASH_CTRL_FCRIS_VOLTRIS |
478                              FLASH_CTRL_FCRIS_INVDRIS | FLASH_CTRL_FCRIS_PROGRIS))
479
480     {
481         return(-1);
482     }
483
484     //
485     // Success.
486     //
487     return(0);
488 }
489
490
491 //*****************************************************************************
492 //
493 //! Programs flash but does not poll for completion.
494 //!
495 //! \param pulData is a pointer to the data to be programmed.
496 //! \param ulAddress is the starting address in flash to be programmed.  Must
497 //! be a multiple of four.
498 //! \param ulCount is the number of bytes to be programmed.  Must be a multiple
499 //! of four.
500 //!
501 //! This function will start programming one or more words into the on-chip
502 //! flash and return immediately.  The number of words that can be programmed
503 //! in a single call depends the part on which the function is running.  For
504 //! parts without support for a flash write buffer, only a single word may be
505 //! programmed on each call to this function (\e ulCount must be 1).  If a
506 //! write buffer is present, up to 32 words may be programmed on condition
507 //! that the block being programmed does not straddle a 32 word address
508 //! boundary.  For example, wherease 32 words can be programmed if the address
509 //! passed is 0x100 (a multiple of 128 bytes or 32 words), only 31 words could
510 //! be programmed at 0x104 since attempting to write 32 would cross the 32
511 //! word boundary at 0x180.
512 //!
513 //! Since the flash is programmed one word at a time, the starting address and
514 //! byte count must both be multiples of four.  It is up to the caller to
515 //! verify the programmed contents, if such verification is required.
516 //!
517 //! This function will return immediately after commanding the erase operation.
518 //! Applications making use of the function can determine completion state by
519 //! using a flash interrupt handler or by polling FlashIntStatus.
520 //!
521 //! \return 0 if the write was started successfully, -1 if there was an error.
522 //
523 //*****************************************************************************
524 long
525 FlashProgramNonBlocking(unsigned long *pulData, unsigned long ulAddress,
526                         unsigned long ulCount)
527 {
528     //
529     // Check the arguments.
530     //
531     ASSERT(!(ulAddress & 3));
532     ASSERT(!(ulCount & 3));
533
534     //
535     // Clear the flash access and error interrupts.
536     //
537     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC)
538       = (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
539                            FLASH_CTRL_FCMISC_INVDMISC | FLASH_CTRL_FCMISC_PROGMISC);
540
541     //
542     // See if this device has a write buffer.
543     //
544
545 #if HAVE_WRITE_BUFFER
546     {
547         //
548         // Make sure the address/count specified doesn't straddle a 32 word
549         // boundary.
550         //
551         if(((ulAddress + (ulCount - 1)) & ~0x7F) != (ulAddress & ~0x7F))
552         {
553             return(-1);
554         }
555
556         //
557         // Loop over the words to be programmed.
558         //
559         while(ulCount)
560         {
561             //
562             // Set the address of this block of words.
563             //
564             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress & ~(0x7F);
565
566             //
567             // Loop over the words in this 32-word block.
568             //
569             while(((ulAddress & 0x7C) || (HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBVAL) == 0)) &&
570                   (ulCount != 0))
571             {
572                 //
573                 // Write this word into the write buffer.
574                 //
575                 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBN + (ulAddress & 0x7C)) = *pulData++;
576                 ulAddress += 4;
577                 ulCount -= 4;
578             }
579
580             //
581             // Program the contents of the write buffer into flash.
582             //
583             HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC2) = FLASH_CTRL_FMC2_WRKEY | FLASH_CTRL_FMC2_WRBUF;
584         }
585     }
586 #else
587     {
588         //
589         // We don't have a write buffer so we can only write a single word.
590         //
591         if(ulCount > 1)
592         {
593             return(-1);
594         }
595
596         //
597         // Write a single word.
598         //
599         HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
600         HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMD) = *pulData;
601         HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_WRITE;
602     }
603 #endif
604     //
605     // Success.
606     //
607     return(0);
608 }
609
610
611 //*****************************************************************************
612 //
613 //! Gets the protection setting for a block of flash.
614 //!
615 //! \param ulAddress is the start address of the flash block to be queried.
616 //!
617 //! This function gets the current protection for the specified 2-kB block
618 //! of flash.  Each block can be read/write, read-only, or execute-only.
619 //! Read/write blocks can be read, executed, erased, and programmed.  Read-only
620 //! blocks can be read and executed.  Execute-only blocks can only be executed;
621 //! processor and debugger data reads are not allowed.
622 //!
623 //! \return Returns the protection setting for this block.  See
624 //! FlashProtectSet() for possible values.
625 //
626 //*****************************************************************************
627 tFlashProtection
628 FlashProtectGet(unsigned long ulAddress)
629 {
630     unsigned long ulFMPRE, ulFMPPE;
631     unsigned long ulBank;
632
633     //
634     // Check the argument.
635     //
636     ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
637
638     //
639     // Calculate the Flash Bank from Base Address, and mask off the Bank
640     // from ulAddress for subsequent reference.
641     //
642     ulBank = (((ulAddress / FLASH_PROTECT_SIZE) / 32) % 16);
643     ulAddress &= ((FLASH_PROTECT_SIZE * 32) - 1);
644
645     //
646     // Read the appropriate flash protection registers for the specified
647     // flash bank.
648     //
649     ulFMPRE = HWREG(g_pulFMPRERegs[ulBank]);
650     ulFMPPE = HWREG(g_pulFMPPERegs[ulBank]);
651
652     //
653     // Check the appropriate protection bits for the block of memory that
654     // is specified by the address.
655     //
656     switch((((ulFMPRE >> (ulAddress / FLASH_PROTECT_SIZE)) &
657              FLASH_FMP_BLOCK_0) << 1) |
658            ((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0))
659     {
660         //
661         // This block is marked as execute only (that is, it can not be erased
662         // or programmed, and the only reads allowed are via the instruction
663         // fetch interface).
664         //
665         case 0:
666         case 1:
667         {
668             return(FlashExecuteOnly);
669         }
670
671         //
672         // This block is marked as read only (that is, it can not be erased or
673         // programmed).
674         //
675         case 2:
676         {
677             return(FlashReadOnly);
678         }
679
680         //
681         // This block is read/write; it can be read, erased, and programmed.
682         //
683         case 3:
684         default:
685         {
686             return(FlashReadWrite);
687         }
688     }
689 }
690
691 //*****************************************************************************
692 //
693 //! Registers an interrupt handler for the flash interrupt.
694 //!
695 //! \param pfnHandler is a pointer to the function to be called when the flash
696 //! interrupt occurs.
697 //!
698 //! This sets the handler to be called when the flash interrupt occurs.  The
699 //! flash controller can generate an interrupt when an invalid flash access
700 //! occurs, such as trying to program or erase a read-only block, or trying to
701 //! read from an execute-only block.  It can also generate an interrupt when a
702 //! program or erase operation has completed.  The interrupt will be
703 //! automatically enabled when the handler is registered.
704 //!
705 //! \sa IntRegister() for important information about registering interrupt
706 //! handlers.
707 //!
708 //! \return None.
709 //
710 //*****************************************************************************
711 void
712 FlashIntRegister(void (*pfnHandler)(void))
713 {
714     //
715     // Register the interrupt handler, returning an error if an error occurs.
716     //
717     IntRegister(INT_FLASH, pfnHandler);
718
719     //
720     // Enable the flash interrupt.
721     //
722     IntEnable(INT_FLASH);
723 }
724
725 //*****************************************************************************
726 //
727 //! Unregisters the interrupt handler for the flash interrupt.
728 //!
729 //! This function will clear the handler to be called when the flash interrupt
730 //! occurs.  This will also mask off the interrupt in the interrupt controller
731 //! so that the interrupt handler is no longer called.
732 //!
733 //! \sa IntRegister() for important information about registering interrupt
734 //! handlers.
735 //!
736 //! \return None.
737 //
738 //*****************************************************************************
739 void
740 FlashIntUnregister(void)
741 {
742     //
743     // Disable the interrupt.
744     //
745     IntDisable(INT_FLASH);
746
747     //
748     // Unregister the interrupt handler.
749     //
750     IntUnregister(INT_FLASH);
751 }
752
753 //*****************************************************************************
754 //
755 //! Enables individual flash controller interrupt sources.
756 //!
757 //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
758 //! Can be any of the \b FLASH_CTRL_PROGRAM or \b FLASH_CTRL_ACCESS values.
759 //!
760 //! Enables the indicated flash controller interrupt sources.  Only the sources
761 //! that are enabled can be reflected to the processor interrupt; disabled
762 //! sources have no effect on the processor.
763 //!
764 //! \return None.
765 //
766 //*****************************************************************************
767 void
768 FlashIntEnable(unsigned long ulIntFlags)
769 {
770     //
771     // Enable the specified interrupts.
772     //
773     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCIM) |= ulIntFlags;
774 }
775
776 //*****************************************************************************
777 //
778 //! Disables individual flash controller interrupt sources.
779 //!
780 //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
781 //! Can be any of the \b FLASH_CTRL_PROGRAM or \b FLASH_CTRL_ACCESS values.
782 //!
783 //! Disables the indicated flash controller interrupt sources.  Only the
784 //! sources that are enabled can be reflected to the processor interrupt;
785 //! disabled sources have no effect on the processor.
786 //!
787 //! \return None.
788 //
789 //*****************************************************************************
790 void
791 FlashIntDisable(unsigned long ulIntFlags)
792 {
793     //
794     // Disable the specified interrupts.
795     //
796     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCIM) &= ~(ulIntFlags);
797 }
798
799 //*****************************************************************************
800 //
801 //! Gets the current interrupt status.
802 //!
803 //! \param bMasked is false if the raw interrupt status is required and true if
804 //! the masked interrupt status is required.
805 //!
806 //! This returns the interrupt status for the flash controller.  Either the raw
807 //! interrupt status or the status of interrupts that are allowed to reflect to
808 //! the processor can be returned.
809 //!
810 //! \return The current interrupt status, enumerated as a bit field of
811 //! \b FLASH_CTRL_PROGRAM and \b FLASH_CTRL_ACCESS.
812 //
813 //*****************************************************************************
814 unsigned long
815 FlashIntStatus(tBoolean bMasked)
816 {
817     //
818     // Return either the interrupt status or the raw interrupt status as
819     // requested.
820     //
821     if(bMasked)
822     {
823         return(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC));
824     }
825     else
826     {
827         return(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS));
828     }
829 }
830
831 //*****************************************************************************
832 //
833 //! Clears flash controller interrupt sources.
834 //!
835 //! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
836 //! Can be any of the \b FLASH_CTRL_PROGRAM or \b FLASH_CTRL_AMISC values.
837 //!
838 //! The specified flash controller interrupt sources are cleared, so that they
839 //! no longer assert.  This must be done in the interrupt handler to keep it
840 //! from being called again immediately upon exit.
841 //!
842 //! \note Because there is a write buffer in the Cortex-M3 processor, it may
843 //! take several clock cycles before the interrupt source is actually cleared.
844 //! Therefore, it is recommended that the interrupt source be cleared early in
845 //! the interrupt handler (as opposed to the very last action) to avoid
846 //! returning from the interrupt handler before the interrupt source is
847 //! actually cleared.  Failure to do so may result in the interrupt handler
848 //! being immediately reentered (because the interrupt controller still sees
849 //! the interrupt source asserted).
850 //!
851 //! \return None.
852 //
853 //*****************************************************************************
854 void
855 FlashIntClear(unsigned long ulIntFlags)
856 {
857     //
858     // Clear the flash interrupt.
859     //
860     HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) = ulIntFlags;
861 }
862
863 //*****************************************************************************
864 //
865 // Close the Doxygen group.
866 //! @}
867 //
868 //*****************************************************************************