|
- /*!
- * \file sysIrqHandlers.c
- *
- * \brief Default IRQ handlers
- *
- * \copyright Revised BSD License, see section \ref LICENSE.
- *
- * \code
- * ______ _
- * / _____) _ | |
- * ( (____ _____ ____ _| |_ _____ ____| |__
- * \____ \| ___ | (_ _) ___ |/ ___) _ \
- * _____) ) ____| | | || |_| ____( (___| | | |
- * (______/|_____)_|_|_| \__)_____)\____)_| |_|
- * (C)2013-2017 Semtech
- *
- * \endcode
- *
- * \author Miguel Luis ( Semtech )
- *
- * \author Gregory Cristian ( Semtech )
- */
- #include <stdint.h>
- #include "stm32l4xx.h"
- #include "eeprom_emul.h"
-
- /*!
- * \brief This function handles NMI exception.
- * \param None
- * \retval None
- */
- void NMI_Handler( void )
- {
- uint32_t corruptedflashaddress;
-
- // Check if NMI is due to flash ECCD (error detection)
- if( __HAL_FLASH_GET_FLAG( FLASH_FLAG_ECCD ) )
- {
- // Compute corrupted flash address
- corruptedflashaddress = FLASH_BASE + ( FLASH->ECCR & FLASH_ECCR_ADDR_ECC );
-
- #if defined(FLASH_OPTR_BFB2)
- // Add bank size to corrupteflashaddress if fail bank is bank 2
- if( READ_BIT( FLASH->ECCR, FLASH_ECCR_BK_ECC ) == FLASH_ECCR_BK_ECC )
- {
- corruptedflashaddress += FLASH_BANK_SIZE;
- }
- #endif
-
- // Check if corrupted flash address is in eeprom emulation pages
- if( ( corruptedflashaddress >= START_PAGE_ADDRESS ) || ( corruptedflashaddress <= END_EEPROM_ADDRESS ) )
- {
- /* Delete the corrupted flash address */
- if( EE_DeleteCorruptedFlashAddress( corruptedflashaddress ) == EE_OK )
- {
- // Resume execution if deletion succeeds
- return;
- }
- }
- }
-
- /* Go to infinite loop when NMI occurs in case:
- - ECCD is raised in eeprom emulation flash pages but corrupted flash address deletion fails
- - ECCD is raised out of eeprom emulation flash pages
- - no ECCD is raised */
- while( 1 )
- {
- }
- }
-
- /*!
- * \brief This function handles Hard Fault exception.
- * \param None
- * \retval None
- */
- void HardFault_Handler( void )
- {
- //*************************************************************************
- // When a power down or external reset occurs during a Flash Write operation,
- // the first line at 0x0 may be corrupted at 0x0 (low occurrence).
- // In this case the Flash content is restored.
- // address : flash bank1 base address
- // data : first flash line (64 bits). This variable must be updated after each build.
- // sram2address : sram2 start address to copy and restore first flash page
- //*************************************************************************
- uint32_t address = FLASH_BASE;
- uint64_t data = 0x08002df120001bc0;
- uint32_t sram2address = 0x20030000;
- uint32_t page = 0;
- uint32_t banks = FLASH_BANK_1;
- uint32_t element = 0U;
-
- if( ( *( __IO uint32_t* )address == 0x0 ) && ( *( __IO uint32_t* )( address + 4 ) == 0x0 ) )
- {
- // Authorize the FLASH Registers access
- FLASH->KEYR = FLASH_KEY1;
- FLASH->KEYR = FLASH_KEY2;
-
- // Save first flash page in SRAM2
- for( element = 2; element < FLASH_PAGE_SIZE; element++ )
- {
- *( __IO uint32_t* )( sram2address + ( element * 4 ) ) = *( __IO uint32_t* )( address + ( element * 4 ) );
- }
-
- // Restore the first flash line in SRAM2 to its correct value
- *( __IO uint32_t* )sram2address = ( uint32_t )data;
- *( __IO uint32_t* )( sram2address + 4 ) = ( uint32_t )( data >> 32 );
-
- // Clear FLASH all errors
- __HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_ALL_ERRORS );
-
- // Erase first flash page
- #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
- defined (STM32L496xx) || defined (STM32L4A6xx) || \
- defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
- #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
- if( READ_BIT( FLASH->OPTR, FLASH_OPTR_DBANK ) == RESET )
- {
- CLEAR_BIT( FLASH->CR, FLASH_CR_BKER );
- }
- else
- #endif
- {
- if( ( banks & FLASH_BANK_1 ) != RESET )
- {
- CLEAR_BIT( FLASH->CR, FLASH_CR_BKER );
- }
- else
- {
- SET_BIT( FLASH->CR, FLASH_CR_BKER );
- }
- }
- #endif
-
- // Proceed to erase the page
- MODIFY_REG( FLASH->CR, FLASH_CR_PNB, ( page << POSITION_VAL( FLASH_CR_PNB ) ) );
- SET_BIT( FLASH->CR, FLASH_CR_PER );
- SET_BIT( FLASH->CR, FLASH_CR_STRT );
-
- // Wait for last operation to be completed
- while( __HAL_FLASH_GET_FLAG( FLASH_FLAG_BSY ) ){ }
- // If the erase operation is completed, disable the PER Bit
- CLEAR_BIT( FLASH->CR, ( FLASH_CR_PER | FLASH_CR_PNB ) );
-
- // Restore first flash page in flash from SRAM2
- for( element = 0; element < FLASH_PAGE_SIZE; element++ )
- {
- // Wait for last operation to be completed
- while( __HAL_FLASH_GET_FLAG( FLASH_FLAG_BSY ) ){ }
-
- // Set PG bit
- SET_BIT( FLASH->CR, FLASH_CR_PG );
-
- // Write in flash
- *( __IO uint32_t* )( address + ( element * 4 ) ) = *( __IO uint32_t* )( sram2address + ( element * 4 ) );
- }
-
- // System reset
- NVIC_SystemReset( );
- }
-
- // Go to infinite loop when Hard Fault exception occurs
- while( 1 )
- {
- }
- }
-
- /*!
- * \brief This function handles Memory Manage exception.
- * \param None
- * \retval None
- */
- void MemManage_Handler( void )
- {
- /* Go to infinite loop when Memory Manage exception occurs */
- while ( 1 )
- {
- }
- }
-
- /*!
- * \brief This function handles Bus Fault exception.
- * \param None
- * \retval None
- */
- void BusFault_Handler( void )
- {
- /* Go to infinite loop when Bus Fault exception occurs */
- while ( 1 )
- {
- }
- }
-
- /*!
- * \brief This function handles Usage Fault exception.
- * \param None
- * \retval None
- */
- void UsageFault_Handler( void )
- {
- /* Go to infinite loop when Usage Fault exception occurs */
- while ( 1 )
- {
- }
- }
-
- /*!
- * \brief This function handles Debug Monitor exception.
- * \param None
- * \retval None
- */
- void DebugMon_Handler( void )
- {
- }
-
- /*!
- * \brief This function handles Flash interrupt request.
- * \param None
- * \retval None
- */
- void FLASH_IRQHandler( void )
- {
- HAL_FLASH_IRQHandler();
- }
-
- /*!
- * \brief This function handles PVD interrupt request.
- * \param None
- * \retval None
- */
- void PVD_PVM_IRQHandler( void )
- {
- // Loop inside the handler to prevent the Cortex from using the Flash,
- // allowing the flash interface to finish any ongoing transfer.
- while( __HAL_PWR_GET_FLAG( PWR_FLAG_PVDO ) != RESET )
- {
- }
- }
|