1 /*
2 * Copyright 2018-2021, 2023 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_iap.h"
9
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.iap"
13 #endif
14
15 #define HZ_TO_KHZ_DIV 1000U
16
17 /*******************************************************************************
18 * Definitions
19 ******************************************************************************/
20 #define IAP_ISP_TYPE_I2C 1U
21 #define IAP_ISP_TYPE_SPI 4U
22 #define IAP_ISP_TYPE_SPI1 5U
23 #define IAP_ISP_TYPE_USB0 8U
24 #define IAP_ISP_TYPE_USB1 9U
25
26 /*! @brief IAP_ENTRY API function type */
27 typedef void (*IAP_ENTRY_T)(uint32_t cmd[], uint32_t stat[]);
28
29 /*******************************************************************************
30 * Prototypes
31 ******************************************************************************/
32 /*!
33 * @brief Translate the IAP return status.
34 *
35 * @param status IAP status return from the IAP function.
36 *
37 * @return sdk status code.
38 */
39 static inline status_t translate_iap_status(uint32_t status);
40
41 /*!
42 * @brief IAP_ENTRY API function type.
43 *
44 * Wrapper for rom iap call.
45 *
46 * @param cmd_param IAP command and relevant parameter array.
47 * @param status_result IAP status result array.
48 */
49 static inline void iap_entry(uint32_t *cmd_param, uint32_t *status_result);
50
51 /*!
52 * @brief IAP_ENTRY API function type.
53 *
54 * Wrapper for rom iap call, but doesn't disable global interrupt.
55 *
56 * @param cmd_param IAP command and relevant parameter array.
57 * @param status_result IAP status result array.
58 */
59 static inline void iap_entry_no_disable_irq(uint32_t *cmd_param, uint32_t *status_result);
60
61 /*******************************************************************************
62 * Variables
63 ******************************************************************************/
64
65 /*******************************************************************************
66 * Code
67 ******************************************************************************/
translate_iap_status(uint32_t status)68 static inline status_t translate_iap_status(uint32_t status)
69 {
70 status_t ret = (status_t)status;
71
72 /* Translate IAP return code to sdk status code */
73 if (status != (uint32_t)kStatus_Success)
74 {
75 ret = MAKE_STATUS((int32_t)kStatusGroup_IAP, (int32_t)status);
76 }
77
78 return ret;
79 }
80
iap_entry(uint32_t * cmd_param,uint32_t * status_result)81 static inline void iap_entry(uint32_t *cmd_param, uint32_t *status_result)
82 {
83 __disable_irq();
84 ((IAP_ENTRY_T)FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION)(cmd_param, status_result);
85 __enable_irq();
86 }
87
iap_entry_no_disable_irq(uint32_t * cmd_param,uint32_t * status_result)88 static inline void iap_entry_no_disable_irq(uint32_t *cmd_param, uint32_t *status_result)
89 {
90 ((IAP_ENTRY_T)FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION)(cmd_param, status_result);
91 }
92
93 /*!
94 * @brief Read part identification number.
95 *
96 * This function is used to read the part identification number.
97 *
98 * @param partID Address to store the part identification number.
99 *
100 * @retval kStatus_IAP_Success Api has been executed successfully.
101 */
IAP_ReadPartID(uint32_t * partID)102 status_t IAP_ReadPartID(uint32_t *partID)
103 {
104 uint32_t command[5] = {0x00U};
105 uint32_t result[5] = {0x00U};
106
107 command[0] = (uint32_t)kIapCmd_IAP_ReadPartId;
108 iap_entry(command, result);
109 *partID = result[1];
110
111 return translate_iap_status(result[0]);
112 }
113
114 /*!
115 * @brief Read boot code version number.
116 *
117 * This function is used to read the boot code version number.
118 *
119 * @param bootCodeVersion Address to store the boot code version.
120 *
121 * @retval kStatus_IAP_Success Api has been executed successfully.
122 *
123 * note Boot code version is two 32-bit words. Word 0 is the major version, word 1 is the minor version.
124 */
IAP_ReadBootCodeVersion(uint32_t * bootCodeVersion)125 status_t IAP_ReadBootCodeVersion(uint32_t *bootCodeVersion)
126 {
127 uint32_t command[5] = {0x00U};
128 uint32_t result[5] = {0x00U};
129
130 command[0] = (uint32_t)kIapCmd_IAP_Read_BootromVersion;
131 iap_entry(command, result);
132 bootCodeVersion[0] = result[1];
133 bootCodeVersion[1] = result[2];
134
135 return translate_iap_status(result[0]);
136 }
137
138 /*!
139 * @brief Reinvoke ISP.
140 *
141 * This function is used to invoke the boot loader in ISP mode. It maps boot vectors and configures the peripherals for
142 * ISP.
143 *
144 * @param ispType ISP type selection.
145 * @param status store the possible status.
146 *
147 * @retval kStatus_IAP_ReinvokeISPConfig reinvoke configuration error.
148 *
149 * note The error response will be returned when IAP is disabled or an invalid ISP type selection appears. The call
150 * won't return unless an error occurs, so there can be no status code.
151 */
IAP_ReinvokeISP(uint8_t ispType,uint32_t * status)152 void IAP_ReinvokeISP(uint8_t ispType, uint32_t *status)
153 {
154 #if (defined(FSL_FEATURE_SYSCON_IAP_REINVOKE_ISP_PARAM_POINTER) && FSL_FEATURE_SYSCON_IAP_REINVOKE_ISP_PARAM_POINTER)
155 uint32_t command[5] = {0x00U};
156 uint32_t result[5] = {0x00U};
157 uint8_t ispParameterArray[8];
158
159 command[0] = (uint32_t)kIapCmd_IAP_ReinvokeISP;
160 (void)memset(ispParameterArray, 0, sizeof(uint8_t) * 8U);
161 if ((IAP_ISP_TYPE_I2C == ispType) || (IAP_ISP_TYPE_SPI == ispType) || (IAP_ISP_TYPE_SPI1 == ispType))
162 {
163 ispParameterArray[0] = 0x55U;
164 }
165 else if ((IAP_ISP_TYPE_USB0 == ispType) || (IAP_ISP_TYPE_USB1 == ispType))
166 {
167 ispParameterArray[0] = 0xAAU;
168 }
169 else
170 {
171 ispParameterArray[0] = 0x00U;
172 }
173 ispParameterArray[1] = ispType;
174 ispParameterArray[7] = ispParameterArray[0] ^ ispParameterArray[1] ^ ispParameterArray[2] ^ ispParameterArray[3] ^
175 ispParameterArray[4] ^ ispParameterArray[5] ^ ispParameterArray[6];
176 command[1] = (uint32_t)ispParameterArray;
177 iap_entry_no_disable_irq(command, result);
178 *status = (uint32_t)translate_iap_status(result[0]);
179 #else
180 uint32_t command[5] = {0x00U};
181 uint32_t result[5] = {0x00U};
182
183 command[0] = (uint32_t)kIapCmd_IAP_ReinvokeISP;
184 command[1] = (uint32_t)ispType;
185 iap_entry_no_disable_irq(command, result);
186 *status = (uint32_t)translate_iap_status(result[0]);
187 #endif
188 }
189
190 /*!
191 * @brief Read unique identification.
192 *
193 * This function is used to read the unique id.
194 *
195 * @param uniqueID store the uniqueID.
196 *
197 * @retval kStatus_IAP_Success Api has been executed successfully.
198 */
IAP_ReadUniqueID(uint32_t * uniqueID)199 status_t IAP_ReadUniqueID(uint32_t *uniqueID)
200 {
201 #if defined(FSL_FEATURE_IAP_READ_UNIQUE_ID_NOWORK) && FSL_FEATURE_IAP_READ_UNIQUE_ID_NOWORK
202 uint32_t *result = (uint32_t *)0x01000100;
203 uint8_t i = 0;
204
205 for (i = 0; i < 4; i++)
206 uniqueID[i] = result[i];
207 return kStatus_IAP_Success;
208 #else
209 uint32_t command[5] = {0x00U};
210 uint32_t result[5] = {0x00U};
211
212 command[0] = (uint32_t)kIapCmd_IAP_ReadUid;
213 iap_entry(command, result);
214 uniqueID[0] = result[1];
215 uniqueID[1] = result[2];
216 uniqueID[2] = result[3];
217 uniqueID[3] = result[4];
218
219 return translate_iap_status(result[0]);
220 #endif
221 }
222
223 #if defined(FLASH_CTRL_FLASHCFG_FLASHTIM_MASK)
224 /*!
225 * @brief Flash memory access time.
226 *
227 * This function is used to configure the access time to the flash memory.
228 *
229 * @param accessTime Flash memory access time FLASHTIM +1 is equal to the
230 * number of system clocks used for flash access.
231 */
IAP_ConfigAccessFlashTime(uint32_t accessTime)232 void IAP_ConfigAccessFlashTime(uint32_t accessTime)
233 {
234 uint32_t temp;
235 temp = FLASH_CTRL->FLASHCFG;
236 temp &= ~FLASH_CTRL_FLASHCFG_FLASHTIM_MASK;
237 FLASH_CTRL->FLASHCFG = temp | FLASH_CTRL_FLASHCFG_FLASHTIM(accessTime);
238 }
239 #endif
240
241 #if defined(FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION) && FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION
242 /*!
243 * @brief Read factory settings.
244 *
245 * This function reads the factory settings for calibration registers.
246 *
247 * @param dstRegAddr Address of the targeted calibration register.
248 * @param factoryValue Store the factory value
249 *
250 * @retval kStatus_IAP_Success Api has been executed successfully.
251 * @retval kStatus_IAP_ParamError Param0 is not one of the supported calibration registers.
252 */
IAP_ReadFactorySettings(uint32_t dstRegAddr,uint32_t * factoryValue)253 status_t IAP_ReadFactorySettings(uint32_t dstRegAddr, uint32_t *factoryValue)
254 {
255 uint32_t command[5] = {0x00U};
256 uint32_t result[5] = {0x00U};
257
258 command[0] = (uint32_t)kIapCmd_IAP_ReadFactorySettings;
259 command[1] = dstRegAddr;
260 iap_entry(command, result);
261 *factoryValue = result[1];
262
263 return translate_iap_status(result[0]);
264 }
265 #endif /* FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION */
266
267 #if defined(FSL_FEATURE_IAP_HAS_FLASH_FUNCTION) && FSL_FEATURE_IAP_HAS_FLASH_FUNCTION
268 /*!
269 * @brief Prepare sector for write operation.
270 *
271 * This function prepares sector(s) for write/erase operation. This function must be called before calling the
272 * IAP_CopyRamToFlash() or IAP_EraseSector() or IAP_ErasePage() function. The end sector number must be greater than or
273 * equal to the start sector number.
274 *
275 * @param startSector Start sector number.
276 * @param endSector End sector number.
277 *
278 * @retval kStatus_IAP_Success Api has been executed successfully.
279 * @retval kStatus_IAP_NoPower Flash memory block is powered down.
280 * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
281 * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number.
282 * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
283 */
IAP_PrepareSectorForWrite(uint32_t startSector,uint32_t endSector)284 status_t IAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector)
285 {
286 uint32_t command[5] = {0x00U};
287 uint32_t result[5] = {0x00U};
288
289 command[0] = (uint32_t)kIapCmd_IAP_PrepareSectorforWrite;
290 command[1] = startSector;
291 command[2] = endSector;
292 iap_entry(command, result);
293
294 return translate_iap_status(result[0]);
295 }
296
297 /*!
298 * @brief Copy RAM to flash.
299 *
300 * This function programs the flash memory. Corresponding sectors must be prepared via IAP_PrepareSectorForWrite before
301 * calling this function.
302 *
303 * @param dstAddr Destination flash address where data bytes are to be written, the address should be multiples
304 * of FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES boundary.
305 * @param srcAddr Source ram address from where data bytes are to be read.
306 * @param numOfBytes Number of bytes to be written, it should be multiples of FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES,
307 * and ranges from FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES to FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES.
308 * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
309 * flash controller has a fixed reference clock, this parameter is bypassed.
310 *
311 * @retval kStatus_IAP_Success Api has been executed successfully.
312 * @retval kStatus_IAP_NoPower Flash memory block is powered down.
313 * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
314 * @retval kStatus_IAP_SrcAddrError Source address is not on word boundary.
315 * @retval kStatus_IAP_DstAddrError Destination address is not on a correct boundary.
316 * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
317 * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
318 * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value.
319 * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
320 * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
321 */
IAP_CopyRamToFlash(uint32_t dstAddr,uint32_t * srcAddr,uint32_t numOfBytes,uint32_t systemCoreClock)322 status_t IAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock)
323 {
324 uint32_t command[5] = {0x00U};
325 uint32_t result[5] = {0x00U};
326
327 command[0] = (uint32_t)kIapCmd_IAP_CopyRamToFlash;
328 command[1] = dstAddr;
329 command[2] = (uint32_t)srcAddr;
330 command[3] = numOfBytes;
331 #if !(defined(FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) && FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK)
332 command[4] = systemCoreClock / HZ_TO_KHZ_DIV;
333 #endif /* FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK */
334 iap_entry(command, result);
335
336 return translate_iap_status(result[0]);
337 }
338
339 /*!
340 * @brief Erase sector.
341 *
342 * This function erases sector(s). The end sector number must be greater than or equal to the start sector number.
343 *
344 * @param startSector Start sector number.
345 * @param endSector End sector number.
346 * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
347 * flash controller has a fixed reference clock, this parameter is bypassed.
348 *
349 * @retval kStatus_IAP_Success Api has been executed successfully.
350 * @retval kStatus_IAP_NoPower Flash memory block is powered down.
351 * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
352 * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number.
353 * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
354 * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
355 */
IAP_EraseSector(uint32_t startSector,uint32_t endSector,uint32_t systemCoreClock)356 status_t IAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock)
357 {
358 uint32_t command[5] = {0x00U};
359 uint32_t result[5] = {0x00U};
360
361 command[0] = (uint32_t)kIapCmd_IAP_EraseSector;
362 command[1] = startSector;
363 command[2] = endSector;
364 #if !(defined(FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) && FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK)
365 command[3] = systemCoreClock / HZ_TO_KHZ_DIV;
366 #endif /* FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK */
367 iap_entry(command, result);
368
369 return translate_iap_status(result[0]);
370 }
371
372 /*!
373 * @brief Erase page.
374 *
375 * This function erases page(s). The end page number must be greater than or equal to the start page number.
376 *
377 * @param startPage Start page number.
378 * @param endPage End page number.
379 * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
380 * flash controller has a fixed reference clock, this parameter is bypassed.
381 *
382 * @retval kStatus_IAP_Success Api has been executed successfully.
383 * @retval kStatus_IAP_NoPower Flash memory block is powered down.
384 * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
385 * @retval kStatus_IAP_InvalidSector Page number is invalid or end page number is greater than start page number.
386 * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
387 * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
388 */
IAP_ErasePage(uint32_t startPage,uint32_t endPage,uint32_t systemCoreClock)389 status_t IAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock)
390 {
391 uint32_t command[5] = {0x00U};
392 uint32_t result[5] = {0x00U};
393
394 command[0] = (uint32_t)kIapCmd_IAP_ErasePage;
395 command[1] = startPage;
396 command[2] = endPage;
397 #if !(defined(FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) && FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK)
398 command[3] = systemCoreClock / HZ_TO_KHZ_DIV;
399 #endif /* FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK */
400 iap_entry(command, result);
401
402 return translate_iap_status(result[0]);
403 }
404
405 /*!
406 * @brief Blank check sector(s)
407 *
408 * Blank check single or multiples sectors of flash memory. The end sector number must be greater than or equal to the
409 * start sector number. It can be used to verify the sector erasure after IAP_EraseSector call.
410 *
411 * @param startSector Start sector number.
412 * @param endSector End sector number.
413 * @retval kStatus_IAP_Success One or more sectors are in erased state.
414 * @retval kStatus_IAP_NoPower Flash memory block is powered down.
415 * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
416 * @retval kStatus_IAP_SectorNotblank One or more sectors are not blank.
417 */
IAP_BlankCheckSector(uint32_t startSector,uint32_t endSector)418 status_t IAP_BlankCheckSector(uint32_t startSector, uint32_t endSector)
419 {
420 uint32_t command[5] = {0x00U};
421 uint32_t result[5] = {0x00U};
422
423 command[0] = (uint32_t)kIapCmd_IAP_BlankCheckSector;
424 command[1] = startSector;
425 command[2] = endSector;
426 iap_entry(command, result);
427
428 return translate_iap_status(result[0]);
429 }
430
431 /*!
432 * @brief Compare memory contents of flash with ram.
433 *
434 * This function compares the contents of flash and ram. It can be used to verify the flash memory contents after
435 * IAP_CopyRamToFlash call.
436 *
437 * @param dstAddr Destination flash address.
438 * @param srcAddr Source ram address.
439 * @param numOfBytes Number of bytes to be compared.
440 *
441 * @retval kStatus_IAP_Success Contents of flash and ram match.
442 * @retval kStatus_IAP_NoPower Flash memory block is powered down.
443 * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
444 * @retval kStatus_IAP_AddrError Address is not on word boundary.
445 * @retval kStatus_IAP_AddrNotMapped Address is not mapped in the memory map.
446 * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value.
447 * @retval kStatus_IAP_CompareError Destination and source memory contents do not match.
448 */
IAP_Compare(uint32_t dstAddr,uint32_t * srcAddr,uint32_t numOfBytes)449 status_t IAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes)
450 {
451 uint32_t command[5] = {0x00U};
452 uint32_t result[5] = {0x00U};
453
454 command[0] = (uint32_t)kIapCmd_IAP_Compare;
455 command[1] = dstAddr;
456 command[2] = (uint32_t)srcAddr;
457 command[3] = numOfBytes;
458 iap_entry(command, result);
459
460 return translate_iap_status(result[0]);
461 }
462
463 #if defined(FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ
464 /*!
465 * @brief Extended Read signature.
466 *
467 * This function calculates the signature value for one or more pages of on-chip flash memory.
468 *
469 * @param startPage Start page number.
470 * @param endPage End page number.
471 * @param numOfStates Number of wait states.
472 * @param signature Address to store the signature value.
473 *
474 * @retval kStatus_IAP_Success Api has been executed successfully.
475 */
IAP_ExtendedFlashSignatureRead(uint32_t startPage,uint32_t endPage,uint32_t numOfStates,uint32_t * signature)476 status_t IAP_ExtendedFlashSignatureRead(uint32_t startPage, uint32_t endPage, uint32_t numOfStates, uint32_t *signature)
477 {
478 uint32_t command[5] = {0x00U};
479 uint32_t result[5] = {0x00U};
480
481 command[0] = (uint32_t)kIapCmd_IAP_ExtendedReadSignature;
482 command[1] = startPage;
483 command[2] = endPage;
484 command[3] = numOfStates;
485 command[4] = 0;
486 iap_entry(command, result);
487 signature[0] = result[4];
488 signature[1] = result[3];
489 signature[2] = result[2];
490 signature[3] = result[1];
491
492 return translate_iap_status(result[0]);
493 }
494 #endif /* FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ */
495
496 #if defined(FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ
497 /*!
498 * @brief Read flash signature.
499 *
500 * This funtion is used to obtain a 32-bit signature value of the entire flash memory.
501 *
502 * @param signature Address to store the 32-bit generated signature value.
503 *
504 * @retval kStatus_IAP_Success Api has been executed successfully.
505 */
IAP_ReadFlashSignature(uint32_t * signature)506 status_t IAP_ReadFlashSignature(uint32_t *signature)
507 {
508 uint32_t command[5] = {0x00U};
509 uint32_t result[5] = {0x00U};
510
511 command[0] = (uint32_t)kIapCmd_IAP_ReadSignature;
512 iap_entry(command, result);
513 *signature = result[1];
514
515 return translate_iap_status(result[0]);
516 }
517 #endif /* FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ */
518 #endif /* FSL_FEATURE_IAP_HAS_FLASH_FUNCTION */
519
520 #if (defined(FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION) && (FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION == 1))
521 /*!
522 * @brief Read EEPROM page.
523 *
524 * This function is used to read given page of EEPROM into the memory provided.
525 *
526 * @param pageNumber EEPROM page number.
527 * @param dstAddr Memory address to store the value read from EEPROM.
528 * @param systemCoreClock Current core clock frequency in kHz.
529 *
530 * @retval kStatus_IAP_Success Api has been executed successfully.
531 * @retval kStatus_IAP_InvalidSector Sector number is invalid.
532 * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
533 *
534 * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM.
535 */
IAP_ReadEEPROMPage(uint32_t pageNumber,uint32_t * dstAddr,uint32_t systemCoreClock)536 status_t IAP_ReadEEPROMPage(uint32_t pageNumber, uint32_t *dstAddr, uint32_t systemCoreClock)
537 {
538 uint32_t command[5] = {0x00U};
539 uint32_t result[5] = {0x00U};
540
541 command[0] = (uint32_t)kIapCmd_IAP_ReadEEPROMPage;
542 command[1] = pageNumber;
543 command[2] = (uint32_t)dstAddr;
544 command[3] = systemCoreClock / HZ_TO_KHZ_DIV;
545 iap_entry(command, result);
546
547 return translate_iap_status(result[0]);
548 }
549
550 /*!
551 * @brief Write EEPROM page.
552 *
553 * This function is used to write given data in the provided memory to a page of EEPROM.
554 *
555 * @param pageNumber EEPROM page number.
556 * @param srcAddr Memory address holding data to be stored on to EEPROM page.
557 * @param systemCoreClock Current core clock frequency in kHz.
558 *
559 * @retval kStatus_IAP_Success Api has been executed successfully.
560 * @retval kStatus_IAP_InvalidSector Sector number is invalid.
561 * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
562 *
563 * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM
564 */
IAP_WriteEEPROMPage(uint32_t pageNumber,uint32_t * srcAddr,uint32_t systemCoreClock)565 status_t IAP_WriteEEPROMPage(uint32_t pageNumber, uint32_t *srcAddr, uint32_t systemCoreClock)
566 {
567 uint32_t command[5] = {0x00U};
568 uint32_t result[5] = {0x00U};
569
570 command[0] = (uint32_t)kIapCmd_IAP_WriteEEPROMPage;
571 command[1] = pageNumber;
572 command[2] = (uint32_t)srcAddr;
573 command[3] = systemCoreClock / HZ_TO_KHZ_DIV;
574 iap_entry(command, result);
575
576 return translate_iap_status(result[0]);
577 }
578 #endif /* FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION */
579
580 #if defined(FSL_FEATURE_IAP_HAS_FAIM_FUNCTION) && FSL_FEATURE_IAP_HAS_FAIM_FUNCTION
581 /*!
582 * @brief Read FAIM page.
583 *
584 * This function is used to read given page of FAIM into the memory provided.
585 *
586 * @param pageNumber FAIM page number.
587 * @param dstAddr Memory address to store the value read from FAIM.
588 *
589 * @retval kStatus_IAP_Success Api has been executed successfully.
590 * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
591 */
IAP_ReadFAIMPage(uint32_t pageNumber,uint32_t * dstAddr)592 status_t IAP_ReadFAIMPage(uint32_t pageNumber, uint32_t *dstAddr)
593 {
594 uint32_t command[5] = {0x00U};
595 uint32_t result[5] = {0x00U};
596
597 command[0] = (uint32_t)kIapCmd_IAP_ReadFAIMPage;
598 command[1] = pageNumber;
599 command[2] = (uint32_t)dstAddr;
600 iap_entry(command, result);
601
602 return translate_iap_status(result[0]);
603 }
604
605 /*!
606 * @brief Write FAIM page.
607 *
608 * This function is used to write given data in the provided memory to a page of G.
609 *
610 * @param pageNumber FAIM page number.
611 * @param srcAddr Memory address holding data to be stored on to FAIM page.
612 *
613 * @retval kStatus_IAP_Success Api has been executed successfully.
614 * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
615 */
IAP_WriteFAIMPage(uint32_t pageNumber,uint32_t * srcAddr)616 status_t IAP_WriteFAIMPage(uint32_t pageNumber, uint32_t *srcAddr)
617 {
618 uint32_t command[5] = {0x00U};
619 uint32_t result[5] = {0x00U};
620
621 command[0] = (uint32_t)kIapCmd_IAP_WriteFAIMPage;
622 command[1] = pageNumber;
623 command[2] = (uint32_t)srcAddr;
624 iap_entry(command, result);
625
626 return translate_iap_status(result[0]);
627 }
628 #endif /* FSL_FEATURE_IAP_HAS_FAIM_FUNCTION */
629