1 //*****************************************************************************
3 // flash.c - Driver for programming the on-chip flash.
5 // Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved.
7 // Software License Agreement
9 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
10 // exclusively on LMI's Stellaris Family of microcontroller products.
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.
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.
24 // This is part of revision 991 of the Stellaris Driver Library.
26 //*****************************************************************************
28 //*****************************************************************************
30 //! \addtogroup flash_api
33 //*****************************************************************************
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"
42 #include "interrupt.h"
44 //*****************************************************************************
46 //! Gets the number of processor clocks per micro-second.
48 //! This function returns the number of clocks per micro-second, as presently
49 //! known by the flash controller.
51 //! \return Returns the number of processor clocks per micro-second.
53 //*****************************************************************************
54 #if defined(GROUP_usecget) || defined(BUILD_ALL) || defined(DOXYGEN)
59 // Return the number of clocks per micro-second.
61 return(HWREG(FLASH_USECRL) + 1);
65 //*****************************************************************************
67 //! Sets the number of processor clocks per micro-second.
69 //! \param ulClocks is the number of processor clocks per micro-second.
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
78 //*****************************************************************************
79 #if defined(GROUP_usecset) || defined(BUILD_ALL) || defined(DOXYGEN)
81 FlashUsecSet(unsigned long ulClocks)
84 // Set the number of clocks per micro-second.
86 HWREG(FLASH_USECRL) = ulClocks - 1;
90 //*****************************************************************************
92 //! Erases a block of flash.
94 //! \param ulAddress is the start address of the flash block to be erased.
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.
100 //! This function will not return until the block has been erased.
102 //! \return Returns 0 on success, or -1 if an invalid block address was
103 //! specified or the block is write-protected.
105 //*****************************************************************************
106 #if defined(GROUP_erase) || defined(BUILD_ALL) || defined(DOXYGEN)
108 FlashErase(unsigned long ulAddress)
111 // Check the arguments.
113 ASSERT(!(ulAddress & (FLASH_ERASE_SIZE - 1)));
116 // Clear the flash access interrupt.
118 HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
123 HWREG(FLASH_FMA) = ulAddress;
124 HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
127 // Wait until the word has been programmed.
129 while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
134 // Return an error if an access violation occurred.
136 if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
148 //*****************************************************************************
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
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.
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.
170 //! This function will not return until the data has been programmed.
172 //! \return Returns 0 on success, or -1 if a programming error is encountered.
174 //*****************************************************************************
175 #if defined(GROUP_program) || defined(BUILD_ALL) || defined(DOXYGEN)
177 FlashProgram(unsigned long *pulData, unsigned long ulAddress,
178 unsigned long ulCount)
181 // Check the arguments.
183 ASSERT(!(ulAddress & 3));
184 ASSERT(!(ulCount & 3));
187 // Clear the flash access interrupt.
189 HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
192 // Loop over the words to be programmed.
197 // Program the next word.
199 HWREG(FLASH_FMA) = ulAddress;
200 HWREG(FLASH_FMD) = *pulData;
201 HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
204 // Wait until the word has been programmed.
206 while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
211 // Increment to the next word.
219 // Return an error if an access violation occurred.
221 if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
233 //*****************************************************************************
235 //! Gets the protection setting for a block of flash.
237 //! \param ulAddress is the start address of the flash block to be queried.
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.
245 //! \return Returns the protection setting for this block. See
246 //! FlashProtectSet() for possible values.
248 //*****************************************************************************
249 #if defined(GROUP_protectget) || defined(BUILD_ALL) || defined(DOXYGEN)
251 FlashProtectGet(unsigned long ulAddress)
253 unsigned long ulFMPRE, ulFMPPE;
256 // Check the argument.
258 ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
261 // Read the flash protection register and get the bits that apply to the
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))
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
278 return(FlashExecuteOnly);
282 // This block is marked as read only (i.e. it can not be erased or
287 return(FlashReadOnly);
291 // This block is read/write; it can be read, erased, and programmed.
296 return(FlashReadWrite);
302 //*****************************************************************************
304 //! Sets the protection setting for a block of flash.
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.
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).
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.
323 //! \return Returns 0 on success, or -1 if an invalid address or an invalid
324 //! protection was specified.
326 //*****************************************************************************
327 #if defined(GROUP_protectset) || defined(BUILD_ALL) || defined(DOXYGEN)
329 FlashProtectSet(unsigned long ulAddress, tFlashProtection eProtect)
331 unsigned long ulProtectRE, ulProtectPE;
334 // Check the argument.
336 ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
337 ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
338 (eProtect == FlashExecuteOnly));
341 // Convert the address into a block number.
343 ulAddress /= FLASH_PROTECT_SIZE;
346 // Get the current protection.
348 ulProtectRE = HWREG(FLASH_FMPRE);
349 ulProtectPE = HWREG(FLASH_FMPPE);
352 // Set the protection based on the requested proection.
357 // Make this block execute only.
359 case FlashExecuteOnly:
362 // Turn off the read and program bits for this block.
364 ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
365 ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
368 // We're done handling this protection.
374 // Make this block read only.
379 // The block can not be made read only if it is execute only.
381 if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
388 // Make this block read only.
390 ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
393 // We're done handling this protection.
399 // Make this block read/write.
405 // The block can not be made read/write if it is not already
408 if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
409 FLASH_FMP_BLOCK_0) ||
410 (((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
417 // The block is already read/write, so there is nothing to do.
424 // Set the new protection.
426 HWREG(FLASH_FMPRE) = ulProtectRE;
427 HWREG(FLASH_FMPPE) = ulProtectPE;
436 //*****************************************************************************
438 //! Saves the flash protection settings.
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.
444 //! This function will not return until the protection has been saved.
446 //! \return Returns 0 on success, or -1 if a hardware error is encountered.
448 //*****************************************************************************
449 #if defined(GROUP_protectsave) || defined(BUILD_ALL) || defined(DOXYGEN)
451 FlashProtectSave(void)
454 // Tell the flash controller to write the flash read protection register.
456 HWREG(FLASH_FMA) = 0;
457 HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
460 // Wait until the write has completed.
462 while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
467 // Tell the flash controller to write the flash program protection
470 HWREG(FLASH_FMA) = 1;
471 HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
474 // Wait until the write has completed.
476 while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
487 //*****************************************************************************
489 //! Registers an interrupt handler for the flash interrupt.
491 //! \param pfnHandler is a pointer to the function to be called when the flash
492 //! interrupt occurs.
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.
501 //! \sa IntRegister() for important information about registering interrupt
506 //*****************************************************************************
507 #if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN)
509 FlashIntRegister(void (*pfnHandler)(void))
512 // Register the interrupt handler, returning an error if an error occurs.
514 IntRegister(INT_FLASH, pfnHandler);
517 // Enable the flash interrupt.
519 IntEnable(INT_FLASH);
523 //*****************************************************************************
525 //! Unregisters the interrupt handler for the flash interrupt.
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.
531 //! \sa IntRegister() for important information about registering interrupt
536 //*****************************************************************************
537 #if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN)
539 FlashIntUnregister(void)
542 // Disable the interrupt.
544 IntDisable(INT_FLASH);
547 // Unregister the interrupt handler.
549 IntUnregister(INT_FLASH);
553 //*****************************************************************************
555 //! Enables individual flash controller interrupt sources.
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.
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.
566 //*****************************************************************************
567 #if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN)
569 FlashIntEnable(unsigned long ulIntFlags)
572 // Enable the specified interrupts.
574 HWREG(FLASH_FCIM) |= ulIntFlags;
578 //*****************************************************************************
580 //! Disables individual flash controller interrupt sources.
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.
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.
591 //*****************************************************************************
592 #if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN)
594 FlashIntDisable(unsigned long ulIntFlags)
597 // Disable the specified interrupts.
599 HWREG(FLASH_FCIM) &= ~(ulIntFlags);
603 //*****************************************************************************
605 //! Gets the current interrupt status.
607 //! \param bMasked is false if the raw interrupt status is required and true if
608 //! the masked interrupt status is required.
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.
614 //! \return The current interrupt status, enumerated as a bit field of
615 //! \b FLASH_FCMISC_PROGRAM and \b FLASH_FCMISC_ACCESS.
617 //*****************************************************************************
618 #if defined(GROUP_intgetstatus) || defined(BUILD_ALL) || defined(DOXYGEN)
620 FlashIntGetStatus(tBoolean bMasked)
623 // Return either the interrupt status or the raw interrupt status as
628 return(HWREG(FLASH_FCMISC));
632 return(HWREG(FLASH_FCRIS));
637 //*****************************************************************************
639 //! Clears flash controller interrupt sources.
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
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.
651 //*****************************************************************************
652 #if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN)
654 FlashIntClear(unsigned long ulIntFlags)
657 // Clear the flash interrupt.
659 HWREG(FLASH_FCMISC) = ulIntFlags;
663 //*****************************************************************************
665 // Close the Doxygen group.
668 //*****************************************************************************