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