2 * -------------------------------------------
3 * CC3220 SDK - v0.10.00.00
4 * -------------------------------------------
6 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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
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.
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.
37 //*****************************************************************************
41 // Driver for programming the on-chip flash.
43 //*****************************************************************************
45 //*****************************************************************************
47 //! \addtogroup flash_api
50 //*****************************************************************************
52 #include "inc/hw_types.h"
53 #include "inc/hw_flash_ctrl.h"
54 #include "inc/hw_memmap.h"
55 #include "inc/hw_ints.h"
56 #include "inc/hw_gprcm.h"
57 #include "inc/hw_hib1p2.h"
58 #include "inc/hw_hib3p3.h"
59 #include "inc/hw_common_reg.h"
60 #include "inc/hw_stack_die_ctrl.h"
64 #include "interrupt.h"
66 #define HAVE_WRITE_BUFFER 1
70 //*****************************************************************************
72 // An array that maps the specified memory bank to the appropriate Flash
73 // Memory Protection Program Enable (FMPPE) register.
75 //*****************************************************************************
76 static const unsigned long g_pulFMPPERegs[] =
98 //*****************************************************************************
100 // An array that maps the specified memory bank to the appropriate Flash
101 // Memory Protection Read Enable (FMPRE) register.
103 //*****************************************************************************
104 static const unsigned long g_pulFMPRERegs[] =
124 //*****************************************************************************
128 //! This function Disables the internal Flash.
132 //*****************************************************************************
138 // Wait for Flash Busy to get cleared
140 while((HWREG(GPRCM_BASE + GPRCM_O_TOP_DIE_ENABLE)
141 & GPRCM_TOP_DIE_ENABLE_FLASH_BUSY))
149 HWREG(HIB1P2_BASE + HIB1P2_O_PORPOL_SPARE) = 0xFFFF0000;
152 // 50 usec Delay Loop
154 UtilsDelay((50*80)/3);
159 HWREG(GPRCM_BASE + GPRCM_O_TOP_DIE_ENABLE) = 0x0;
162 // 50 usec Delay Loop
164 UtilsDelay((50*80)/3);
166 HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
169 // 50 usec Delay Loop
171 UtilsDelay((50*80)/3);
175 //*****************************************************************************
177 //! Erases a block of flash.
179 //! \param ulAddress is the start address of the flash block to be erased.
181 //! This function will erase a 2 kB block of the on-chip flash. After erasing,
182 //! the block will be filled with 0xFF bytes. Read-only and execute-only
183 //! blocks cannot be erased.
185 //! This function will not return until the block has been erased.
187 //! \return Returns 0 on success, or -1 if an invalid block address was
188 //! specified or the block is write-protected.
190 //*****************************************************************************
192 FlashErase(unsigned long ulAddress)
195 // Check the arguments.
197 ASSERT(!(ulAddress & (FLASH_CTRL_ERASE_SIZE - 1)));
200 // Clear the flash access and error interrupts.
202 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC)
203 = (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
204 FLASH_CTRL_FCMISC_ERMISC);
208 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
209 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC)
210 = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_ERASE;
213 // Wait until the block has been erased.
215 while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) & FLASH_CTRL_FMC_ERASE)
220 // Return an error if an access violation or erase error occurred.
222 if(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS)
223 & (FLASH_CTRL_FCRIS_ARIS | FLASH_CTRL_FCRIS_VOLTRIS |
224 FLASH_CTRL_FCRIS_ERRIS))
238 //*****************************************************************************
240 //! Erases a block of flash but does not wait for completion.
242 //! \param ulAddress is the start address of the flash block to be erased.
244 //! This function will erase a 2 kB block of the on-chip flash. After erasing,
245 //! the block will be filled with 0xFF bytes. Read-only and execute-only
246 //! blocks cannot be erased.
248 //! This function will return immediately after commanding the erase operation.
249 //! Applications making use of the function can determine completion state by
250 //! using a flash interrupt handler or by polling FlashIntStatus.
254 //*****************************************************************************
256 FlashEraseNonBlocking(unsigned long ulAddress)
259 // Check the arguments.
261 ASSERT(!(ulAddress & (FLASH_CTRL_ERASE_SIZE - 1)));
264 // Clear the flash access and error interrupts.
266 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) =
267 (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
268 FLASH_CTRL_FCMISC_ERMISC);
271 // Command the flash controller to erase the block.
273 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
274 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_ERASE;
278 //*****************************************************************************
280 //! Erases a complele flash at shot.
282 //! This function erases a complele flash at shot
284 //! \return Returns 0 on success, or -1 if the block is write-protected.
286 //*****************************************************************************
291 // Clear the flash access and error interrupts.
293 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) =
294 (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
295 FLASH_CTRL_FCMISC_ERMISC);
298 // Command the flash controller for mass erase.
300 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) =
301 FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_MERASE1;
304 // Wait until mass erase completes.
306 while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) & FLASH_CTRL_FMC_MERASE1)
312 // Return an error if an access violation or erase error occurred.
314 if(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS)
315 & (FLASH_CTRL_FCRIS_ARIS | FLASH_CTRL_FCRIS_VOLTRIS |
316 FLASH_CTRL_FCRIS_ERRIS))
327 //*****************************************************************************
329 //! Erases a complele flash at shot but does not wait for completion.
332 //! This function will not return until the Flash has been erased.
336 //*****************************************************************************
338 FlashMassEraseNonBlocking()
341 // Clear the flash access and error interrupts.
343 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) =
344 (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
345 FLASH_CTRL_FCMISC_ERMISC);
348 // Command the flash controller for mass erase.
350 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) =
351 FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_MERASE1;
355 //*****************************************************************************
359 //! \param pulData is a pointer to the data to be programmed.
360 //! \param ulAddress is the starting address in flash to be programmed. Must
361 //! be a multiple of four.
362 //! \param ulCount is the number of bytes to be programmed. Must be a multiple
365 //! This function will program a sequence of words into the on-chip flash.
366 //! Each word in a page of flash can only be programmed one time between an
367 //! erase of that page; programming a word multiple times will result in an
368 //! unpredictable value in that word of flash.
370 //! Since the flash is programmed one word at a time, the starting address and
371 //! byte count must both be multiples of four. It is up to the caller to
372 //! verify the programmed contents, if such verification is required.
374 //! This function will not return until the data has been programmed.
376 //! \return Returns 0 on success, or -1 if a programming error is encountered.
378 //*****************************************************************************
380 FlashProgram(unsigned long *pulData, unsigned long ulAddress,
381 unsigned long ulCount)
384 // Check the arguments.
386 ASSERT(!(ulAddress & 3));
387 ASSERT(!(ulCount & 3));
390 // Clear the flash access and error interrupts.
392 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC)
393 = (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
394 FLASH_CTRL_FCMISC_INVDMISC | FLASH_CTRL_FCMISC_PROGMISC);
398 // See if this device has a write buffer.
401 #if HAVE_WRITE_BUFFER
404 // Loop over the words to be programmed.
409 // Set the address of this block of words. for 1 MB
411 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress & ~(0x7F);
414 // Loop over the words in this 32-word block.
416 while(((ulAddress & 0x7C) ||
417 (HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBVAL) == 0)) &&
421 // Write this word into the write buffer.
423 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBN
424 + (ulAddress & 0x7C)) = *pulData++;
430 // Program the contents of the write buffer into flash.
432 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC2)
433 = FLASH_CTRL_FMC2_WRKEY | FLASH_CTRL_FMC2_WRBUF;
436 // Wait until the write buffer has been programmed.
438 while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC2) & FLASH_CTRL_FMC2_WRBUF)
446 // Loop over the words to be programmed.
451 // Program the next word.
453 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
454 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMD) = *pulData;
455 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_WRITE;
458 // Wait until the word has been programmed.
460 while(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) & FLASH_CTRL_FMC_WRITE)
465 // Increment to the next word.
474 // Return an error if an access violation occurred.
477 if(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS) & (FLASH_CTRL_FCRIS_ARIS | FLASH_CTRL_FCRIS_VOLTRIS |
478 FLASH_CTRL_FCRIS_INVDRIS | FLASH_CTRL_FCRIS_PROGRIS))
491 //*****************************************************************************
493 //! Programs flash but does not poll for completion.
495 //! \param pulData is a pointer to the data to be programmed.
496 //! \param ulAddress is the starting address in flash to be programmed. Must
497 //! be a multiple of four.
498 //! \param ulCount is the number of bytes to be programmed. Must be a multiple
501 //! This function will start programming one or more words into the on-chip
502 //! flash and return immediately. The number of words that can be programmed
503 //! in a single call depends the part on which the function is running. For
504 //! parts without support for a flash write buffer, only a single word may be
505 //! programmed on each call to this function (\e ulCount must be 1). If a
506 //! write buffer is present, up to 32 words may be programmed on condition
507 //! that the block being programmed does not straddle a 32 word address
508 //! boundary. For example, wherease 32 words can be programmed if the address
509 //! passed is 0x100 (a multiple of 128 bytes or 32 words), only 31 words could
510 //! be programmed at 0x104 since attempting to write 32 would cross the 32
511 //! word boundary at 0x180.
513 //! Since the flash is programmed one word at a time, the starting address and
514 //! byte count must both be multiples of four. It is up to the caller to
515 //! verify the programmed contents, if such verification is required.
517 //! This function will return immediately after commanding the erase operation.
518 //! Applications making use of the function can determine completion state by
519 //! using a flash interrupt handler or by polling FlashIntStatus.
521 //! \return 0 if the write was started successfully, -1 if there was an error.
523 //*****************************************************************************
525 FlashProgramNonBlocking(unsigned long *pulData, unsigned long ulAddress,
526 unsigned long ulCount)
529 // Check the arguments.
531 ASSERT(!(ulAddress & 3));
532 ASSERT(!(ulCount & 3));
535 // Clear the flash access and error interrupts.
537 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC)
538 = (FLASH_CTRL_FCMISC_AMISC | FLASH_CTRL_FCMISC_VOLTMISC |
539 FLASH_CTRL_FCMISC_INVDMISC | FLASH_CTRL_FCMISC_PROGMISC);
542 // See if this device has a write buffer.
545 #if HAVE_WRITE_BUFFER
548 // Make sure the address/count specified doesn't straddle a 32 word
551 if(((ulAddress + (ulCount - 1)) & ~0x7F) != (ulAddress & ~0x7F))
557 // Loop over the words to be programmed.
562 // Set the address of this block of words.
564 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress & ~(0x7F);
567 // Loop over the words in this 32-word block.
569 while(((ulAddress & 0x7C) || (HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBVAL) == 0)) &&
573 // Write this word into the write buffer.
575 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FWBN + (ulAddress & 0x7C)) = *pulData++;
581 // Program the contents of the write buffer into flash.
583 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC2) = FLASH_CTRL_FMC2_WRKEY | FLASH_CTRL_FMC2_WRBUF;
589 // We don't have a write buffer so we can only write a single word.
597 // Write a single word.
599 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMA) = ulAddress;
600 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMD) = *pulData;
601 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FMC) = FLASH_CTRL_FMC_WRKEY | FLASH_CTRL_FMC_WRITE;
611 //*****************************************************************************
613 //! Gets the protection setting for a block of flash.
615 //! \param ulAddress is the start address of the flash block to be queried.
617 //! This function gets the current protection for the specified 2-kB block
618 //! of flash. Each block can be read/write, read-only, or execute-only.
619 //! Read/write blocks can be read, executed, erased, and programmed. Read-only
620 //! blocks can be read and executed. Execute-only blocks can only be executed;
621 //! processor and debugger data reads are not allowed.
623 //! \return Returns the protection setting for this block. See
624 //! FlashProtectSet() for possible values.
626 //*****************************************************************************
628 FlashProtectGet(unsigned long ulAddress)
630 unsigned long ulFMPRE, ulFMPPE;
631 unsigned long ulBank;
634 // Check the argument.
636 ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
639 // Calculate the Flash Bank from Base Address, and mask off the Bank
640 // from ulAddress for subsequent reference.
642 ulBank = (((ulAddress / FLASH_PROTECT_SIZE) / 32) % 16);
643 ulAddress &= ((FLASH_PROTECT_SIZE * 32) - 1);
646 // Read the appropriate flash protection registers for the specified
649 ulFMPRE = HWREG(g_pulFMPRERegs[ulBank]);
650 ulFMPPE = HWREG(g_pulFMPPERegs[ulBank]);
653 // Check the appropriate protection bits for the block of memory that
654 // is specified by the address.
656 switch((((ulFMPRE >> (ulAddress / FLASH_PROTECT_SIZE)) &
657 FLASH_FMP_BLOCK_0) << 1) |
658 ((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0))
661 // This block is marked as execute only (that is, it can not be erased
662 // or programmed, and the only reads allowed are via the instruction
668 return(FlashExecuteOnly);
672 // This block is marked as read only (that is, it can not be erased or
677 return(FlashReadOnly);
681 // This block is read/write; it can be read, erased, and programmed.
686 return(FlashReadWrite);
691 //*****************************************************************************
693 //! Registers an interrupt handler for the flash interrupt.
695 //! \param pfnHandler is a pointer to the function to be called when the flash
696 //! interrupt occurs.
698 //! This sets the handler to be called when the flash interrupt occurs. The
699 //! flash controller can generate an interrupt when an invalid flash access
700 //! occurs, such as trying to program or erase a read-only block, or trying to
701 //! read from an execute-only block. It can also generate an interrupt when a
702 //! program or erase operation has completed. The interrupt will be
703 //! automatically enabled when the handler is registered.
705 //! \sa IntRegister() for important information about registering interrupt
710 //*****************************************************************************
712 FlashIntRegister(void (*pfnHandler)(void))
715 // Register the interrupt handler, returning an error if an error occurs.
717 IntRegister(INT_FLASH, pfnHandler);
720 // Enable the flash interrupt.
722 IntEnable(INT_FLASH);
725 //*****************************************************************************
727 //! Unregisters the interrupt handler for the flash interrupt.
729 //! This function will clear the handler to be called when the flash interrupt
730 //! occurs. This will also mask off the interrupt in the interrupt controller
731 //! so that the interrupt handler is no longer called.
733 //! \sa IntRegister() for important information about registering interrupt
738 //*****************************************************************************
740 FlashIntUnregister(void)
743 // Disable the interrupt.
745 IntDisable(INT_FLASH);
748 // Unregister the interrupt handler.
750 IntUnregister(INT_FLASH);
753 //*****************************************************************************
755 //! Enables individual flash controller interrupt sources.
757 //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
758 //! Can be any of the \b FLASH_CTRL_PROGRAM or \b FLASH_CTRL_ACCESS values.
760 //! Enables the indicated flash controller interrupt sources. Only the sources
761 //! that are enabled can be reflected to the processor interrupt; disabled
762 //! sources have no effect on the processor.
766 //*****************************************************************************
768 FlashIntEnable(unsigned long ulIntFlags)
771 // Enable the specified interrupts.
773 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCIM) |= ulIntFlags;
776 //*****************************************************************************
778 //! Disables individual flash controller interrupt sources.
780 //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
781 //! Can be any of the \b FLASH_CTRL_PROGRAM or \b FLASH_CTRL_ACCESS values.
783 //! Disables the indicated flash controller interrupt sources. Only the
784 //! sources that are enabled can be reflected to the processor interrupt;
785 //! disabled sources have no effect on the processor.
789 //*****************************************************************************
791 FlashIntDisable(unsigned long ulIntFlags)
794 // Disable the specified interrupts.
796 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCIM) &= ~(ulIntFlags);
799 //*****************************************************************************
801 //! Gets the current interrupt status.
803 //! \param bMasked is false if the raw interrupt status is required and true if
804 //! the masked interrupt status is required.
806 //! This returns the interrupt status for the flash controller. Either the raw
807 //! interrupt status or the status of interrupts that are allowed to reflect to
808 //! the processor can be returned.
810 //! \return The current interrupt status, enumerated as a bit field of
811 //! \b FLASH_CTRL_PROGRAM and \b FLASH_CTRL_ACCESS.
813 //*****************************************************************************
815 FlashIntStatus(tBoolean bMasked)
818 // Return either the interrupt status or the raw interrupt status as
823 return(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC));
827 return(HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCRIS));
831 //*****************************************************************************
833 //! Clears flash controller interrupt sources.
835 //! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
836 //! Can be any of the \b FLASH_CTRL_PROGRAM or \b FLASH_CTRL_AMISC values.
838 //! The specified flash controller interrupt sources are cleared, so that they
839 //! no longer assert. This must be done in the interrupt handler to keep it
840 //! from being called again immediately upon exit.
842 //! \note Because there is a write buffer in the Cortex-M3 processor, it may
843 //! take several clock cycles before the interrupt source is actually cleared.
844 //! Therefore, it is recommended that the interrupt source be cleared early in
845 //! the interrupt handler (as opposed to the very last action) to avoid
846 //! returning from the interrupt handler before the interrupt source is
847 //! actually cleared. Failure to do so may result in the interrupt handler
848 //! being immediately reentered (because the interrupt controller still sees
849 //! the interrupt source asserted).
853 //*****************************************************************************
855 FlashIntClear(unsigned long ulIntFlags)
858 // Clear the flash interrupt.
860 HWREG(FLASH_CONTROL_BASE + FLASH_CTRL_O_FCMISC) = ulIntFlags;
863 //*****************************************************************************
865 // Close the Doxygen group.
868 //*****************************************************************************