]> begriffs open source - cmsis-freertos/blob - Demo/CORTEX_LM3S811_IAR/LuminaryCode/flash.c
Update cmsis_os2.c
[cmsis-freertos] / Demo / CORTEX_LM3S811_IAR / LuminaryCode / flash.c
1 //*****************************************************************************
2 //
3 // flash.c - Driver for programming the on-chip flash.
4 //
5 // Copyright (c) 2005,2006 Luminary Micro, Inc.  All rights reserved.
6 //
7 // Software License Agreement
8 //
9 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
10 // exclusively on LMI's Stellaris Family of microcontroller products.
11 //
12 // The software is owned by LMI and/or its suppliers, and is protected under
13 // applicable copyright laws.  All rights are reserved.  Any use in violation
14 // of the foregoing restrictions may subject the user to criminal sanctions
15 // under applicable laws, as well as to civil liability for the breach of the
16 // terms and conditions of this license.
17 //
18 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
19 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
20 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
21 // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
22 // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
23 //
24 // This is part of revision 991 of the Stellaris Driver Library.
25 //
26 //*****************************************************************************
27
28 //*****************************************************************************
29 //
30 //! \addtogroup flash_api
31 //! @{
32 //
33 //*****************************************************************************
34
35 #include "../hw_flash.h"
36 #include "../hw_ints.h"
37 #include "../hw_memmap.h"
38 #include "../hw_sysctl.h"
39 #include "../hw_types.h"
40 #include "debug.h"
41 #include "flash.h"
42 #include "interrupt.h"
43
44 //*****************************************************************************
45 //
46 //! Gets the number of processor clocks per micro-second.
47 //!
48 //! This function returns the number of clocks per micro-second, as presently
49 //! known by the flash controller.
50 //!
51 //! \return Returns the number of processor clocks per micro-second.
52 //
53 //*****************************************************************************
54 #if defined(GROUP_usecget) || defined(BUILD_ALL) || defined(DOXYGEN)
55 unsigned long
56 FlashUsecGet(void)
57 {
58     //
59     // Return the number of clocks per micro-second.
60     //
61     return(HWREG(FLASH_USECRL) + 1);
62 }
63 #endif
64
65 //*****************************************************************************
66 //
67 //! Sets the number of processor clocks per micro-second.
68 //!
69 //! \param ulClocks is the number of processor clocks per micro-second.
70 //!
71 //! This function is used to tell the flash controller the number of processor
72 //! clocks per micro-second.  This value must be programmed correctly or the
73 //! flash most likely will not program correctly; it has no affect on reading
74 //! flash.
75 //!
76 //! \return None.
77 //
78 //*****************************************************************************
79 #if defined(GROUP_usecset) || defined(BUILD_ALL) || defined(DOXYGEN)
80 void
81 FlashUsecSet(unsigned long ulClocks)
82 {
83     //
84     // Set the number of clocks per micro-second.
85     //
86     HWREG(FLASH_USECRL) = ulClocks - 1;
87 }
88 #endif
89
90 //*****************************************************************************
91 //
92 //! Erases a block of flash.
93 //!
94 //! \param ulAddress is the start address of the flash block to be erased.
95 //!
96 //! This function will erase a 1 kB block of the on-chip flash.  After erasing,
97 //! the block will be filled with 0xFF bytes.  Read-only and execute-only
98 //! blocks cannot be erased.
99 //!
100 //! This function will not return until the block has been erased.
101 //!
102 //! \return Returns 0 on success, or -1 if an invalid block address was
103 //! specified or the block is write-protected.
104 //
105 //*****************************************************************************
106 #if defined(GROUP_erase) || defined(BUILD_ALL) || defined(DOXYGEN)
107 long
108 FlashErase(unsigned long ulAddress)
109 {
110     //
111     // Check the arguments.
112     //
113     ASSERT(!(ulAddress & (FLASH_ERASE_SIZE - 1)));
114
115     //
116     // Clear the flash access interrupt.
117     //
118     HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
119
120     //
121     // Erase the block.
122     //
123     HWREG(FLASH_FMA) = ulAddress;
124     HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
125
126     //
127     // Wait until the word has been programmed.
128     //
129     while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
130     {
131     }
132
133     //
134     // Return an error if an access violation occurred.
135     //
136     if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
137     {
138         return(-1);
139     }
140
141     //
142     // Success.
143     //
144     return(0);
145 }
146 #endif
147
148 //*****************************************************************************
149 //
150 //! Programs flash.
151 //!
152 //! \param pulData is a pointer to the data to be programmed.
153 //! \param ulAddress is the starting address in flash to be programmed.  Must
154 //! be a multiple of four.
155 //! \param ulCount is the number of bytes to be programmed.  Must be a multiple
156 //! of four.
157 //!
158 //! This function will program a sequence of words into the on-chip flash.
159 //! Programming each location consists of the result of an AND operation
160 //! of the new data and the existing data; in other words bits that contain
161 //! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed
162 //! to 1.  Therefore, a word can be programmed multiple times as long as these
163 //! rules are followed; if a program operation attempts to change a 0 bit to
164 //! a 1 bit, that bit will not have its value changed.
165 //!
166 //! Since the flash is programmed one word at a time, the starting address and
167 //! byte count must both be multiples of four.  It is up to the caller to
168 //! verify the programmed contents, if such verification is required.
169 //!
170 //! This function will not return until the data has been programmed.
171 //!
172 //! \return Returns 0 on success, or -1 if a programming error is encountered.
173 //
174 //*****************************************************************************
175 #if defined(GROUP_program) || defined(BUILD_ALL) || defined(DOXYGEN)
176 long
177 FlashProgram(unsigned long *pulData, unsigned long ulAddress,
178              unsigned long ulCount)
179 {
180     //
181     // Check the arguments.
182     //
183     ASSERT(!(ulAddress & 3));
184     ASSERT(!(ulCount & 3));
185
186     //
187     // Clear the flash access interrupt.
188     //
189     HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
190
191     //
192     // Loop over the words to be programmed.
193     //
194     while(ulCount)
195     {
196         //
197         // Program the next word.
198         //
199         HWREG(FLASH_FMA) = ulAddress;
200         HWREG(FLASH_FMD) = *pulData;
201         HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
202
203         //
204         // Wait until the word has been programmed.
205         //
206         while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
207         {
208         }
209
210         //
211         // Increment to the next word.
212         //
213         pulData++;
214         ulAddress += 4;
215         ulCount -= 4;
216     }
217
218     //
219     // Return an error if an access violation occurred.
220     //
221     if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
222     {
223         return(-1);
224     }
225
226     //
227     // Success.
228     //
229     return(0);
230 }
231 #endif
232
233 //*****************************************************************************
234 //
235 //! Gets the protection setting for a block of flash.
236 //!
237 //! \param ulAddress is the start address of the flash block to be queried.
238 //!
239 //! This function will get the current protection for the specified 2 kB block
240 //! of flash.  Each block can be read/write, read-only, or execute-only.
241 //! Read/write blocks can be read, executed, erased, and programmed.  Read-only
242 //! blocks can be read and executed.  Execute-only blocks can only be executed;
243 //! processor and debugger data reads are not allowed.
244 //!
245 //! \return Returns the protection setting for this block.  See
246 //! FlashProtectSet() for possible values.
247 //
248 //*****************************************************************************
249 #if defined(GROUP_protectget) || defined(BUILD_ALL) || defined(DOXYGEN)
250 tFlashProtection
251 FlashProtectGet(unsigned long ulAddress)
252 {
253     unsigned long ulFMPRE, ulFMPPE;
254
255     //
256     // Check the argument.
257     //
258     ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
259
260     //
261     // Read the flash protection register and get the bits that apply to the
262     // specified block.
263     //
264     ulFMPRE = HWREG(FLASH_FMPRE);
265     ulFMPPE = HWREG(FLASH_FMPPE);
266     switch((((ulFMPRE >> (ulAddress / FLASH_PROTECT_SIZE)) &
267              FLASH_FMP_BLOCK_0) << 1) |
268            ((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0))
269     {
270         //
271         // This block is marked as execute only (i.e. it can not be erased or
272         // programmed, and the only reads allowed are via the instruction fecth
273         // interface).
274         //
275         case 0:
276         case 1:
277         {
278             return(FlashExecuteOnly);
279         }
280
281         //
282         // This block is marked as read only (i.e. it can not be erased or
283         // programmed).
284         //
285         case 2:
286         {
287             return(FlashReadOnly);
288         }
289
290         //
291         // This block is read/write; it can be read, erased, and programmed.
292         //
293         case 3:
294         default:
295         {
296             return(FlashReadWrite);
297         }
298     }
299 }
300 #endif
301
302 //*****************************************************************************
303 //
304 //! Sets the protection setting for a block of flash.
305 //!
306 //! \param ulAddress is the start address of the flash block to be protected.
307 //! \param eProtect is the protection to be applied to the block.  Can be one
308 //! of \b FlashReadWrite, \b FlashReadOnly, or \b FlashExecuteOnly.
309 //!
310 //! This function will set the protection for the specified 2 kB block of
311 //! flash.  Blocks which are read/write can be made read-only or execute-only.
312 //! Blocks which are read-only can be made execute-only.  Blocks which are
313 //! execute-only cannot have their protection modified.  Attempts to make the
314 //! block protection less stringent (i.e. read-only to read/write) will result
315 //! in a failure (and be prevented by the hardware).
316 //!
317 //! Changes to the flash protection are maintained only until the next reset.
318 //! This allows the application to be executed in the desired flash protection
319 //! environment to check for inappropriate flash access (via the flash
320 //! interrupt).  To make the flash protection permanent, use the
321 //! FlashProtectSave() function.
322 //!
323 //! \return Returns 0 on success, or -1 if an invalid address or an invalid
324 //! protection was specified.
325 //
326 //*****************************************************************************
327 #if defined(GROUP_protectset) || defined(BUILD_ALL) || defined(DOXYGEN)
328 long
329 FlashProtectSet(unsigned long ulAddress, tFlashProtection eProtect)
330 {
331     unsigned long ulProtectRE, ulProtectPE;
332
333     //
334     // Check the argument.
335     //
336     ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
337     ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
338            (eProtect == FlashExecuteOnly));
339
340     //
341     // Convert the address into a block number.
342     //
343     ulAddress /= FLASH_PROTECT_SIZE;
344
345     //
346     // Get the current protection.
347     //
348     ulProtectRE = HWREG(FLASH_FMPRE);
349     ulProtectPE = HWREG(FLASH_FMPPE);
350
351     //
352     // Set the protection based on the requested proection.
353     //
354     switch(eProtect)
355     {
356         //
357         // Make this block execute only.
358         //
359         case FlashExecuteOnly:
360         {
361             //
362             // Turn off the read and program bits for this block.
363             //
364             ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
365             ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
366
367             //
368             // We're done handling this protection.
369             //
370             break;
371         }
372
373         //
374         // Make this block read only.
375         //
376         case FlashReadOnly:
377         {
378             //
379             // The block can not be made read only if it is execute only.
380             //
381             if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
382                FLASH_FMP_BLOCK_0)
383             {
384                 return(-1);
385             }
386
387             //
388             // Make this block read only.
389             //
390             ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
391
392             //
393             // We're done handling this protection.
394             //
395             break;
396         }
397
398         //
399         // Make this block read/write.
400         //
401         case FlashReadWrite:
402         default:
403         {
404             //
405             // The block can not be made read/write if it is not already
406             // read/write.
407             //
408             if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
409                 FLASH_FMP_BLOCK_0) ||
410                (((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
411                 FLASH_FMP_BLOCK_0))
412             {
413                 return(-1);
414             }
415
416             //
417             // The block is already read/write, so there is nothing to do.
418             //
419             return(0);
420         }
421     }
422
423     //
424     // Set the new protection.
425     //
426     HWREG(FLASH_FMPRE) = ulProtectRE;
427     HWREG(FLASH_FMPPE) = ulProtectPE;
428
429     //
430     // Success.
431     //
432     return(0);
433 }
434 #endif
435
436 //*****************************************************************************
437 //
438 //! Saves the flash protection settings.
439 //!
440 //! This function will make the currently programmed flash protection settings
441 //! permanent.  This is a non-reversible operation; a chip reset or power cycle
442 //! will not change the flash protection.
443 //!
444 //! This function will not return until the protection has been saved.
445 //!
446 //! \return Returns 0 on success, or -1 if a hardware error is encountered.
447 //
448 //*****************************************************************************
449 #if defined(GROUP_protectsave) || defined(BUILD_ALL) || defined(DOXYGEN)
450 long
451 FlashProtectSave(void)
452 {
453     //
454     // Tell the flash controller to write the flash read protection register.
455     //
456     HWREG(FLASH_FMA) = 0;
457     HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
458
459     //
460     // Wait until the write has completed.
461     //
462     while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
463     {
464     }
465
466     //
467     // Tell the flash controller to write the flash program protection
468     // register.
469     //
470     HWREG(FLASH_FMA) = 1;
471     HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
472
473     //
474     // Wait until the write has completed.
475     //
476     while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
477     {
478     }
479
480     //
481     // Success.
482     //
483     return(0);
484 }
485 #endif
486
487 //*****************************************************************************
488 //
489 //! Registers an interrupt handler for the flash interrupt.
490 //!
491 //! \param pfnHandler is a pointer to the function to be called when the flash
492 //! interrupt occurs.
493 //!
494 //! This sets the handler to be called when the flash interrupt occurs.  The
495 //! flash controller can generate an interrupt when an invalid flash access
496 //! occurs, such as trying to program or erase a read-only block, or trying to
497 //! read from an execute-only block.  It can also generate an interrupt when a
498 //! program or erase operation has completed.  The interrupt will be
499 //! automatically enabled when the handler is registered.
500 //!
501 //! \sa IntRegister() for important information about registering interrupt
502 //! handlers.
503 //!
504 //! \return None.
505 //
506 //*****************************************************************************
507 #if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN)
508 void
509 FlashIntRegister(void (*pfnHandler)(void))
510 {
511     //
512     // Register the interrupt handler, returning an error if an error occurs.
513     //
514     IntRegister(INT_FLASH, pfnHandler);
515
516     //
517     // Enable the flash interrupt.
518     //
519     IntEnable(INT_FLASH);
520 }
521 #endif
522
523 //*****************************************************************************
524 //
525 //! Unregisters the interrupt handler for the flash interrupt.
526 //!
527 //! This function will clear the handler to be called when the flash interrupt
528 //! occurs.  This will also mask off the interrupt in the interrupt controller
529 //! so that the interrupt handler is no longer called.
530 //!
531 //! \sa IntRegister() for important information about registering interrupt
532 //! handlers.
533 //!
534 //! \return None.
535 //
536 //*****************************************************************************
537 #if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN)
538 void
539 FlashIntUnregister(void)
540 {
541     //
542     // Disable the interrupt.
543     //
544     IntDisable(INT_FLASH);
545
546     //
547     // Unregister the interrupt handler.
548     //
549     IntUnregister(INT_FLASH);
550 }
551 #endif
552
553 //*****************************************************************************
554 //
555 //! Enables individual flash controller interrupt sources.
556 //!
557 //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
558 //! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
559 //!
560 //! Enables the indicated flash controller interrupt sources.  Only the sources
561 //! that are enabled can be reflected to the processor interrupt; disabled
562 //! sources have no effect on the processor.
563 //!
564 //! \return None.
565 //
566 //*****************************************************************************
567 #if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN)
568 void
569 FlashIntEnable(unsigned long ulIntFlags)
570 {
571     //
572     // Enable the specified interrupts.
573     //
574     HWREG(FLASH_FCIM) |= ulIntFlags;
575 }
576 #endif
577
578 //*****************************************************************************
579 //
580 //! Disables individual flash controller interrupt sources.
581 //!
582 //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
583 //! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
584 //!
585 //! Disables the indicated flash controller interrupt sources.  Only the
586 //! sources that are enabled can be reflected to the processor interrupt;
587 //! disabled sources have no effect on the processor.
588 //!
589 //! \return None.
590 //
591 //*****************************************************************************
592 #if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN)
593 void
594 FlashIntDisable(unsigned long ulIntFlags)
595 {
596     //
597     // Disable the specified interrupts.
598     //
599     HWREG(FLASH_FCIM) &= ~(ulIntFlags);
600 }
601 #endif
602
603 //*****************************************************************************
604 //
605 //! Gets the current interrupt status.
606 //!
607 //! \param bMasked is false if the raw interrupt status is required and true if
608 //! the masked interrupt status is required.
609 //!
610 //! This returns the interrupt status for the flash controller.  Either the raw
611 //! interrupt status or the status of interrupts that are allowed to reflect to
612 //! the processor can be returned.
613 //!
614 //! \return The current interrupt status, enumerated as a bit field of
615 //! \b FLASH_FCMISC_PROGRAM and \b FLASH_FCMISC_ACCESS.
616 //
617 //*****************************************************************************
618 #if defined(GROUP_intgetstatus) || defined(BUILD_ALL) || defined(DOXYGEN)
619 unsigned long
620 FlashIntGetStatus(tBoolean bMasked)
621 {
622     //
623     // Return either the interrupt status or the raw interrupt status as
624     // requested.
625     //
626     if(bMasked)
627     {
628         return(HWREG(FLASH_FCMISC));
629     }
630     else
631     {
632         return(HWREG(FLASH_FCRIS));
633     }
634 }
635 #endif
636
637 //*****************************************************************************
638 //
639 //! Clears flash controller interrupt sources.
640 //!
641 //! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
642 //! Can be any of the \b FLASH_FCMISC_PROGRAM or \b FLASH_FCMISC_ACCESS
643 //! values.
644 //!
645 //! The specified flash controller interrupt sources are cleared, so that they
646 //! no longer assert.  This must be done in the interrupt handler to keep it
647 //! from being called again immediately upon exit.
648 //!
649 //! \return None.
650 //
651 //*****************************************************************************
652 #if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN)
653 void
654 FlashIntClear(unsigned long ulIntFlags)
655 {
656     //
657     // Clear the flash interrupt.
658     //
659     HWREG(FLASH_FCMISC) = ulIntFlags;
660 }
661 #endif
662
663 //*****************************************************************************
664 //
665 // Close the Doxygen group.
666 //! @}
667 //
668 //*****************************************************************************