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