1 /*!
2  * \file      sysIrqHandlers.c
3  *
4  * \brief     Default IRQ handlers
5  *
6  * \copyright Revised BSD License, see section \ref LICENSE.
7  *
8  * \code
9  *                ______                              _
10  *               / _____)             _              | |
11  *              ( (____  _____ ____ _| |_ _____  ____| |__
12  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
13  *               _____) ) ____| | | || |_| ____( (___| | | |
14  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
15  *              (C)2013-2017 Semtech
16  *
17  * \endcode
18  *
19  * \author    Miguel Luis ( Semtech )
20  *
21  * \author    Gregory Cristian ( Semtech )
22  */
23 #include <stdint.h>
24 #include "stm32l4xx.h"
25 #include "eeprom_emul.h"
26 
27 /*!
28  * \brief  This function handles NMI exception.
29  * \param  None
30  * \retval None
31  */
NMI_Handler(void)32 void NMI_Handler( void )
33 {
34     uint32_t corruptedflashaddress;
35 
36     // Check if NMI is due to flash ECCD (error detection)
37     if( __HAL_FLASH_GET_FLAG( FLASH_FLAG_ECCD ) )
38     {
39         // Compute corrupted flash address
40         corruptedflashaddress = FLASH_BASE + ( FLASH->ECCR & FLASH_ECCR_ADDR_ECC );
41 
42 #if defined(FLASH_OPTR_BFB2)
43         // Add bank size to corrupteflashaddress if fail bank is bank 2
44         if( READ_BIT( FLASH->ECCR, FLASH_ECCR_BK_ECC ) == FLASH_ECCR_BK_ECC )
45         {
46             corruptedflashaddress += FLASH_BANK_SIZE;
47         }
48 #endif
49 
50         // Check if corrupted flash address is in eeprom emulation pages
51         if( ( corruptedflashaddress >= START_PAGE_ADDRESS ) || ( corruptedflashaddress <= END_EEPROM_ADDRESS ) )
52         {
53             /* Delete the corrupted flash address */
54             if( EE_DeleteCorruptedFlashAddress( corruptedflashaddress ) == EE_OK )
55             {
56                 // Resume execution if deletion succeeds
57                 return;
58             }
59         }
60     }
61 
62     /* Go to infinite loop when NMI occurs in case:
63     - ECCD is raised in eeprom emulation flash pages but corrupted flash address deletion fails
64     - ECCD is raised out of eeprom emulation flash pages
65     - no ECCD is raised */
66     while( 1 )
67     {
68     }
69 }
70 
71 /*!
72  * \brief  This function handles Hard Fault exception.
73  * \param  None
74  * \retval None
75  */
HardFault_Handler(void)76 void HardFault_Handler( void )
77 {
78     //*************************************************************************
79     // When a power down or external reset occurs during a Flash Write operation,
80     // the first line at 0x0 may be corrupted at 0x0 (low occurrence).
81     // In this case the Flash content is restored.
82     //    address : flash bank1 base address
83     //    data : first flash line (64 bits). This variable must be updated after each build.
84     //    sram2address : sram2 start address to copy and restore first flash page
85     //*************************************************************************
86     uint32_t address = FLASH_BASE;
87     uint64_t data = 0x08002df120001bc0;
88     uint32_t sram2address = 0x20030000;
89     uint32_t page = 0;
90     uint32_t banks = FLASH_BANK_1;
91     uint32_t element = 0U;
92 
93     if( ( *( __IO uint32_t* )address == 0x0 ) && ( *( __IO uint32_t* )( address + 4 ) == 0x0 ) )
94     {
95         // Authorize the FLASH Registers access
96         FLASH->KEYR = FLASH_KEY1;
97         FLASH->KEYR = FLASH_KEY2;
98 
99         // Save first flash page in SRAM2
100         for( element = 2; element < FLASH_PAGE_SIZE; element++ )
101         {
102             *( __IO uint32_t* )( sram2address + ( element * 4 ) ) = *( __IO uint32_t* )( address + ( element * 4 ) );
103         }
104 
105         // Restore the first flash line in SRAM2 to its correct value
106         *( __IO uint32_t* )sram2address = ( uint32_t )data;
107         *( __IO uint32_t* )( sram2address + 4 ) = ( uint32_t )( data >> 32 );
108 
109         // Clear FLASH all errors
110         __HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_ALL_ERRORS );
111 
112         // Erase first flash page
113 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
114     defined (STM32L496xx) || defined (STM32L4A6xx) || \
115     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
116 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
117         if( READ_BIT( FLASH->OPTR, FLASH_OPTR_DBANK ) == RESET )
118         {
119             CLEAR_BIT( FLASH->CR, FLASH_CR_BKER );
120         }
121         else
122 #endif
123         {
124             if( ( banks & FLASH_BANK_1 ) != RESET )
125             {
126                 CLEAR_BIT( FLASH->CR, FLASH_CR_BKER );
127             }
128             else
129             {
130                 SET_BIT( FLASH->CR, FLASH_CR_BKER );
131             }
132         }
133 #endif
134 
135         // Proceed to erase the page
136         MODIFY_REG( FLASH->CR, FLASH_CR_PNB, ( page << POSITION_VAL( FLASH_CR_PNB ) ) );
137         SET_BIT( FLASH->CR, FLASH_CR_PER );
138         SET_BIT( FLASH->CR, FLASH_CR_STRT );
139 
140         // Wait for last operation to be completed
141         while( __HAL_FLASH_GET_FLAG( FLASH_FLAG_BSY ) ){ }
142         // If the erase operation is completed, disable the PER Bit
143         CLEAR_BIT( FLASH->CR, ( FLASH_CR_PER | FLASH_CR_PNB ) );
144 
145         // Restore first flash page in flash from SRAM2
146         for( element = 0; element < FLASH_PAGE_SIZE; element++ )
147         {
148             // Wait for last operation to be completed
149             while( __HAL_FLASH_GET_FLAG( FLASH_FLAG_BSY ) ){ }
150 
151             // Set PG bit
152             SET_BIT( FLASH->CR, FLASH_CR_PG );
153 
154             // Write in flash
155             *( __IO uint32_t* )( address + ( element * 4 ) ) = *( __IO uint32_t* )( sram2address + ( element * 4 ) );
156         }
157 
158         // System reset
159         NVIC_SystemReset( );
160     }
161 
162     // Go to infinite loop when Hard Fault exception occurs
163     while( 1 )
164     {
165     }
166 }
167 
168 /*!
169  * \brief  This function handles Memory Manage exception.
170  * \param  None
171  * \retval None
172  */
MemManage_Handler(void)173 void MemManage_Handler( void )
174 {
175     /* Go to infinite loop when Memory Manage exception occurs */
176     while ( 1 )
177     {
178     }
179 }
180 
181 /*!
182  * \brief  This function handles Bus Fault exception.
183  * \param  None
184  * \retval None
185  */
BusFault_Handler(void)186 void BusFault_Handler( void )
187 {
188     /* Go to infinite loop when Bus Fault exception occurs */
189     while ( 1 )
190     {
191     }
192 }
193 
194 /*!
195  * \brief  This function handles Usage Fault exception.
196  * \param  None
197  * \retval None
198  */
UsageFault_Handler(void)199 void UsageFault_Handler( void )
200 {
201     /* Go to infinite loop when Usage Fault exception occurs */
202     while ( 1 )
203     {
204     }
205 }
206 
207 /*!
208  * \brief  This function handles Debug Monitor exception.
209  * \param  None
210  * \retval None
211  */
DebugMon_Handler(void)212 void DebugMon_Handler( void )
213 {
214 }
215 
216 /*!
217  * \brief  This function handles Flash interrupt request.
218  * \param  None
219  * \retval None
220  */
FLASH_IRQHandler(void)221 void FLASH_IRQHandler( void )
222 {
223     HAL_FLASH_IRQHandler();
224 }
225 
226 /*!
227  * \brief  This function handles PVD interrupt request.
228  * \param  None
229  * \retval None
230  */
PVD_PVM_IRQHandler(void)231 void PVD_PVM_IRQHandler( void )
232 {
233     // Loop inside the handler to prevent the Cortex from using the Flash,
234     // allowing the flash interface to finish any ongoing transfer.
235     while( __HAL_PWR_GET_FLAG( PWR_FLAG_PVDO ) != RESET )
236     {
237     }
238 }
239 
240