1 /*
2 * Copyright 2018, 2020 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_common.h"
10 #include "fsl_adapter_eeprom.h"
11 #include "fsl_adapter_flash.h"
12
13 /******************************************************************************
14 *******************************************************************************
15 * Private Macros
16 *******************************************************************************
17 ******************************************************************************/
18
19 /******************************************************************************
20 *******************************************************************************
21 * Private Prototypes
22 *******************************************************************************
23 ******************************************************************************/
24
25 /******************************************************************************
26 *******************************************************************************
27 * Private type definitions
28 *******************************************************************************
29 ******************************************************************************/
30
31 /******************************************************************************
32 *******************************************************************************
33 * Private Memory Declarations
34 *******************************************************************************
35 ******************************************************************************/
36
37 typedef struct _eeprom_state
38 {
39 uint8_t eepromEraseBitmap[32];
40 uint32_t eepromParams_StartOffset;
41 uint32_t eepromParams_TotalSize;
42 uint32_t eepromParams_SectorSize;
43 eeprom_type_t eeType;
44 } eeprom_state_t;
45
46 static eeprom_state_t s_eeState;
47 /*! *********************************************************************************
48 *************************************************************************************
49 * Private Memory Declarations
50 *************************************************************************************
51 ********************************************************************************** */
52
53 /*! *********************************************************************************
54 *************************************************************************************
55 * Private Memory function
56 *************************************************************************************
57 ********************************************************************************** */
EEPROM_CleanEraseFlag(uint32_t noOfBytes,uint32_t addr)58 static eeprom_status_t EEPROM_CleanEraseFlag(uint32_t noOfBytes, uint32_t addr)
59 {
60 uint32_t i;
61 uint32_t startBlk, endBlk;
62 /* Obtain the first and last block that need to be erased */
63 startBlk = addr / s_eeState.eepromParams_SectorSize;
64 endBlk = (addr + noOfBytes) / s_eeState.eepromParams_SectorSize;
65
66 if ((addr + noOfBytes) & s_eeState.eepromParams_SectorSize)
67 {
68 endBlk++;
69 }
70 for (i = startBlk; i <= endBlk; i++)
71 {
72 s_eeState.eepromEraseBitmap[i / 8] &= ~(1U << (i % 8));
73 }
74 return kStatus_EeSuccess;
75 }
EEPROM_PrepareForWrite(uint32_t noOfBytes,uint32_t addr)76 static eeprom_status_t EEPROM_PrepareForWrite(uint32_t noOfBytes, uint32_t addr)
77 {
78 uint32_t i;
79 uint32_t startBlk, endBlk;
80 /* Obtain the first and last block that need to be erased */
81 startBlk = addr / s_eeState.eepromParams_SectorSize;
82 endBlk = (addr + noOfBytes) / s_eeState.eepromParams_SectorSize;
83
84 if ((addr + noOfBytes) & s_eeState.eepromParams_SectorSize)
85 {
86 endBlk++;
87 }
88
89 /* Check if the block was previousley erased */
90 for (i = startBlk; i <= endBlk; i++)
91 {
92 if ((s_eeState.eepromEraseBitmap[i / 8] & (1U << (i % 8))) == 0)
93 {
94 if (EEPROM_EraseBlock(i * s_eeState.eepromParams_SectorSize, s_eeState.eepromParams_SectorSize) !=
95 kStatus_EeSuccess)
96 {
97 return kStatus_EeError;
98 }
99 s_eeState.eepromEraseBitmap[i / 8] |= 1U << (i % 8);
100 }
101 }
102
103 return kStatus_EeSuccess;
104 }
105 /******************************************************************************
106 *******************************************************************************
107 * Public Memory
108 *******************************************************************************
109 ******************************************************************************/
110
111 /******************************************************************************
112 *******************************************************************************
113 * Public Functions
114 *******************************************************************************
115 ******************************************************************************/
116
117 /*****************************************************************************
118 * EEPROM_Init
119 *
120 * Initializes the EEPROM_ peripheral
121 *
122 *****************************************************************************/
EEPROM_Init(eeprom_config_t * eepromConfig)123 eeprom_status_t EEPROM_Init(eeprom_config_t *eepromConfig)
124 {
125 uint32_t pflashBlockBase = 0;
126 uint32_t pflashTotalSize = 0;
127 uint32_t eepromTotalSize = 0;
128
129 memset(s_eeState.eepromEraseBitmap, 0x00, 32);
130
131 HAL_FlashInit();
132 HAL_FlashGetProperty(kHAL_Flash_PropertyPflashBlockBaseAddr, &pflashBlockBase);
133 HAL_FlashGetProperty(kHAL_Flash_PropertyPflashTotalSize, &pflashTotalSize);
134 HAL_FlashGetProperty(kHAL_Flash_PropertyPflashSectorSize, &s_eeState.eepromParams_SectorSize);
135 eepromTotalSize = pflashTotalSize / 2 - ((pflashTotalSize / 2) & (s_eeState.eepromParams_SectorSize - 1));
136 s_eeState.eepromParams_TotalSize = (eepromTotalSize > 32 * 8 * s_eeState.eepromParams_SectorSize) ?
137 32 * 8 * s_eeState.eepromParams_SectorSize :
138 eepromTotalSize;
139 s_eeState.eepromParams_StartOffset = pflashBlockBase + pflashTotalSize - s_eeState.eepromParams_TotalSize;
140 return kStatus_EeSuccess;
141 }
142
143 /*****************************************************************************
144 * EEPROM_ChipErase
145 *
146 * Erase all memory to 0xFF
147 *
148 *****************************************************************************/
EEPROM_ChipErase(void)149 eeprom_status_t EEPROM_ChipErase(void)
150 {
151 uint32_t i, endAddr;
152 endAddr = s_eeState.eepromParams_TotalSize;
153
154 for (i = 0; i < endAddr; i += s_eeState.eepromParams_SectorSize)
155 {
156 if (kStatus_EeSuccess != EEPROM_EraseBlock(i, s_eeState.eepromParams_SectorSize))
157 {
158 return kStatus_EeError;
159 }
160 }
161 return kStatus_EeSuccess;
162 }
163
164 /*****************************************************************************
165 * EEPROM_EraseSector4K
166 *
167 * Erase 4K of memory to 0xFF
168 *
169 *****************************************************************************/
EEPROM_EraseBlock(uint32_t addr,uint32_t size)170 eeprom_status_t EEPROM_EraseBlock(uint32_t addr, uint32_t size)
171 {
172 eeprom_status_t status;
173
174 if (size != s_eeState.eepromParams_SectorSize)
175 {
176 status = kStatus_EeError;
177 }
178 else if (HAL_FlashEraseSector(s_eeState.eepromParams_StartOffset + addr, size) != kStatus_HAL_Flash_Success)
179 {
180 status = kStatus_EeError;
181 }
182 else
183 {
184 status = kStatus_EeSuccess;
185 }
186
187 return status;
188 }
189
190 /*****************************************************************************
191 * EEPROM_WriteData
192 *
193 * Writes a data buffer into EEPROM, at a given address
194 *
195 *****************************************************************************/
EEPROM_WriteData(uint32_t noOfBytes,uint32_t addr,uint8_t * Outbuf)196 eeprom_status_t EEPROM_WriteData(uint32_t noOfBytes, uint32_t addr, uint8_t *Outbuf)
197 {
198 /* If Erase is done during write, no need to erase here */
199 if (kStatus_EeSuccess != EEPROM_PrepareForWrite(noOfBytes, addr))
200 {
201 return kStatus_EeError;
202 }
203
204 /* Write data to FLASH */
205 if (HAL_FlashProgramUnaligned(s_eeState.eepromParams_StartOffset + addr, noOfBytes, Outbuf) !=
206 kStatus_HAL_Flash_Success)
207 {
208 return kStatus_EeError;
209 }
210 EEPROM_CleanEraseFlag(noOfBytes, addr);
211 return kStatus_EeSuccess;
212 }
213
214 /*****************************************************************************
215 * EEPROM_ReadData
216 *
217 * Reads a data buffer from EEPROM, from a given address
218 *
219 *****************************************************************************/
EEPROM_ReadData(uint16_t noOfBytes,uint32_t addr,uint8_t * inbuf)220 eeprom_status_t EEPROM_ReadData(uint16_t noOfBytes, uint32_t addr, uint8_t *inbuf)
221 {
222 if (HAL_FlashRead(s_eeState.eepromParams_StartOffset + addr, noOfBytes, inbuf) != kStatus_HAL_Flash_Success)
223 {
224 return kStatus_EeError;
225 }
226
227 return kStatus_EeSuccess;
228 }
229 #if (defined(GET_EEPROM_SIZE) && (GET_EEPROM_SIZE > 0))
EEPROM_GetProperty(eeprom_property_tag_t property,uint32_t * value)230 eeprom_status_t EEPROM_GetProperty(eeprom_property_tag_t property, uint32_t *value)
231 {
232 if (value == NULL)
233 {
234 return kStatus_EeInvalidArgument;
235 }
236
237 switch (property)
238 {
239 case kEEPROM_PropertyTotalSize:
240
241 *value = s_eeState.eepromParams_TotalSize; /* 512 KBytes */
242 break;
243
244 case kEEPROM_PropertySectorSize:
245 *value = s_eeState.eepromParams_SectorSize; /* 2 KBytes */
246 break;
247
248 default: /* catch inputs that are not recognized */
249 return kStatus_EeInvalidArgument;
250 }
251
252 return kStatus_EeSuccess;
253 }
254 #endif
255