| //***************************************************************************** |
| // |
| // am_hal_flash.c |
| //! @file |
| //! |
| //! @brief Functions for performing Flash operations. |
| //! |
| //! @addtogroup flash2 Flash |
| //! @ingroup apollo2hal |
| //! |
| //! IMPORTANT: Interrupts are active during execution of all HAL flash |
| //! functions. If an interrupt occurs during execution of a flash function |
| //! that programs or erases flash or INFO space, errors will occur if the |
| //! interrupt service routine (ISR) is located in on-chip flash. |
| //! If interrupts are expected during execution of a flash function that |
| //! programs or erases either flash or INFO space: |
| //! - Interrupts must be disabled via a critical section handler prior to |
| //! calling the flash function. |
| //! - Alternatively, applicable ISRs must be located in non-flash address space |
| //! (i.e. SRAM, off-chip ROM, etc.). |
| //! |
| //! @{ |
| // |
| //***************************************************************************** |
| |
| //***************************************************************************** |
| // |
| // Copyright (c) 2017, Ambiq Micro |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright |
| // notice, this list of conditions and the following disclaimer in the |
| // documentation and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from this |
| // software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| // POSSIBILITY OF SUCH DAMAGE. |
| // |
| // This is part of revision v1.2.10-2-gea660ad-hotfix2 of the AmbiqSuite Development Package. |
| // |
| //***************************************************************************** |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include "am_mcu_apollo.h" |
| |
| // |
| // Look-up table |
| // |
| g_am_hal_flash_t g_am_hal_flash = |
| { |
| // |
| // The basics. |
| // |
| // flash_mass_erase() |
| ((int (*) (uint32_t, uint32_t)) 0x0800004d), |
| // flash_page_erase() |
| ((int (*) (uint32_t, uint32_t, uint32_t)) 0x08000051), |
| // flash_program_main() |
| ((int (*) (uint32_t, uint32_t *, uint32_t *, uint32_t)) 0x08000055), |
| // flash_program_info() |
| ((int (*) (uint32_t, uint32_t, uint32_t *, uint32_t, uint32_t)) 0x08000059), |
| |
| // |
| // Non-blocking variants, but be careful these are not interrupt safe so |
| // mask interrupts while these very long operations proceed. |
| // |
| // flash_mass_erase_nb() |
| ((int (*)(uint32_t, uint32_t)) 0x0800006d), |
| // flash_page_erase_nb() |
| ((int (*)(uint32_t, uint32_t, uint32_t)) 0x08000071), |
| // flash_nb_operation_complete() |
| ((bool (*)(void)) 0x0800007d), |
| |
| // |
| // Essentially these are recovery options. |
| // |
| // flash_erase_info() |
| ((int (*)(uint32_t, uint32_t)) 0x08000081), |
| // flash_erase_main_plus_info() |
| ((int (*)(uint32_t, uint32_t)) 0x08000089), |
| // flash_erase_main_plus_info_both_instances() |
| ((int (*)(uint32_t)) 0x08000091), |
| // flash_recovery() |
| ((void (*)(uint32_t)) 0x08000099), |
| |
| // |
| // Useful utilities. |
| // |
| // flash_util_read_word() |
| ((uint32_t (*)(uint32_t*)) 0x08000075), |
| // flash_util_write_word() |
| ((void (*)(uint32_t*, uint32_t)) 0x08000079), |
| // delay_cycles() |
| ((void (*)(uint32_t)) 0x0800009d), |
| |
| // |
| // The following functions pointers must never be called from user |
| // programs. They are here primarily to document these entry points |
| // which are usable from a debugger or debugger script. |
| // |
| // flash_program_main_sram() |
| ((void (*) (void)) 0x0800005d), |
| // flash_program_info_sram() |
| ((void (*) (void)) 0x08000061), |
| // flash_erase_main_pages_sram() |
| ((void (*) (void)) 0x08000065), |
| // flash_mass_erase_sram() |
| ((void (*) (void)) 0x08000069), |
| // flash_erase_info_sram() |
| ((void (*)(void)) 0x08000085), |
| // flash_erase_main_plus_info_sram() |
| ((void (*)(void)) 0x0800008d) |
| }; |
| |
| //***************************************************************************** |
| // |
| //! @brief This function performs a mass erase on a flash instance. |
| //! |
| //! @param ui32Value - The flash program key. |
| //! @param ui32FlashInst - The flash instance to erase. |
| //! |
| //! This function will erase the desired instance of flash. |
| //! |
| //! @note For Apollo2, each flash instance contains a maximum of 512KB. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_mass_erase(uint32_t ui32Value, uint32_t ui32FlashInst) |
| { |
| return g_am_hal_flash.flash_mass_erase(ui32Value, ui32FlashInst); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function performs a page erase on a flash instance. |
| //! |
| //! @param ui32Value - The flash program key. |
| //! @param ui32FlashInst - The flash instance to reference the page number with. |
| //! @param ui32PageNum - The flash page relative to the specified instance. |
| //! |
| //! This function will erase the desired flash page in the desired instance of |
| //! flash. |
| //! |
| //! @note For Apollo2, each flash page is 8KB (or AM_HAL_FLASH_PAGE_SIZE). |
| //! Each flash instance contains a maximum of 64 pages (or |
| //! AM_HAL_FLASH_INSTANCE_PAGES). |
| //! |
| //! @note When given an absolute flash address, a couple of helpful macros can |
| //! be utilized when calling this function. |
| //! For example: |
| //! am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY, |
| //! AM_HAL_FLASH_ADDR2INST(ui32Addr), |
| //! AM_HAL_FLASH_ADDR2PAGE(ui32Addr) ); |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_page_erase(uint32_t ui32Value, uint32_t ui32FlashInst, |
| uint32_t ui32PageNum) |
| { |
| return g_am_hal_flash.flash_page_erase(ui32Value, |
| ui32FlashInst, |
| ui32PageNum); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This programs up to N words of the Main array on one flash instance. |
| //! |
| //! @param ui32Value - The programming key, AM_HAL_FLASH_PROGRAM_KEY. |
| //! @param pui32Src - Pointer to word aligned array of data to program into |
| //! the flash instance. |
| //! @param pui32Dst - Pointer to the word aligned flash location where |
| //! programming of the flash instance is to begin. |
| //! @param ui32NumWords - The number of words to be programmed. |
| //! |
| //! This function will program multiple words in main flash. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_program_main(uint32_t ui32Value, uint32_t *pui32Src, |
| uint32_t *pui32Dst, uint32_t ui32NumWords) |
| { |
| return g_am_hal_flash.flash_program_main(ui32Value, pui32Src, |
| pui32Dst, ui32NumWords); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function programs multiple words in the customer INFO space. |
| //! |
| //! @param ui32Value - The customer INFO space key. |
| //! @param ui32InfoInst - The INFO space instance, 0 or 1. |
| //! @param *pui32Src - Pointer to word aligned array of data to program into |
| //! the customer INFO space. |
| //! @param ui32Offset - Word offset into customer INFO space (offset of 0 is |
| //! the first word, 1 is second word, etc.). |
| //! @param ui32NumWords - The number of words to be programmed, must not |
| //! exceed AM_HAL_FLASH_INFO_SIZE/4. |
| //! |
| //! This function will program multiple words in the customer INFO space. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_program_info(uint32_t ui32Value, uint32_t ui32InfoInst, |
| uint32_t *pui32Src, uint32_t ui32Offset, |
| uint32_t ui32NumWords) |
| { |
| return g_am_hal_flash.flash_program_info(ui32Value, 0, pui32Src, |
| ui32Offset, ui32NumWords); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function erases an instance of the customer INFO space. |
| //! |
| //! @param ui32ProgramKey - The customer INFO space programming key |
| //! (AM_HAL_FLASH_PROGRAM_KEY). |
| //! @param ui32Inst - The flash instance, either 0 or 1. |
| //! |
| //! This function will erase the the customer INFO space of the specified |
| //! instance. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_erase_info(uint32_t ui32ProgramKey, |
| uint32_t ui32Inst) |
| { |
| return g_am_hal_flash.flash_erase_info(ui32ProgramKey, ui32Inst); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function erases the main instance + the customer INFO space. |
| //! |
| //! @param ui32ProgramKey - The customer INFO space key. |
| //! @param ui32Inst - The flash instance, either 0 or 1. |
| //! |
| //! This function will erase the main flash + the customer INFO space of the |
| //! specified instance. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_erase_main_plus_info(uint32_t ui32ProgramKey, |
| uint32_t ui32Inst) |
| { |
| return g_am_hal_flash.flash_erase_main_plus_info(ui32ProgramKey, |
| ui32Inst); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function erases the main flash + the customer INFO space. |
| //! |
| //! @param ui32ProgramKey - The customer INFO space key. |
| //! |
| //! This function will erase both instances the main flash + the |
| //! customer INFO space. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return 0 for success, non-zero for failure. |
| // |
| //***************************************************************************** |
| int |
| am_hal_flash_erase_main_plus_info_both_instances(uint32_t ui32ProgramKey) |
| { |
| return g_am_hal_flash.flash_erase_main_plus_info_both_instances( |
| ui32ProgramKey); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function erases both main flash instances + both customer INFO |
| //! space instances. |
| //! |
| //! @param ui32RecoveryKey - The recovery key. |
| //! |
| //! This function erases both main instances and both customer INFOinstances |
| //! even if the customer INFO space is programmed to not be erasable. This |
| //! function completely erases the flash main and info instances and wipes the |
| //! SRAM. Upon completion of the erasure operations, it does a POI (power on |
| //! initialization) reset. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Never Returns!!! |
| // |
| //***************************************************************************** |
| void |
| am_hal_flash_recovery(uint32_t ui32RecoveryKey) |
| { |
| g_am_hal_flash.flash_recovery(ui32RecoveryKey); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Return ui32 value obtained from anywhere in D Code or System Bus |
| //! |
| //! @param ui32Address - return the value corresponding to this location. |
| //! |
| //! Use this function to read a value from various peripheral locations |
| //! that must be read from code running external to flash. |
| //! |
| //! @return the value found |
| // |
| //***************************************************************************** |
| uint32_t |
| am_hal_flash_load_ui32(uint32_t ui32Address) |
| { |
| return g_am_hal_flash.flash_util_read_word((uint32_t*)ui32Address); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Use the bootrom to write to a location in SRAM or the system bus. |
| //! |
| //! @param ui32Address - Store the data value corresponding to this location. |
| //! @param ui32Data - 32-bit Data to be stored. |
| //! |
| //! Use this function to store a value to various peripheral or SRAM locations |
| //! that can not be touched from code running in SRAM or FLASH. There is no |
| //! known need for this function in Apollo2 at this time. |
| //! |
| //! @return None. |
| // |
| //***************************************************************************** |
| void |
| am_hal_flash_store_ui32(uint32_t ui32Address, uint32_t ui32Data) |
| { |
| g_am_hal_flash.flash_util_write_word((uint32_t*)ui32Address, |
| ui32Data); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Use the bootrom to implement a spin loop. |
| //! |
| //! @param ui32Iterations - Number of iterations to delay. |
| //! |
| //! Use this function to implement a CPU busy waiting spin loop without cache |
| //! or delay uncertainties. |
| //! |
| //! Note that the ROM-based function executes at 3 cycles per iteration plus |
| //! the regular function call, entry, and exit overhead. |
| //! The call and return overhead, including the call to this function, is |
| //! somewhere in the neighborhood of 14 cycles, or 4.7 iterations. |
| //! |
| //! Example: |
| //! - MCU operating at 48MHz -> 20.83 ns / cycle |
| //! - Therefore each iteration (once inside the bootrom function) will consume |
| //! 62.5ns. |
| //! - The total overhead (assuming 14 cycles) is 292ns. |
| //! - For ui32Iterations=28: Total delay time = 0.292 + (0.0625 * 28) = 2.04us. |
| //! |
| //! The FLASH_CYCLES_US(n) macro can be used with am_hal_flash_delay() to |
| //! get an approximate microsecond delay. |
| //! e.g. For a 2us delay, use: |
| //! am_hal_flash_delay( FLASH_CYCLES_US(2) ); |
| //! |
| //! @note Interrupts are active during execution of this function. Therefore, |
| //! any interrupt taken will affect the delay timing. |
| //! |
| //! @return None. |
| // |
| //***************************************************************************** |
| void |
| am_hal_flash_delay(uint32_t ui32Iterations) |
| { |
| g_am_hal_flash.delay_cycles(ui32Iterations); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Static Helper Function to check customer info valid bits erasure. |
| //! |
| //! Use this function to test the state of the 128 valid bits at the beginning |
| //! of customer info space. If these are all erased then return true. |
| //! |
| //! @return true if the customer info bits are currently erased. |
| // |
| //***************************************************************************** |
| static bool |
| customer_info_signature_erased(void) |
| { |
| uint32_t *pui32Signature = (uint32_t *) AM_HAL_FLASH_INFO_ADDR; |
| |
| return ( (pui32Signature[3] == 0xFFFFFFFF) && |
| (pui32Signature[2] == 0xFFFFFFFF) && |
| (pui32Signature[1] == 0xFFFFFFFF) && |
| (pui32Signature[0] == 0xFFFFFFFF) ) ? true : false; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Static Helper Function to set customer info valid bits |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space. If these bits are not set correctly then the |
| //! customer protection bits in the INFO space will not be honored by the |
| //! hardware. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| static int |
| customer_info_signature_set(void) |
| { |
| uint32_t ui32Valid[4]; |
| int iRC; |
| |
| // |
| // If they are already set then we are done. |
| // |
| if ( am_hal_flash_customer_info_signature_check() ) |
| { |
| return 0; |
| } |
| |
| // |
| // If they are not erased at this point we have an error. |
| // |
| if ( !customer_info_signature_erased() ) |
| { |
| return (2 << 16); |
| } |
| |
| // |
| // OK they need to be set so do it. |
| // |
| ui32Valid[3] = AM_HAL_FLASH_INFO_SIGNATURE3; |
| ui32Valid[2] = AM_HAL_FLASH_INFO_SIGNATURE2; |
| ui32Valid[1] = AM_HAL_FLASH_INFO_SIGNATURE1; |
| ui32Valid[0] = AM_HAL_FLASH_INFO_SIGNATURE0; |
| |
| iRC = g_am_hal_flash.flash_program_info(AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| ui32Valid, // source data |
| 0, // offset |
| 4); // number of words |
| return iRC | ((iRC) ? (1 << 16) : 0); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Check that the customer info bits are valid. |
| //! |
| //! Use this function to test the state of the 128 valid bits at the beginning |
| //! of customer info space. If these are not set correctly then the customer |
| //! protection bits in the INFO space will not be honored by the hardware. |
| //! |
| //! @return true if valid. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_customer_info_signature_check(void) |
| { |
| uint32_t *pui32Signature = (uint32_t *)AM_HAL_FLASH_INFO_ADDR; |
| |
| return ( (pui32Signature[3] == AM_HAL_FLASH_INFO_SIGNATURE3) && |
| (pui32Signature[2] == AM_HAL_FLASH_INFO_SIGNATURE2) && |
| (pui32Signature[1] == AM_HAL_FLASH_INFO_SIGNATURE1) && |
| (pui32Signature[0] == AM_HAL_FLASH_INFO_SIGNATURE0) ); |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief INFO signature set. |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_info_signature_set(void) |
| { |
| // |
| // Check and set signature. |
| // |
| return customer_info_signature_set() ? false : true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Disable FLASH INFO space. |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. Then disable FLASH erasure. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_info_erase_disable(void) |
| { |
| int iRC; |
| uint32_t ui32SecurityValue; |
| |
| // |
| // Security protection only works if the signature data is correct. |
| // |
| iRC = customer_info_signature_set(); |
| if ( iRC ) |
| { |
| return iRC; |
| } |
| |
| // |
| // Clear bit in INFO space to disable erasure. |
| // |
| ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| ~AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M; |
| |
| // |
| // Now write the word to the flash INFO space. |
| // |
| return g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32SecurityValue, // source data |
| AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset |
| 1 ); // number of words |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Check for Disabled FLASH INFO space. |
| //! |
| //! Use this function to determine whether FLASH INFO erasure is disabled. |
| //! |
| //! @return true if FLASH INFO erase is disabled, otherwise false. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_info_erase_disable_check(void) |
| { |
| // |
| // If they are erased at this point then SRAM wipe can't be enabled. |
| // |
| if ( customer_info_signature_erased() ) |
| { |
| return false; |
| } |
| |
| // |
| // If they are not valid at this point then SRAM wipe can't be enabled. |
| // |
| if ( !am_hal_flash_customer_info_signature_check() ) |
| { |
| return false; |
| } |
| |
| // |
| // Looking good so far, now check the SRAM WIPE bit. |
| // |
| return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M ? false : true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Mask off 1 to 4 quadrants of FLASH INFO space for programming. |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. Then and the mask bits with the INFO |
| //! space programming disable bits. |
| //! |
| //! @param ui32Mask - A mask of the 4 quadrants of info space where |
| //! bit0 = First quadrant (first 2KB). |
| //! bit1 = Second quadrant (second 2KB). |
| //! bit2 = Third quadrant (third 2KB). |
| //! bit3 = Fourth quadrant (fourth 2KB). |
| //! |
| //! @note This function disables only, any quadrant already disabled is not |
| //! reenabled. That is, any ui32Mask bits specified as 0 are essentially nops. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_info_program_disable(uint32_t ui32Mask) |
| { |
| int iRC; |
| uint32_t ui32SecurityValue; |
| |
| // |
| // Security protection only works if the signature data is correct. |
| // |
| iRC = customer_info_signature_set(); |
| if ( iRC ) |
| { |
| return iRC; |
| } |
| |
| // |
| // Make sure we have a valid mask and get the mask into the correct position. |
| // |
| ui32Mask <<= AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S; |
| ui32Mask &= AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M; |
| |
| // |
| // The security bit set to 1 enables programming, 0 disables programming. |
| // |
| ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & ~ui32Mask; |
| |
| // |
| // Now write the word to the flash INFO space. |
| // |
| return g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32SecurityValue, // source data |
| AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset |
| 1 ); // number of words |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Return a mask specifying which quadrants of customer INFO space have |
| //! been disabled for programming. |
| //! |
| //! Use this function to determine whether programming of customer INFO space |
| //! has been disabled. |
| //! |
| //! @return A 4-bit mask of the disabled quadrants. |
| //! 0xFFFFFFFF indicates an error. |
| //! 0x0 indicates all customer INFO space programming is enabled. |
| //! 0xF indicates all customer INFO space programming is disabled. |
| //! bit0 indicates the first customer INFO space is disabled for programming. |
| //! bit1 indicates the second customer INFO space is disabled for programming. |
| //! bit2 indicates the third customer INFO space is disabled for programming. |
| //! bit3 indicates the fourth customer INFO space is disabled for programming. |
| // |
| //***************************************************************************** |
| uint32_t |
| am_hal_flash_info_program_disable_get(void) |
| { |
| // |
| // If they are erased at this point then SRAM wipe can't be enabled. |
| // |
| if ( customer_info_signature_erased() ) |
| { |
| return 0xFFFFFFFF; |
| } |
| |
| // |
| // If not valid at this point, then INFO programming can't be enabled. |
| // |
| if ( !am_hal_flash_customer_info_signature_check() ) |
| { |
| return 0xFFFFFFFF; |
| } |
| |
| // |
| // Looking good so far, now return a mask of the disabled bits. |
| // |
| return ((AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M) ^ |
| AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M) >> |
| AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Enable FLASH debugger protection (FLASH gets wiped if a debugger is |
| //! connected). |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. Then set the FLASH wipe bit to zero. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_wipe_flash_enable(void) |
| { |
| int iRC; |
| uint32_t ui32SecurityValue; |
| |
| // |
| // Security protection only works if the signature data is correct. |
| // |
| iRC = customer_info_signature_set(); |
| if ( iRC ) |
| { |
| return iRC; |
| } |
| |
| // |
| // Clear the FLASH Wipe bit. |
| // |
| ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| ~AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M; |
| |
| // |
| // Now write the word to the flash INFO space. |
| // |
| return g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32SecurityValue, // source data |
| AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset |
| 1 ); // number of words |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief check for FLASH wipe protection enabled. |
| //! |
| //! Use this function to determine if FLASH wipe protection is enabled. |
| //! |
| //! @return true if FLASH wipe protection is enabled, otherwise false. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_wipe_flash_enable_check(void) |
| { |
| // |
| // If they are erased at this point then flash wipe can't be enabled. |
| // |
| if ( customer_info_signature_erased() ) |
| { |
| return false; |
| } |
| |
| // |
| // If they are not valid at this point then flash wipe can't be enabled. |
| // |
| if ( !am_hal_flash_customer_info_signature_check() ) |
| { |
| return false; |
| } |
| |
| // |
| // Looking good so far, now check the Flash WIPE bit. |
| // |
| return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M ? false : true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Enable SRAM protection so SRAM gets wiped if a debgger is connected. |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. Then set the SRAM wipe bit to zero. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_wipe_sram_enable(void) |
| { |
| int iRC; |
| uint32_t ui32SecurityValue; |
| |
| // |
| // Security protection only works if the signature data is correct. |
| // |
| iRC = customer_info_signature_set(); |
| if ( iRC ) |
| { |
| return iRC; |
| } |
| |
| // |
| // Clear the SRAM Wipe bit. |
| // |
| ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| ~AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M; |
| |
| // |
| // Now write the word to the flash INFO space. |
| // |
| return g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32SecurityValue, // source data |
| AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset |
| 1 ); // number of words |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief check for SRAM protection enabled. |
| //! |
| //! Use this function to determine if SRAM protection is enabled. |
| //! |
| //! @return true if SRAM wipe protection is enabled, otherwise false. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_wipe_sram_enable_check(void) |
| { |
| // |
| // If they are erased at this point then SRAM wipe can't be enabled. |
| // |
| if ( customer_info_signature_erased() ) |
| { |
| return false; |
| } |
| |
| // |
| // If they are not vale at this point then SRAM wipe can't be enabled. |
| // |
| if ( !am_hal_flash_customer_info_signature_check() ) |
| { |
| return false; |
| } |
| |
| // |
| // Looking good so far, now check the SRAM WIPE bit. |
| // |
| return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M ? false : true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Disable Output from ITM/SWO. |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. Set the SWO disable bit to zero. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_swo_disable(void) |
| { |
| int iRC; |
| uint32_t ui32SecurityValue; |
| |
| // |
| // Security protection only works if the signature data is correct. |
| // |
| iRC = customer_info_signature_set(); |
| if ( iRC ) |
| { |
| return iRC; |
| } |
| |
| // |
| // Clear the SWO bit. |
| // |
| ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| ~AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M; |
| |
| // |
| // Now write the word to the flash INFO space. |
| // |
| return g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32SecurityValue, // source data |
| AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset |
| 1 ); // number of words |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief check for SWO disabled. |
| //! |
| //! Use this function to determine if the SWO is disabled. |
| //! |
| //! @return true if the ITM/SWO is disabled, otherwise false. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_swo_disable_check(void) |
| { |
| // |
| // If they are erased at this point then SRAM wipe can't be enabled. |
| // |
| if ( customer_info_signature_erased() ) |
| { |
| return false; |
| } |
| |
| // |
| // If they are not vale at this point then SRAM wipe can't be enabled. |
| // |
| if ( !am_hal_flash_customer_info_signature_check() ) |
| { |
| return false; |
| } |
| |
| // |
| // Looking good so far, now check the SWO bit. |
| // |
| return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M ? false : true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief Disable Connections from a debugger on the SWD interface. |
| //! |
| //! Use this function to set the state of the 128 valid bits at the beginning |
| //! of customer info space, if needed. Set the debugger disable bit to zero. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return Zero for success. Non-Zero for errors. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_debugger_disable(void) |
| { |
| int iRC; |
| uint32_t ui32SecurityValue; |
| |
| // |
| // Security protection only works if the signature data is correct. |
| // |
| iRC = customer_info_signature_set(); |
| if ( iRC ) |
| { |
| return iRC; |
| } |
| |
| // |
| // Clear the DEBUGGER bit. |
| // |
| ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| ~AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M; |
| |
| // |
| // Now write the word to the flash INFO space. |
| // |
| return g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32SecurityValue, // source data |
| AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset |
| 1 ); // number of words |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief check for debugger disabled. |
| //! |
| //! Use this function to determine if the debugger is disabled. |
| //! |
| //! @return true if the debugger is disabled, otherwise false. |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_debugger_disable_check(void) |
| { |
| // |
| // If they are erased at this point then SRAM wipe can't be enabled. |
| // |
| if ( customer_info_signature_erased() ) |
| { |
| return false; |
| } |
| |
| // |
| // If they are not vale at this point then SRAM wipe can't be enabled. |
| // |
| if ( !am_hal_flash_customer_info_signature_check() ) |
| { |
| return false; |
| } |
| |
| // |
| // Looking good so far, now check the debugger disable bit. |
| // |
| return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & |
| AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M ? false : true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This static helper function generates a 64-bit protection mask. |
| //! |
| //! @param pui32StartAddress - Starting address in flash to begin protection. |
| //! @param pui32StopAddress - Ending address in flash to stop protection. |
| //! |
| //! This function computes a chunk map for the protection range. |
| //! |
| //! @return Inverse of the actual chunk mask. That is, chunks to be protected |
| //! are represented as 0 in the returned mask, while chunks to be left alone |
| //! are represented as 1. This value can therefore be directly ANDed with the |
| //! existing bits in INFO space. |
| //! Note that -1 is returned if input parameters are invalid - this return |
| //! value would indicate that no chunks are to be protected. |
| //! |
| // |
| //***************************************************************************** |
| static uint64_t |
| generate_chunk_mask(uint32_t *pui32StartAddress, uint32_t *pui32StopAddress) |
| { |
| uint32_t ui32ChunkStart, ui32ChunkStop; |
| uint32_t ui32Width; |
| uint64_t ui64Mask; |
| |
| // |
| // Validate the address input parameters |
| // |
| if ( (pui32StartAddress > pui32StopAddress) || |
| (pui32StopAddress > (uint32_t*)AM_HAL_FLASH_LARGEST_VALID_ADDR) ) |
| { |
| // |
| // Argument error, return value to leave all chunks unprotected. |
| // |
| return 0xFFFFFFFFFFFFFFFF; |
| } |
| |
| // |
| // Extract chunk related information |
| // |
| ui32ChunkStart = AM_HAL_FLASH_INFO_ADDR2CHUNK((uint32_t)pui32StartAddress); |
| ui32ChunkStop = AM_HAL_FLASH_INFO_ADDR2CHUNK((uint32_t)pui32StopAddress); |
| ui32Width = ui32ChunkStop - ui32ChunkStart + 1; |
| |
| if ( ui32Width == 64 ) |
| { |
| ui64Mask = (uint64_t)0xFFFFFFFFFFFFFFFFLLU; |
| } |
| else |
| { |
| ui64Mask = ( ((uint64_t)0x0000000000000001) << ui32Width) - 1; |
| ui64Mask <<= ui32ChunkStart; |
| } |
| |
| // |
| // OK now return the chunk mask (inverted). |
| // |
| return ~ui64Mask; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function sets copy protection for a range of flash chunks. |
| //! |
| //! @param pui32StartAddress - Starting address in flash to begin protection. |
| //! @param pui32StopAddress - Ending address in flash to stop protection. |
| //! |
| //! This function will set copy protection bits for a range of flash chunks |
| //! |
| //! @note Each flash chunk contains 16KBytes and corresponds to one bit in |
| //! the protection register. Set the bit to zero to enable protection. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return |
| //! 0 for success. |
| //! 0x400000 if the protection bits were already programmed (mask the return |
| //! value with 0x3FFFFF to ignore this case and treat as success). |
| //! Otherwise, non-zero for failure. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_copy_protect_set(uint32_t *pui32StartAddress, |
| uint32_t *pui32StopAddress) |
| { |
| int iRC; |
| bool bModified = false; |
| uint64_t ui64Mask; |
| uint32_t ui32Work; |
| uint32_t ui32Protection[2]; |
| uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_COPYPROT_ADDR; |
| |
| // |
| // Extract chunk mask from parameters. |
| // Also checks parameter validity (returns -1 if bad parameters). |
| // |
| ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); |
| if ( ~ui64Mask == 0x0 ) |
| { |
| return 0x100000; |
| } |
| |
| // |
| // Go get the current settings for copy protection. |
| // |
| ui32Protection[0] = pui32Protection[0]; |
| ui32Protection[1] = pui32Protection[1]; |
| |
| // |
| // AND mask off the necessary protection bits in the lower word. |
| // |
| ui32Work = (uint32_t)ui64Mask; |
| if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[0] ) ) |
| { |
| bModified = true; |
| ui32Protection[0] &= ui32Work; |
| iRC = g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32Protection[0], // source data |
| (AM_HAL_FLASH_INFO_COPYPROT_O / 4) + 0, // word offset |
| 1 ); // number of words |
| |
| if ( iRC ) |
| { |
| return iRC | 0x10000; |
| } |
| } |
| |
| // |
| // AND mask off the necessary protection bits in the upper word. |
| // |
| ui32Work = (uint32_t)(ui64Mask >> 32); |
| if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[1] ) ) |
| { |
| bModified = true; |
| ui32Protection[1] &= ui32Work; |
| iRC = g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32Protection[1], // source data |
| (AM_HAL_FLASH_INFO_COPYPROT_O / 4) + 1, // word offset |
| 1 ); // number of words |
| |
| if ( iRC ) |
| { |
| return iRC | 0x20000; |
| } |
| } |
| |
| if ( bModified ) |
| { |
| return 0; |
| } |
| else |
| { |
| return 0x400000; |
| } |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function checks copy protection for a range of flash chunks. |
| //! |
| //! @param pui32StartAddress - Starting address in flash. |
| //! @param pui32StopAddress - Ending address in flash. |
| //! |
| //! This function will check copy protection bits for a range of flash chunks |
| //! it expects all chunks in the range to be protected. |
| //! |
| //! @note Each flash chunk contains 16KBytes and corresponds to one bit in |
| //! the protection register. Set the bit to zero to enable protection. |
| //! |
| //! @return false for at least one chunk in the covered range is not protected, |
| //! and true if all chunks in the covered range are protected. |
| //! |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_copy_protect_check(uint32_t *pui32StartAddress, |
| uint32_t *pui32StopAddress) |
| { |
| uint64_t ui64Mask; |
| uint32_t ui32Work; |
| uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_COPYPROT_ADDR; |
| |
| // |
| // Extract chunk mask from parameters. |
| // Also checks parameter validity (returns -1 if bad parameters). |
| // |
| ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); |
| if ( ~ui64Mask == 0x0 ) |
| { |
| return false; |
| } |
| |
| // |
| // Now check the lower word of protection bits. |
| // |
| ui32Work = (uint32_t)ui64Mask; |
| if ( ~ui32Work & pui32Protection[0] ) |
| { |
| return false; |
| } |
| |
| // |
| // Now check the lower word of protection bits. |
| // |
| ui32Work = (uint32_t)(ui64Mask >> 32); |
| if ( ~ui32Work & pui32Protection[1] ) |
| { |
| return false; |
| } |
| |
| // |
| // If we get here, there are no unprotected chunks within specified range. |
| // |
| return true; |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function sets write protection for a range of flash chunks. |
| //! |
| //! @param pui32StartAddress - Starting address in flash to begin protection. |
| //! @param pui32StopAddress - Ending address in flash to stop protection. |
| //! |
| //! This function will set write protection bits for a range of flash chunks |
| //! |
| //! @note Each flash chunk contains 16KBytes and corresponds to one bit in |
| //! the protection register. Set the bit to zero to enable protection. |
| //! |
| //! @note Interrupts are active during execution of this function. Any interrupt |
| //! taken could cause execution errors. Please see the IMPORTANT note under |
| //! Detailed Description above for more details. |
| //! |
| //! @return |
| //! 0 for success. |
| //! 0x400000 if the protection bits were already programmed (mask the return |
| //! value with 0x3FFFFF to ignore this case and treat as success). |
| //! Otherwise, non-zero for failure. |
| // |
| //***************************************************************************** |
| int32_t |
| am_hal_flash_write_protect_set(uint32_t *pui32StartAddress, |
| uint32_t *pui32StopAddress) |
| { |
| int iRC; |
| bool bModified = false; |
| uint64_t ui64Mask; |
| uint32_t ui32Work; |
| uint32_t ui32Protection[2]; |
| uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_WRITPROT_ADDR; |
| |
| // |
| // Extract chunk mask from parameters. |
| // Also checks parameter validity (returns -1 if bad parameters). |
| // |
| ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); |
| if ( ~ui64Mask == 0x0 ) |
| { |
| return 0x100000; |
| } |
| |
| // |
| // Go get the current settings for copy protection. |
| // |
| ui32Protection[0] = pui32Protection[0]; |
| ui32Protection[1] = pui32Protection[1]; |
| |
| // |
| // AND mask off the necessary protection bits in the lower word. |
| // |
| ui32Work = (uint32_t)ui64Mask; |
| if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[0] ) ) |
| { |
| bModified = true; |
| ui32Protection[0] &= ui32Work; |
| iRC = g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32Protection[0], // source data |
| (AM_HAL_FLASH_INFO_WRITPROT_O / 4) + 0, // word offset |
| 1 ); // number of words |
| |
| if ( iRC ) |
| { |
| return iRC | 0x10000; |
| } |
| } |
| |
| // |
| // AND mask off the necessary protection bits in the upper word. |
| // |
| ui32Work = (uint32_t)(ui64Mask >> 32); |
| if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[1] ) ) |
| { |
| bModified = true; |
| ui32Protection[1] &= ui32Work; |
| iRC = g_am_hal_flash.flash_program_info( |
| AM_HAL_FLASH_PROGRAM_KEY, |
| 0, // instance |
| &ui32Protection[1], // source data |
| (AM_HAL_FLASH_INFO_WRITPROT_O / 4) + 1, // word offset |
| 1 ); // number of words |
| |
| if ( iRC ) |
| { |
| return iRC | 0x20000; |
| } |
| } |
| |
| if ( bModified ) |
| { |
| return 0; |
| } |
| else |
| { |
| return 0x400000; |
| } |
| } |
| |
| //***************************************************************************** |
| // |
| //! @brief This function checks write protection for a range of flash chunks. |
| //! |
| //! @param pui32StartAddress - Starting address in flash. |
| //! @param pui32StopAddress - Ending address in flash. |
| //! |
| //! This function will check write protection bits for a range of flash chunks |
| //! it expects all chunks in the range to be protected. |
| //! |
| //! @note Each flash chunk contains 16KBytes and corresponds to one bit in |
| //! the protection register. Set the bit to zero to enable protection. |
| //! |
| //! @return false for at least one chunk in the covered range is not protected, |
| //! and true if all chunks in the covered range are protected. |
| //! |
| // |
| //***************************************************************************** |
| bool |
| am_hal_flash_write_protect_check(uint32_t *pui32StartAddress, |
| uint32_t *pui32StopAddress) |
| { |
| uint64_t ui64Mask; |
| uint32_t ui32Work; |
| uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_WRITPROT_ADDR; |
| |
| // |
| // Extract chunk mask from parameters. |
| // Also checks parameter validity (returns -1 if bad parameters). |
| // |
| ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); |
| if ( ~ui64Mask == 0x0 ) |
| { |
| return false; |
| } |
| |
| // |
| // Now check the lower word of protection bits. |
| // |
| ui32Work = (uint32_t)ui64Mask; |
| if ( ~ui32Work & pui32Protection[0] ) |
| { |
| return false; |
| } |
| |
| // |
| // Now check the lower word of protection bits. |
| // |
| ui32Work = (uint32_t)(ui64Mask >> 32); |
| if ( ~ui32Work & pui32Protection[1] ) |
| { |
| return false; |
| } |
| |
| // |
| // If we get here, there are no unprotected chunks within specified range. |
| // |
| return true; |
| } |
| |
| //***************************************************************************** |
| // |
| // End Doxygen group. |
| //! @} |
| // |
| //***************************************************************************** |