1 /*
2  * Copyright 2018-2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /*!*********************************************************************************
10 *************************************************************************************
11 * Include
12 *************************************************************************************
13 ********************************************************************************** */
14 #include "fsl_flash.h"
15 #include "fsl_adapter_flash.h"
16 /*****************************************************************************
17  *****************************************************************************
18  * Private macros
19  *****************************************************************************
20  *****************************************************************************/
21 #define PGM_SIZE_BYTE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE
22 /*!*********************************************************************************
23 *************************************************************************************
24 * Private type definitions
25 *************************************************************************************
26 ********************************************************************************** */
27 static flash_config_t s_flashConfig;
28 /*!*********************************************************************************
29 *************************************************************************************
30 * Private prototypes
31 *************************************************************************************
32 ********************************************************************************** */
33 static hal_flash_status_t HAL_FlashProgramAdaptation(uint32_t dest, uint32_t size, uint8_t *pData);
34 /*!*********************************************************************************
35 *************************************************************************************
36 * Public memory declarations
37 *************************************************************************************
38 ********************************************************************************** */
39 
40 /*****************************************************************************
41  *****************************************************************************
42  * Private functions
43  *****************************************************************************
44  *****************************************************************************/
HAL_FlashGetStatus(status_t status)45 static hal_flash_status_t HAL_FlashGetStatus(status_t status)
46 {
47 #if (defined(HAL_FLASH_TRANSFER_MODE) && (HAL_FLASH_TRANSFER_MODE > 0U))
48     hal_flash_status_t flashStatus = kStatus_HAL_Flash_Error;
49     switch (status)
50     {
51         case (status_t)kStatus_Success:
52             flashStatus = kStatus_HAL_Flash_Success;
53             break;
54         case (status_t)kStatus_FTFx_InvalidArgument:
55             flashStatus = kStatus_HAL_Flash_InvalidArgument;
56             break;
57         case (status_t)kStatus_FTFx_AlignmentError:
58             flashStatus = kStatus_HAL_Flash_AlignmentError;
59             break;
60         default:
61             /*MISRA rule 16.4*/
62             break;
63     }
64     return flashStatus;
65 #else
66     return (hal_flash_status_t)status;
67 #endif
68 }
69 
HAL_FlashProgramAdaptation(uint32_t dest,uint32_t size,uint8_t * pData)70 static hal_flash_status_t HAL_FlashProgramAdaptation(uint32_t dest, uint32_t size, uint8_t *pData)
71 {
72     return HAL_FlashGetStatus(FLASH_Program(&s_flashConfig, dest, pData, size));
73 }
74 
75 /*!*********************************************************************************
76 *************************************************************************************
77 * Public functions
78 *************************************************************************************
79 ********************************************************************************** */
80 
81 /*!
82  * @brief Initializes the global flash properties structure members.
83  *
84  * This function initializes the Flash module for the other Flash APIs.
85  *
86  *
87  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
88  * @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
89  * @retval #kStatus_HAL_Flash_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available.
90  * @retval #kStatus_HAL_Flash_PartitionStatusUpdateFailure Failed to update the partition status.
91  */
HAL_FlashInit(void)92 hal_flash_status_t HAL_FlashInit(void)
93 {
94     static uint32_t flashInit = 0;
95     status_t status           = (status_t)kStatus_HAL_Flash_Success;
96 
97     if (0U == flashInit)
98     {
99         /* Init Flash */
100         status    = FLASH_Init(&s_flashConfig);
101         flashInit = 1U;
102     }
103     return HAL_FlashGetStatus(status);
104 }
105 
106 /*!
107  * \brief  Verify erase data in Flash
108  *
109  * @param start           The address of the Flash location
110  * @param lengthInBytes   The number of bytes to be checked
111  * @param margin          Flash margin value
112  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
113  */
HAL_FlashVerifyErase(uint32_t start,uint32_t lengthInBytes,hal_flash_margin_value_t margin)114 hal_flash_status_t HAL_FlashVerifyErase(uint32_t start, uint32_t lengthInBytes, hal_flash_margin_value_t margin)
115 {
116     status_t status;
117 
118     uint32_t regPrimask = DisableGlobalIRQ();
119     status              = FLASH_VerifyErase(&s_flashConfig, start, lengthInBytes, (ftfx_margin_value_t)margin);
120     EnableGlobalIRQ(regPrimask);
121     return HAL_FlashGetStatus(status);
122 }
123 
124 /*!
125  * \brief  Write alligned data to FLASH
126  *
127  * @param dest            The address of the Flash location
128  * @param size            The number of bytes to be programed
129  * @param pData           Pointer to the data to be programmed to Flash
130  *
131  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
132  *
133  */
HAL_FlashProgram(uint32_t dest,uint32_t size,uint8_t * pData)134 hal_flash_status_t HAL_FlashProgram(uint32_t dest, uint32_t size, uint8_t *pData)
135 {
136     return HAL_FlashProgramAdaptation(dest, size, pData);
137 }
138 
139 /*!
140  * \brief  Write data to FLASH
141  *
142  * @param dest        The address of the Flash location
143  * @param size        The number of bytes to be programed
144  * @param pData       Pointer to the data to be programmed to Flash
145  *
146  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
147  *
148  */
HAL_FlashProgramUnaligned(uint32_t dest,uint32_t size,uint8_t * pData)149 hal_flash_status_t HAL_FlashProgramUnaligned(uint32_t dest, uint32_t size, uint8_t *pData)
150 {
151     uint8_t buffer[PGM_SIZE_BYTE];
152     uint32_t bytes            = dest & ((uint32_t)PGM_SIZE_BYTE - 1U);
153     hal_flash_status_t status = kStatus_HAL_Flash_Success;
154 
155     if (bytes != 0U)
156     {
157         uint32_t unalignedBytes = (uint32_t)PGM_SIZE_BYTE - bytes;
158 
159         if (unalignedBytes > size)
160         {
161             unalignedBytes = size;
162         }
163 
164         (void)memcpy(buffer, (uint8_t *)(dest - bytes), PGM_SIZE_BYTE);
165         (void)memcpy(&buffer[bytes], pData, unalignedBytes);
166 
167         status = HAL_FlashProgramAdaptation(dest - bytes, PGM_SIZE_BYTE, buffer);
168         if (kStatus_HAL_Flash_Success == status)
169         {
170             dest += (uint32_t)PGM_SIZE_BYTE - bytes;
171             pData += unalignedBytes;
172             size -= unalignedBytes;
173         }
174     }
175 
176     if (kStatus_HAL_Flash_Success == status)
177     {
178         bytes = size & ~((uint32_t)PGM_SIZE_BYTE - 1U);
179 
180         if (bytes != 0U)
181         {
182             status = HAL_FlashProgramAdaptation(dest, bytes, pData);
183             if (kStatus_HAL_Flash_Success == status)
184             {
185                 dest += bytes;
186                 pData += bytes;
187                 size -= bytes;
188             }
189         }
190 
191         if (kStatus_HAL_Flash_Success == status)
192         {
193             if (size != 0U)
194             {
195                 (void)memcpy(buffer, (uint8_t *)dest, PGM_SIZE_BYTE);
196                 (void)memcpy(buffer, pData, size);
197                 status = HAL_FlashProgramAdaptation(dest, PGM_SIZE_BYTE, buffer);
198             }
199         }
200     }
201     return status;
202 }
203 /*!
204  * \brief  Erase to 0xFF one or more FLASH sectors.
205  *
206  * @param dest            The start address of the first sector to be erased
207  * @param size            The amount of flash to be erased (multiple of sector size)
208  *
209  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
210  *
211  */
HAL_FlashEraseSector(uint32_t dest,uint32_t size)212 hal_flash_status_t HAL_FlashEraseSector(uint32_t dest, uint32_t size)
213 {
214     int32_t status;
215 
216     uint32_t regPrimask = DisableGlobalIRQ();
217     status              = FLASH_Erase(&s_flashConfig, dest, size, (uint32_t)kFLASH_ApiEraseKey);
218     EnableGlobalIRQ(regPrimask);
219     return HAL_FlashGetStatus(status);
220 }
221 
222 /*!
223  * \brief  Read data from FLASH
224  *
225  * @param scr             The address of the Flash location to be read
226  * @param size            The number of bytes to be read
227  * @param pData           Pointer to the data to be read from Flash
228  *
229  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
230  *
231  */
HAL_FlashRead(uint32_t src,uint32_t size,uint8_t * pData)232 hal_flash_status_t HAL_FlashRead(uint32_t src, uint32_t size, uint8_t *pData)
233 {
234     (void)memcpy(pData, (uint8_t *)src, size);
235 
236     return kStatus_HAL_Flash_Success;
237 }
238 
239 /*!
240  * @brief Returns the desired hal flash property.
241  *
242  * @param Property        The desired property from the list of properties in
243  *                        enum hal_flash_property_tag_t
244  * @param value           A pointer to the value returned for the desired flash property.
245  *
246  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
247  * @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
248  * @retval #kStatus_HAL_Flash_NotSupport Flash currently not support.
249  */
HAL_FlashGetProperty(hal_flash_property_tag_t property,uint32_t * value)250 hal_flash_status_t HAL_FlashGetProperty(hal_flash_property_tag_t property, uint32_t *value)
251 {
252     return HAL_FlashGetStatus(FLASH_GetProperty(&s_flashConfig, (flash_property_tag_t)property, value));
253 }
254 
255 /*!
256  * @brief Set the desired hal flash property.
257  *
258  * @param Property        The desired property from the list of properties in
259  *                        enum hal_flash_property_tag_t
260  * @param value           The value would be set to the desired flash property.
261  *
262  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
263  * @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
264  * @retval #kStatus_HAL_Flash_NotSupport Flash currently not support.
265  */
HAL_FlashSetProperty(hal_flash_property_tag_t property,uint32_t value)266 hal_flash_status_t HAL_FlashSetProperty(hal_flash_property_tag_t property, uint32_t value)
267 {
268     return kStatus_HAL_Flash_NotSupport;
269 }
270 
271 /*!
272  * @brief Returns the security state via the pointer passed into the function.
273  *
274  * This function retrieves the current flash security status, including the
275  * security enabling state and the backdoor key enabling state.
276  *
277  * @param state           A pointer to the value returned for the current security status
278  *
279  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
280  * @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
281  * @retval #kStatus_HAL_Flash_NotSupport Flash currently not support.
282  */
HAL_FlashGetSecurityState(hal_flash_security_state_t * state)283 hal_flash_status_t HAL_FlashGetSecurityState(hal_flash_security_state_t *state)
284 {
285     return HAL_FlashGetStatus(FLASH_GetSecurityState(&s_flashConfig, (ftfx_security_state_t *)((void *)state)));
286 }
287 
288 /*!
289  * \brief  Read data from FLASH with ECC Fault detection enabled.
290  *
291  *  Note : BusFault is not raised, just SoC indication
292  *
293  * @param scr             The address of the Flash location to be read
294  * @param size            The number of bytes to be read
295  * @param pData           Pointer to the data to be read from Flash
296  *
297  * @retval #kStatus_HAL_Flash_Success API was executed successfully.
298  *         #kStatus_HAL_Flash_EccError if ECC Fault error got raised
299  *
300  */
HAL_FlashReadCheckEccFaults(uint32_t src,uint32_t size,uint8_t * pData)301 hal_flash_status_t HAL_FlashReadCheckEccFaults(uint32_t src, uint32_t size, uint8_t *pData)
302 {
303     return kStatus_HAL_Flash_NotSupport;
304 }
305