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