1 /*!
2  * \file      eeprom-board.c
3  *
4  * \brief     Target board EEPROM driver implementation
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 <stdbool.h>
25 #include "stm32l4xx.h"
26 #include "eeprom_emul.h"
27 #include "eeprom-board.h"
28 #include "utilities.h"
29 
30 uint16_t EepromVirtualAddress[NB_OF_VARIABLES];
31 __IO uint32_t ErasingOnGoing = 0;
32 
33 /*!
34  * \brief Initializes the EEPROM emulation module.
35  */
EepromMcuInit(void)36 void EepromMcuInit( void )
37 {
38     EE_Status eeStatus = EE_OK;
39 
40     // Unlock the Flash Program Erase controller
41     HAL_FLASH_Unlock( );
42 
43     // Set user List of Virtual Address variables: 0x0000 and 0xFFFF values are prohibited
44     for( uint16_t varValue = 0; varValue < NB_OF_VARIABLES; varValue++ )
45     {
46         EepromVirtualAddress[varValue] = varValue + 1;
47     }
48 
49     // Set EEPROM emulation firmware to erase all potentially incompletely erased
50     // pages if the system came from an asynchronous reset. Conditional erase is
51     // safe to use if all Flash operations where completed before the system reset
52     if( __HAL_PWR_GET_FLAG( PWR_FLAG_SB ) == RESET )
53     {
54         // System reset comes from a power-on reset: Forced Erase
55         // Initialize EEPROM emulation driver (mandatory)
56         eeStatus = EE_Init( EepromVirtualAddress, EE_FORCED_ERASE );
57         if( eeStatus != EE_OK )
58         {
59             assert_param( LMN_STATUS_ERROR );
60         }
61     }
62     else
63     {
64         // Clear the Standby flag
65         __HAL_PWR_CLEAR_FLAG( PWR_FLAG_SB );
66 
67         // Check and Clear the Wakeup flag
68         if( __HAL_PWR_GET_FLAG( PWR_FLAG_WUF1 ) != RESET )
69         {
70             __HAL_PWR_CLEAR_FLAG( PWR_FLAG_WUF1 );
71         }
72 
73         // System reset comes from a STANDBY wakeup: Conditional Erase
74         // Initialize EEPROM emulation driver (mandatory)
75         eeStatus = EE_Init( EepromVirtualAddress, EE_CONDITIONAL_ERASE );
76         if( eeStatus != EE_OK )
77         {
78             assert_param( LMN_STATUS_ERROR );
79         }
80     }
81 
82     // Lock the Flash Program Erase controller
83     HAL_FLASH_Lock( );
84 }
85 
86 /*!
87  * \brief Indicates if an erasing operation is on going.
88  *
89  * \retval isEradingOnGoing Returns true is an erasing operation is on going.
90  */
EepromMcuIsErasingOnGoing(void)91 bool EepromMcuIsErasingOnGoing( void )
92 {
93     return ErasingOnGoing;
94 }
95 
EepromMcuWriteBuffer(uint16_t addr,uint8_t * buffer,uint16_t size)96 LmnStatus_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size )
97 {
98     LmnStatus_t status = LMN_STATUS_OK;
99     EE_Status eeStatus = EE_OK;
100 
101     // Unlock the Flash Program Erase controller
102     HAL_FLASH_Unlock( );
103 
104     CRITICAL_SECTION_BEGIN( );
105     for( uint32_t i = 0; i < size; i++ )
106     {
107         eeStatus |= EE_WriteVariable8bits( EepromVirtualAddress[addr + i], buffer[i] );
108     }
109     CRITICAL_SECTION_END( );
110 
111     if( eeStatus != EE_OK )
112     {
113         status = LMN_STATUS_ERROR;
114     }
115 
116     if( ( eeStatus & EE_STATUSMASK_CLEANUP ) == EE_STATUSMASK_CLEANUP )
117     {
118         ErasingOnGoing = 0;
119         eeStatus |= EE_CleanUp( );
120     }
121     if( ( eeStatus & EE_STATUSMASK_ERROR ) == EE_STATUSMASK_ERROR )
122     {
123         status = LMN_STATUS_ERROR;
124     }
125 
126     // Lock the Flash Program Erase controller
127     HAL_FLASH_Lock( );
128     return status;
129 }
130 
EepromMcuReadBuffer(uint16_t addr,uint8_t * buffer,uint16_t size)131 LmnStatus_t EepromMcuReadBuffer( uint16_t addr, uint8_t *buffer, uint16_t size )
132 {
133     LmnStatus_t status = LMN_STATUS_OK;
134 
135     // Unlock the Flash Program Erase controller
136     HAL_FLASH_Unlock( );
137 
138     for( uint32_t i = 0; i < size; i++ )
139     {
140         if( EE_ReadVariable8bits( EepromVirtualAddress[addr + i], buffer + i ) != EE_OK )
141         {
142             status = LMN_STATUS_ERROR;
143             break;
144         }
145     }
146 
147     // Lock the Flash Program Erase controller
148     HAL_FLASH_Lock( );
149     return status;
150 }
151 
EepromMcuSetDeviceAddr(uint8_t addr)152 void EepromMcuSetDeviceAddr( uint8_t addr )
153 {
154     assert_param( LMN_STATUS_ERROR );
155 }
156 
EepromMcuGetDeviceAddr(void)157 LmnStatus_t EepromMcuGetDeviceAddr( void )
158 {
159     assert_param( LMN_STATUS_ERROR );
160     return 0;
161 }
162 
163 /*!
164  * \brief  FLASH end of operation interrupt callback.
165  * \param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
166  *                  Mass Erase: Bank number which has been requested to erase
167  *                  Page Erase: Page which has been erased
168  *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
169  *                  Program: Address which was selected for data program
170  * \retval None
171  */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)172 void HAL_FLASH_EndOfOperationCallback( uint32_t ReturnValue )
173 {
174     // Call CleanUp callback when all requested pages have been erased
175     if( ReturnValue == 0xFFFFFFFF )
176     {
177         EE_EndOfCleanup_UserCallback( );
178     }
179 }
180 
181 /*!
182  * \brief  Clean Up end of operation interrupt callback.
183  * \param  None
184  * \retval None
185  */
EE_EndOfCleanup_UserCallback(void)186 void EE_EndOfCleanup_UserCallback( void )
187 {
188     ErasingOnGoing = 0;
189 }
190