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