1 /*
2  * Copyright 2018-2021, 2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_IAP_H_
9 #define _FSL_IAP_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup IAP_driver
15  * @{
16  */
17 
18 /*! @file */
19 
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 
24 /*! @name Driver version */
25 /*@{*/
26 #define FSL_IAP_DRIVER_VERSION (MAKE_VERSION(2, 0, 7))
27 /*@}*/
28 
29 /*!
30  * @brief iap status codes.
31  */
32 enum
33 {
34     kStatus_IAP_Success        = kStatus_Success,                   /*!< Api is executed successfully */
35     kStatus_IAP_InvalidCommand = MAKE_STATUS(kStatusGroup_IAP, 1U), /*!< Invalid command */
36     kStatus_IAP_SrcAddrError   = MAKE_STATUS(kStatusGroup_IAP, 2U), /*!< Source address is not on word boundary */
37     kStatus_IAP_DstAddrError =
38         MAKE_STATUS(kStatusGroup_IAP, 3U), /*!< Destination address is not on a correct boundary */
39     kStatus_IAP_SrcAddrNotMapped =
40         MAKE_STATUS(kStatusGroup_IAP, 4U), /*!< Source address is not mapped in the memory map */
41     kStatus_IAP_DstAddrNotMapped =
42         MAKE_STATUS(kStatusGroup_IAP, 5U), /*!< Destination address is not mapped in the memory map */
43     kStatus_IAP_CountError =
44         MAKE_STATUS(kStatusGroup_IAP, 6U), /*!< Byte count is not multiple of 4 or is not a permitted value */
45     kStatus_IAP_InvalidSector = MAKE_STATUS(
46         kStatusGroup_IAP,
47         7), /*!< Sector/page number is invalid or end sector/page number is greater than start sector/page number */
48     kStatus_IAP_SectorNotblank = MAKE_STATUS(kStatusGroup_IAP, 8U), /*!< One or more sectors are not blank */
49     kStatus_IAP_NotPrepared =
50         MAKE_STATUS(kStatusGroup_IAP, 9U), /*!< Command to prepare sector for write operation has not been executed */
51     kStatus_IAP_CompareError =
52         MAKE_STATUS(kStatusGroup_IAP, 10U),                /*!< Destination and source memory contents do not match */
53     kStatus_IAP_Busy = MAKE_STATUS(kStatusGroup_IAP, 11U), /*!< Flash programming hardware interface is busy */
54     kStatus_IAP_ParamError =
55         MAKE_STATUS(kStatusGroup_IAP, 12U), /*!< Insufficient number of parameters or invalid parameter */
56     kStatus_IAP_AddrError     = MAKE_STATUS(kStatusGroup_IAP, 13U), /*!< Address is not on word boundary */
57     kStatus_IAP_AddrNotMapped = MAKE_STATUS(kStatusGroup_IAP, 14U), /*!< Address is not mapped in the memory map */
58     kStatus_IAP_NoPower       = MAKE_STATUS(kStatusGroup_IAP, 24U), /*!< Flash memory block is powered down */
59     kStatus_IAP_NoClock = MAKE_STATUS(kStatusGroup_IAP, 27U), /*!< Flash memory block or controller is not clocked */
60     kStatus_IAP_ReinvokeISPConfig = MAKE_STATUS(kStatusGroup_IAP, 0x1CU), /*!< Reinvoke configuration error */
61 };
62 
63 /*!
64  * @brief iap command codes.
65  */
66 enum _iap_commands
67 {
68     kIapCmd_IAP_ReadFactorySettings   = 40U, /*!< Read the factory settings */
69     kIapCmd_IAP_PrepareSectorforWrite = 50U, /*!< Prepare Sector for write */
70     kIapCmd_IAP_CopyRamToFlash        = 51U, /*!< Copy RAM to flash */
71     kIapCmd_IAP_EraseSector           = 52U, /*!< Erase Sector */
72     kIapCmd_IAP_BlankCheckSector      = 53U, /*!< Blank check sector */
73     kIapCmd_IAP_ReadPartId            = 54U, /*!< Read part id */
74     kIapCmd_IAP_Read_BootromVersion   = 55U, /*!< Read bootrom version */
75     kIapCmd_IAP_Compare               = 56U, /*!< Compare */
76     kIapCmd_IAP_ReinvokeISP           = 57U, /*!< Reinvoke ISP */
77     kIapCmd_IAP_ReadUid               = 58U, /*!< Read Uid */
78     kIapCmd_IAP_ErasePage             = 59U, /*!< Erase Page */
79     kIapCmd_IAP_ReadSignature         = 70U, /*!< Read Signature */
80     kIapCmd_IAP_ExtendedReadSignature = 73U, /*!< Extended Read Signature */
81 #if defined(FSL_FEATURE_IAP_HAS_FAIM_FUNCTION) && FSL_FEATURE_IAP_HAS_FAIM_FUNCTION
82     kIapCmd_IAP_ReadFAIMPage  = 80U, /*!< Read FAIM page */
83     kIapCmd_IAP_WriteFAIMPage = 81U, /*!< Write FAIM page */
84 #else
85     kIapCmd_IAP_ReadEEPROMPage  = 80U, /*!< Read EEPROM page */
86     kIapCmd_IAP_WriteEEPROMPage = 81U, /*!< Write EEPROM page */
87 #endif /*FSL_FEATURE_IAP_HAS_FAIM_FUNCTION  */
88 };
89 
90 /*!
91  * @brief Flash memory access time.
92  */
93 enum _flash_access_time
94 {
95     kFlash_IAP_OneSystemClockTime   = 0U, /*! 1 system clock flash access time */
96     kFlash_IAP_TwoSystemClockTime   = 1U, /*! 2 system clock flash access time */
97     kFlash_IAP_ThreeSystemClockTime = 2U, /*! 3 system clock flash access time */
98 };
99 
100 /*******************************************************************************
101  * API
102  ******************************************************************************/
103 
104 #if defined(__cplusplus)
105 extern "C" {
106 #endif
107 
108 /*!
109  * @name Basic operations
110  * @{
111  */
112 
113 /*!
114  * @brief Read part identification number.
115  *
116  * This function is used to read the part identification number.
117  *
118  * @param partID Address to store the part identification number.
119  *
120  * @retval kStatus_IAP_Success Api has been executed successfully.
121  */
122 status_t IAP_ReadPartID(uint32_t *partID);
123 
124 /*!
125  * @brief Read boot code version number.
126  *
127  * This function is used to read the boot code version number.
128  *
129  * @param bootCodeVersion Address to store the boot code version.
130  *
131  * @retval kStatus_IAP_Success Api has been executed successfully.
132  *
133  * note Boot code version is two 32-bit words. Word 0 is the major version, word 1 is the minor version.
134  */
135 status_t IAP_ReadBootCodeVersion(uint32_t *bootCodeVersion);
136 
137 /*!
138  * @brief Reinvoke ISP.
139  *
140  * This function is used to invoke the boot loader in ISP mode. It maps boot vectors and configures the peripherals for
141  * ISP.
142  *
143  * @param ispType ISP type selection.
144  * @param status store the possible status.
145  *
146  * @retval kStatus_IAP_ReinvokeISPConfig reinvoke configuration error.
147  *
148  * note The error response will be returned when IAP is disabled or an invalid ISP type selection appears. The call
149  * won't return unless an error occurs, so there can be no status code.
150  */
151 void IAP_ReinvokeISP(uint8_t ispType, uint32_t *status);
152 
153 /*!
154  * @brief Read unique identification.
155  *
156  * This function is used to read the unique id.
157  *
158  * @param uniqueID store the uniqueID.
159  *
160  * @retval kStatus_IAP_Success Api has been executed successfully.
161  */
162 status_t IAP_ReadUniqueID(uint32_t *uniqueID);
163 
164 #if defined(FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION) && FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION
165 /*!
166  * @brief Read factory settings.
167  *
168  * This function reads the factory settings for calibration registers.
169  *
170  * @param dstRegAddr Address of the targeted calibration register.
171  * @param factoryValue Store the factory value
172  *
173  * @retval kStatus_IAP_Success Api has been executed successfully.
174  * @retval kStatus_IAP_ParamError Param0 is not one of the supported calibration registers.
175  */
176 status_t IAP_ReadFactorySettings(uint32_t dstRegAddr, uint32_t *factoryValue);
177 #endif /* FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION */
178 
179 /*@}*/
180 
181 #if defined(FSL_FEATURE_IAP_HAS_FLASH_FUNCTION) && FSL_FEATURE_IAP_HAS_FLASH_FUNCTION
182 /*!
183  * @name Flash operations
184  * @{
185  */
186 
187 #if defined(FLASH_CTRL_FLASHCFG_FLASHTIM_MASK)
188 /*!
189  * @brief Flash memory access time.
190  *
191  * This function is used to configure the access time to the flash memory.
192  *
193  * @param accessTime Flash memory access time FLASHTIM +1 is equal to the
194  *                   number of system clocks used for flash access.
195  */
196 void IAP_ConfigAccessFlashTime(uint32_t accessTime);
197 #endif
198 
199 /*!
200  * @brief Prepare sector for write operation.
201  *
202  * This function prepares sector(s) for write/erase operation. This function must be called before calling the
203  * IAP_CopyRamToFlash() or IAP_EraseSector() or IAP_ErasePage() function. The end sector number must be greater than or
204  * equal to the start sector number.
205  *
206  * @param startSector Start sector number.
207  * @param endSector End sector number.
208  *
209  * @retval kStatus_IAP_Success Api has been executed successfully.
210  * @retval kStatus_IAP_NoPower Flash memory block is powered down.
211  * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
212  * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number.
213  * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
214  */
215 status_t IAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector);
216 
217 /*!
218  * @brief Copy RAM to flash.
219  *
220  * This function programs the flash memory. Corresponding sectors must be prepared via IAP_PrepareSectorForWrite before
221  * calling this function.
222  *
223  * @param dstAddr Destination flash address where data bytes are to be written, the address should be multiples
224  *      of FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES boundary.
225  * @param srcAddr Source ram address from where data bytes are to be read.
226  * @param numOfBytes Number of bytes to be written, it should be multiples of FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES,
227  *      and ranges from FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES to FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES.
228  * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
229  *      flash controller has a fixed reference clock, this parameter is bypassed.
230  *
231  * @retval kStatus_IAP_Success Api has been executed successfully.
232  * @retval kStatus_IAP_NoPower Flash memory block is powered down.
233  * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
234  * @retval kStatus_IAP_SrcAddrError Source address is not on word boundary.
235  * @retval kStatus_IAP_DstAddrError Destination address is not on a correct boundary.
236  * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
237  * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
238  * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value.
239  * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
240  * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
241  */
242 status_t IAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock);
243 
244 /*!
245  * @brief Erase sector.
246  *
247  * This function erases sector(s). The end sector number must be greater than or equal to the start sector number.
248  *
249  * @param startSector Start sector number.
250  * @param endSector End sector number.
251  * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
252  * flash controller has a fixed reference clock, this parameter is bypassed.
253  *
254  * @retval kStatus_IAP_Success Api has been executed successfully.
255  * @retval kStatus_IAP_NoPower Flash memory block is powered down.
256  * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
257  * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number.
258  * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
259  * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
260  */
261 status_t IAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock);
262 
263 /*!
264  * @brief Erase page.
265  *
266  * This function erases page(s). The end page number must be greater than or equal to the start page number.
267  *
268  * @param startPage Start page number.
269  * @param endPage End page number.
270  * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
271  * flash controller has a fixed reference clock, this parameter is bypassed.
272  *
273  * @retval kStatus_IAP_Success Api has been executed successfully.
274  * @retval kStatus_IAP_NoPower Flash memory block is powered down.
275  * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
276  * @retval kStatus_IAP_InvalidSector Page number is invalid or end page number is greater than start page number.
277  * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
278  * @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
279  */
280 status_t IAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock);
281 
282 /*!
283  * @brief Blank check sector(s)
284  *
285  * Blank check single or multiples sectors of flash memory. The end sector number must be greater than or equal to the
286  * start sector number. It can be used to verify the sector erasure after IAP_EraseSector call.
287  *
288  * @param startSector Start sector number.
289  * @param endSector End sector number.
290  * @retval kStatus_IAP_Success One or more sectors are in erased state.
291  * @retval kStatus_IAP_NoPower Flash memory block is powered down.
292  * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
293  * @retval kStatus_IAP_SectorNotblank One or more sectors are not blank.
294  */
295 status_t IAP_BlankCheckSector(uint32_t startSector, uint32_t endSector);
296 
297 /*!
298  * @brief Compare memory contents of flash with ram.
299  *
300  * This function compares the contents of flash and ram. It can be used to verify the flash memory contents after
301  * IAP_CopyRamToFlash call.
302  *
303  * @param dstAddr Destination flash address.
304  * @param srcAddr Source ram address.
305  * @param numOfBytes Number of bytes to be compared.
306  *
307  * @retval kStatus_IAP_Success Contents of flash and ram match.
308  * @retval kStatus_IAP_NoPower Flash memory block is powered down.
309  * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
310  * @retval kStatus_IAP_AddrError Address is not on word boundary.
311  * @retval kStatus_IAP_AddrNotMapped Address is not mapped in the memory map.
312  * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value.
313  * @retval kStatus_IAP_CompareError Destination and source memory contents do not match.
314  */
315 status_t IAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes);
316 
317 #if defined(FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ
318 /*!
319  * @brief Extended Read signature.
320  *
321  * This function calculates the signature value for one or more pages of on-chip flash memory.
322  *
323  * @param startPage Start page number.
324  * @param endPage End page number.
325  * @param numOfStates Number of wait states.
326  * @param signature Address to store the signature value.
327  *
328  * @retval kStatus_IAP_Success Api has been executed successfully.
329  */
330 status_t IAP_ExtendedFlashSignatureRead(uint32_t startPage,
331                                         uint32_t endPage,
332                                         uint32_t numOfStates,
333                                         uint32_t *signature);
334 #endif /* FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ */
335 
336 #if defined(FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ
337 /*!
338  * @brief Read flash signature.
339  *
340  * This funtion is used to obtain a 32-bit signature value of the entire flash memory.
341  *
342  * @param signature Address to store the 32-bit generated signature value.
343  *
344  * @retval kStatus_IAP_Success Api has been executed successfully.
345  */
346 status_t IAP_ReadFlashSignature(uint32_t *signature);
347 #endif /* FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ */
348 
349 /*@}*/
350 #endif /* FSL_FEATURE_IAP_HAS_FLASH_FUNCTION */
351 
352 #if (defined(FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION) && (FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION == 1))
353 /*!
354  * @name EEPROM operations
355  * @{
356  */
357 
358 /*!
359  * @brief Read EEPROM page.
360  *
361  * This function is used to read given page of EEPROM into the memory provided.
362  *
363  * @param pageNumber EEPROM page number.
364  * @param dstAddr Memory address to store the value read from EEPROM.
365  * @param systemCoreClock Current core clock frequency in kHz.
366  *
367  * @retval kStatus_IAP_Success Api has been executed successfully.
368  * @retval kStatus_IAP_InvalidSector Sector number is invalid.
369  * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
370  *
371  * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM.
372  */
373 status_t IAP_ReadEEPROMPage(uint32_t pageNumber, uint32_t *dstAddr, uint32_t systemCoreClock);
374 
375 /*!
376  * @brief Write EEPROM page.
377  *
378  * This function is used to write given data in the provided memory to a page of EEPROM.
379  *
380  * @param pageNumber EEPROM page number.
381  * @param srcAddr Memory address holding data to be stored on to EEPROM page.
382  * @param systemCoreClock Current core clock frequency in kHz.
383  *
384  * @retval kStatus_IAP_Success Api has been executed successfully.
385  * @retval kStatus_IAP_InvalidSector Sector number is invalid.
386  * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
387  *
388  * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM
389  */
390 status_t IAP_WriteEEPROMPage(uint32_t pageNumber, uint32_t *srcAddr, uint32_t systemCoreClock);
391 
392 /*@}*/
393 #endif /* FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION */
394 
395 #if defined(FSL_FEATURE_IAP_HAS_FAIM_FUNCTION) && FSL_FEATURE_IAP_HAS_FAIM_FUNCTION
396 /*!
397  * @name FAIM operations
398  * @{
399  */
400 
401 /*!
402  * @brief Read FAIM page.
403  *
404  * This function is used to read given page of FAIM into the memory provided.
405  *
406  * @param pageNumber FAIM page number.
407  * @param dstAddr Memory address to store the value read from FAIM.
408  *
409  * @retval kStatus_IAP_Success Api has been executed successfully.
410  * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
411  */
412 status_t IAP_ReadFAIMPage(uint32_t pageNumber, uint32_t *dstAddr);
413 
414 /*!
415  * @brief Write FAIM page.
416  *
417  * This function is used to write given data in the provided memory to a page of G.
418  *
419  * @param pageNumber FAIM page number.
420  * @param srcAddr Memory address holding data to be stored on to FAIM page.
421  *
422  * @retval kStatus_IAP_Success Api has been executed successfully.
423  * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
424  */
425 status_t IAP_WriteFAIMPage(uint32_t pageNumber, uint32_t *srcAddr);
426 #endif /* FSL_FEATURE_IAP_HAS_FAIM_FUNCTION */
427 
428 /*@}*/
429 
430 #ifdef __cplusplus
431 }
432 #endif
433 
434 /*@}*/
435 
436 #endif /* _FSL_IAP_H_ */
437