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