1 /*
2 * Copyright 2023, NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #ifndef _FSL_ROMAPI_H_
9 #define _FSL_ROMAPI_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup romapi
15 * @{
16 */
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /* Component ID definition, used by tools. */
23 #ifndef FSL_COMPONENT_ID
24 #define FSL_COMPONENT_ID "platform.drivers.romapi"
25 #endif
26
27 /*! @name Driver version */
28 /*@{*/
29
30 /*! @brief romapi driver version 2.0.0. */
31 #define FSL_ROMAPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
32 /*@}*/
33
34 /*!
35 * @name Flash status
36 * @{
37 */
38 /*! @brief Flash driver status group. */
39 #if defined(kStatusGroup_FlashDriver)
40 #define kStatusGroupGeneric kStatusGroup_Generic
41 #define kStatusGroupFlashDriver kStatusGroup_FlashDriver
42 #elif defined(kStatusGroup_FLASHIAP)
43 #define kStatusGroupGeneric kStatusGroup_Generic
44 #define kStatusGroupFlashDriver kStatusGroup_FLASH
45 #else
46 #define kStatusGroupGeneric 0
47 #define kStatusGroupFlashDriver 1
48 #endif
49
50 /*! @brief Constructs a status code value from a group and a code number. */
51 #if !defined(MAKE_STATUS)
52 #define MAKE_STATUS(group, code) ((((group) * 100) + (code)))
53 #endif
54
55 /*!
56 * @brief Flash driver status codes.
57 */
58 enum
59 {
60 kStatus_FLASH_Success = MAKE_STATUS(kStatusGroupGeneric, 0), /*!< API is executed successfully*/
61 kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroupGeneric, 4), /*!< Invalid argument*/
62 kStatus_FLASH_SizeError = MAKE_STATUS(kStatusGroupFlashDriver, 0), /*!< Error size*/
63 kStatus_FLASH_AlignmentError =
64 MAKE_STATUS(kStatusGroupFlashDriver, 1), /*!< Parameter is not aligned with the specified baseline*/
65 kStatus_FLASH_AddressError = MAKE_STATUS(kStatusGroupFlashDriver, 2), /*!< Address is out of range */
66 kStatus_FLASH_AccessError =
67 MAKE_STATUS(kStatusGroupFlashDriver, 3), /*!< Invalid instruction codes and out-of bound addresses */
68 kStatus_FLASH_ProtectionViolation = MAKE_STATUS(
69 kStatusGroupFlashDriver, 4), /*!< The program/erase operation is requested to execute on protected areas */
70 kStatus_FLASH_CommandFailure =
71 MAKE_STATUS(kStatusGroupFlashDriver, 5), /*!< Run-time error during command execution. */
72 kStatus_FLASH_UnknownProperty = MAKE_STATUS(kStatusGroupFlashDriver, 6), /*!< Unknown property.*/
73 kStatus_FLASH_EraseKeyError = MAKE_STATUS(kStatusGroupFlashDriver, 7) /*!< API erase key is invalid.*/
74 };
75 /*@}*/
76
77 /*!
78 * @brief Enumeration for various flash properties.
79 */
80 typedef enum _flash_property_tag
81 {
82 kFLASH_PropertyPflashSectorSize = 0x00U, /*!< Pflash sector size property.*/
83 kFLASH_PropertyPflashTotalSize = 0x01U, /*!< Pflash total size property.*/
84 kFLASH_PropertyPflashBlockSize = 0x02U, /*!< Pflash block size property.*/
85 kFLASH_PropertyPflashBlockCount = 0x03U, /*!< Pflash block count property.*/
86 kFLASH_PropertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/
87 kFLASH_PropertyPflashPageSize = 0x30U, /*!< Pflash page size property.*/
88 kFLASH_PropertyPflashSystemFreq = 0x31U, /*!< System Frequency property.*/
89 kFLASH_PropertyFfrSectorSize = 0x40U, /*!< FFR sector size property.*/
90 kFLASH_PropertyFfrTotalSize = 0x41U, /*!< FFR total size property.*/
91 kFLASH_PropertyFfrBlockBaseAddr = 0x42U, /*!< FFR block base address property.*/
92 kFLASH_PropertyFfrPageSize = 0x43U, /*!< FFR page size property.*/
93 } flash_property_tag_t;
94
95 /*! @brief Flash controller paramter config. */
96 typedef struct _flash_ffr_config
97 {
98 uint32_t ffrBlockBase;
99 uint32_t ffrTotalSize;
100 uint32_t ffrPageSize;
101 uint32_t sectorSize;
102 uint32_t cfpaPageVersion;
103 uint32_t cfpaPageOffset;
104 } flash_ffr_config_t;
105
106 /*! @brief Flash driver state information.
107 *
108 * An instance of this structure is allocated by the user of the flash driver and
109 * passed into each of the driver APIs.
110 */
111 typedef struct _flash_config
112 {
113 uint32_t PFlashBlockBase; /*!< A base address of the first PFlash block */
114 uint32_t PFlashTotalSize; /*!< The size of the combined PFlash block. */
115 uint32_t PFlashBlockCount; /*!< A number of PFlash blocks. */
116 uint32_t PFlashPageSize; /*!< The size in bytes of a page of PFlash. */
117 uint32_t PFlashSectorSize; /*!< The size in bytes of a sector of PFlash. */
118 flash_ffr_config_t ffrConfig;
119 } flash_config_t;
120
121 /*! @brief Interface for the flash driver. */
122 typedef struct _flash_driver_interface
123 {
124 /* Flash driver */
125 status_t (*flash_init)(flash_config_t *config);
126 status_t (*flash_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key);
127 status_t (*flash_program_phrase)(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes);
128 status_t (*flash_program_page)(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes);
129 status_t (*flash_verify_program)(flash_config_t *config,
130 uint32_t start,
131 uint32_t lengthInBytes,
132 const uint8_t *expectedData,
133 uint32_t *failedAddress,
134 uint32_t *failedData);
135 status_t (*flash_verify_erase_phrase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
136 status_t (*flash_verify_erase_page)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
137 status_t (*flash_verify_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
138 status_t (*flash_get_property)(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value);
139 /* IFR driver */
140 status_t (*ifr_verify_erase_phrase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
141 status_t (*ifr_verify_erase_page)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
142 status_t (*ifr_verify_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
143 status_t (*flash_read)(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
144 /* version */
145 uint32_t version;
146 } flash_driver_interface_t;
147
148 /*! @brief Constructs the four character code for the Flash driver API key. */
149 #if !defined(FOUR_CHAR_CODE)
150 #define FOUR_CHAR_CODE(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a)))
151 #endif
152
153 /*!
154 * @brief Enumeration for Flash driver API keys.
155 *
156 * @note The resulting value is built with a byte order such that the string
157 * being readable in expected order when viewed in a hex editor, if the value
158 * is treated as a 32-bit little endian value.
159 */
160 enum _flash_driver_api_keys
161 {
162 kFLASH_ApiEraseKey = FOUR_CHAR_CODE('l', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/
163 };
164
165 /* API prototype fields definition.
166 | 31 : 24 | 23 : 20 | 19 : 16 | 15 : 12 | 11 : 8 | 7 : 0 |
167 | Tag | Boot mode | bootloader periphal| Instance | Image Index| Reserved |
168 | | | | Used For Boot mode 0| | |
169 | | 0: Passive mode | 0 - Auto detection | | | |
170 | | 1: ISP mode | 1 - USB-HID | | | |
171 | | | 2 - UART | | | |
172 | | | 3 - SPI | | | |
173 | | | 4 - I2C | | | |
174 | | | 5 - CAN | | | |
175 */
176 typedef struct
177 {
178 union
179 {
180 struct
181 {
182 uint32_t reserved : 8;
183 uint32_t boot_image_index : 4;
184 uint32_t instance : 4;
185 uint32_t boot_interface : 4;
186 uint32_t mode : 4;
187 uint32_t tag : 8;
188 } B;
189 uint32_t U;
190 } option;
191 } user_app_boot_invoke_option_t;
192
193 /*! @brief Root of the bootloader API tree.
194 *
195 * An instance of this struct resides in read-only memory in the bootloader. It
196 * provides a user application access to APIs exported by the bootloader.
197 *
198 */
199 typedef struct _bootloader_tree
200 {
201 void (*run_bootloader)(void *arg); /*!< Function to start the bootloader executing. */
202 const flash_driver_interface_t *flash_driver; /*!< Internal Flash driver API. */
203 void (*jump)(void *arg);
204 } bootloader_tree_t;
205
206 /** ROM API base address */
207 #define ROM_API_BASE (0x03003fe0u)
208 /** ROM API base pointer */
209 #define ROM_API ((bootloader_tree_t *)ROM_API_BASE)
210 /** FLASH API base pointer */
211 #define FLASH_API (ROM_API->flash_driver)
212
213 /*!
214 * @name Flash API
215 * @{
216 */
217
218 /*!
219 * @brief Initializes the global flash properties structure members
220 *
221 * This function checks and initializes the Flash module for the other Flash APIs.
222 *
223 * @param config Pointer to the storage for the driver runtime state.
224 *
225 */
FLASH_Init(flash_config_t * config)226 static inline status_t FLASH_Init(flash_config_t *config)
227 {
228 return FLASH_API->flash_init(config);
229 }
230
231 /*!
232 * @brief Erases the flash sectors encompassed by parameters passed into function
233 *
234 * This function erases the appropriate number of flash sectors based on the
235 * desired start address and length.
236 *
237 * @param config The pointer to the storage for the driver runtime state.
238 * @param start The start address of the desired flash memory to be erased.
239 * NOTE: The start address need to be 4 Bytes-aligned.
240 *
241 * @param lengthInBytes The length, given in bytes need be 4 Bytes-aligned.
242 *
243 * @param key The value used to validate all flash erase APIs.
244 *
245 */
FLASH_EraseSector(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,uint32_t key)246 static inline status_t FLASH_EraseSector(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key)
247 {
248 return FLASH_API->flash_erase_sector(config, start, lengthInBytes, key);
249 }
250
251 /*!
252 * @brief Programs flash phrases with data at locations passed in through parameters
253 *
254 * This function programs the flash memory with the desired data for a given
255 * flash area as determined by the start address and the length.
256 *
257 * @param config A pointer to the storage for the driver runtime state.
258 * @param start The start address of the desired flash memory to be programmed. Must be
259 * word-aligned.
260 * @param src A pointer to the source buffer of data that is to be programmed
261 * into the flash.
262 * @param lengthInBytes The length, given in bytes (not words or long-words),
263 * to be programmed. Must be word-aligned.
264 *
265 */
FLASH_ProgramPhrase(flash_config_t * config,uint32_t start,uint8_t * src,uint32_t lengthInBytes)266 static inline status_t FLASH_ProgramPhrase(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
267 {
268 return FLASH_API->flash_program_phrase(config, start, src, lengthInBytes);
269 }
270
271 /*!
272 * @brief Programs flash page with data at locations passed in through parameters
273 *
274 * This function programs the flash memory with the desired data for a given
275 * flash area as determined by the start address and the length.
276 *
277 * @param config A pointer to the storage for the driver runtime state.
278 * @param start The start address of the desired flash memory to be programmed. Must be
279 * word-aligned.
280 * @param src A pointer to the source buffer of data that is to be programmed
281 * into the flash.
282 * @param lengthInBytes The length, given in bytes (not words or long-words),
283 * to be programmed. Must be word-aligned.
284 *
285 */
FLASH_ProgramPage(flash_config_t * config,uint32_t start,uint8_t * src,uint32_t lengthInBytes)286 static inline status_t FLASH_ProgramPage(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
287 {
288 return FLASH_API->flash_program_page(config, start, src, lengthInBytes);
289 }
290
291 /*!
292 * @brief Verifies programming of the desired flash area
293 *
294 * This function verifies the data programed in the flash memory using the
295 * Flash Program Check Command and compares it to the expected data for a given
296 * flash area as determined by the start address and length.
297 *
298 * @param config A pointer to the storage for the driver runtime state.
299 * @param start The start address of the desired flash memory to be verified. Must be word-aligned.
300 * @param lengthInBytes The length, given in bytes (not words or long-words),
301 * to be verified. Must be word-aligned.
302 * @param expectedData A pointer to the expected data that is to be
303 * verified against.
304 * @param failedAddress A pointer to the returned failing address.
305 * @param failedData A pointer to the returned failing data. Some derivatives do
306 * not include failed data as part of the FCCOBx registers. In this
307 * case, zeros are returned upon failure.
308 *
309 */
FLASH_VerifyProgram(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,const uint8_t * expectedData,uint32_t * failedAddress,uint32_t * failedData)310 static inline status_t FLASH_VerifyProgram(flash_config_t *config,
311 uint32_t start,
312 uint32_t lengthInBytes,
313 const uint8_t *expectedData,
314 uint32_t *failedAddress,
315 uint32_t *failedData)
316 {
317 return FLASH_API->flash_verify_program(config, start, lengthInBytes, expectedData, failedAddress, failedData);
318 }
319
320 /*!
321 * @brief Verify that the flash phrases are erased
322 *
323 * This function checks the appropriate number of flash sectors based on
324 * the desired start address and length to check whether the flash is erased
325 *
326 * @param config A pointer to the storage for the driver runtime state.
327 * @param start The start address of the desired flash memory to be verified.
328 * The start address does not need to be sector-aligned but must be word-aligned.
329 * @param lengthInBytes The length, given in bytes (not words or long-words),
330 * to be verified. Must be word-aligned.
331 *
332 */
FLASH_VerifyErasePhrase(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)333 static inline status_t FLASH_VerifyErasePhrase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
334 {
335 return FLASH_API->flash_verify_erase_phrase(config, start, lengthInBytes);
336 }
337
338 /*!
339 * @brief Verify that the flash pages are erased
340 *
341 * This function checks the appropriate number of flash sectors based on
342 * the desired start address and length to check whether the flash is erased
343 *
344 * @param config A pointer to the storage for the driver runtime state.
345 * @param start The start address of the desired flash memory to be verified.
346 * The start address does not need to be sector-aligned but must be word-aligned.
347 * @param lengthInBytes The length, given in bytes (not words or long-words),
348 * to be verified. Must be word-aligned.
349 *
350 */
FLASH_VerifyErasePage(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)351 static inline status_t FLASH_VerifyErasePage(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
352 {
353 return FLASH_API->flash_verify_erase_page(config, start, lengthInBytes);
354 }
355
356 /*!
357 * @brief Verify that the flash sectors are erased
358 *
359 * This function checks the appropriate number of flash sectors based on
360 * the desired start address and length to check whether the flash is erased
361 *
362 * @param config A pointer to the storage for the driver runtime state.
363 * @param start The start address of the desired flash memory to be verified.
364 * The start address does not need to be sector-aligned but must be word-aligned.
365 * @param lengthInBytes The length, given in bytes (not words or long-words),
366 * to be verified. Must be word-aligned.
367 *
368 */
FLASH_VerifyEraseSector(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)369 static inline status_t FLASH_VerifyEraseSector(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
370 {
371 return FLASH_API->flash_verify_erase_sector(config, start, lengthInBytes);
372 }
373
374 /*!
375 * @brief Returns the desired flash property
376 *
377 * @param config A pointer to the storage for the driver runtime state.
378 * @param whichProperty The desired property from the list of properties in
379 * enum flash_property_tag_t
380 * @param value A pointer to the value returned for the desired flash property.
381 *
382 */
FLASH_GetProperty(flash_config_t * config,flash_property_tag_t whichProperty,uint32_t * value)383 static inline status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value)
384 {
385 return FLASH_API->flash_get_property(config, whichProperty, value);
386 }
387
388 /*!
389 * @brief Verify that the IFR0 phrases are erased
390 *
391 * This function checks the appropriate number of flash sectors based on
392 * the desired start address and length to check whether the flash is erased
393 *
394 * @param config A pointer to the storage for the driver runtime state.
395 * @param start The start address of the desired flash memory to be verified.
396 * The start address does not need to be sector-aligned but must be word-aligned.
397 * @param lengthInBytes The length, given in bytes (not words or long-words),
398 * to be verified. Must be word-aligned.
399 *
400 */
IFR_VerifyErasePhrase(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)401 static inline status_t IFR_VerifyErasePhrase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
402 {
403 return FLASH_API->ifr_verify_erase_phrase(config, start, lengthInBytes);
404 }
405
406 /*!
407 * @brief Verify that the IFR0 pages are erased
408 *
409 * This function checks the appropriate number of flash sectors based on
410 * the desired start address and length to check whether the flash is erased
411 *
412 * @param config A pointer to the storage for the driver runtime state.
413 * @param start The start address of the desired flash memory to be verified.
414 * The start address does not need to be sector-aligned but must be word-aligned.
415 * @param lengthInBytes The length, given in bytes (not words or long-words),
416 * to be verified. Must be word-aligned.
417 *
418 */
IFR_VerifyErasePage(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)419 static inline status_t IFR_VerifyErasePage(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
420 {
421 return FLASH_API->ifr_verify_erase_page(config, start, lengthInBytes);
422 }
423
424 /*!
425 * @brief Verify that the IFR0 sectors are erased
426 *
427 * This function checks the appropriate number of flash sectors based on
428 * the desired start address and length to check whether the flash is erased
429 *
430 * @param config A pointer to the storage for the driver runtime state.
431 * @param start The start address of the desired flash memory to be verified.
432 * The start address does not need to be sector-aligned but must be word-aligned.
433 * @param lengthInBytes The length, given in bytes (not words or long-words),
434 * to be verified. Must be word-aligned.
435 *
436 */
IFR_VerifyEraseSector(flash_config_t * config,uint32_t start,uint32_t lengthInBytes)437 static inline status_t IFR_VerifyEraseSector(flash_config_t *config, uint32_t start, uint32_t lengthInBytes)
438 {
439 return FLASH_API->ifr_verify_erase_sector(config, start, lengthInBytes);
440 }
441
442 /*!
443 * @brief Reads flash at locations passed in through parameters
444 *
445 * This function read the flash memory from a given flash area as determined
446 * by the start address and the length.
447 *
448 * @param config A pointer to the storage for the driver runtime state.
449 * @param start The start address of the desired flash memory to be read.
450 * @param dest A pointer to the dest buffer of data that is to be read
451 * from the flash.
452 * @param lengthInBytes The length, given in bytes (not words or long-words),
453 * to be read.
454 *
455 */
FLASH_Read(flash_config_t * config,uint32_t start,uint8_t * dest,uint32_t lengthInBytes)456 static inline status_t FLASH_Read(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
457 {
458 return FLASH_API->flash_read(config, start, dest, lengthInBytes);
459 }
460
461 /*!
462 * @brief Get ROM API version.
463 *
464 * This function read the ROM API version.
465 *
466 */
ROMAPI_GetVersion(void)467 static inline uint32_t ROMAPI_GetVersion(void)
468 {
469 return FLASH_API->version;
470 }
471
472 /*!
473 * @brief Run the Bootloader API to force into the ISP mode base on the user arg
474 *
475 * @param arg Indicates API prototype fields definition.
476 * Refer to the above #user_app_boot_invoke_option_t structure
477 */
ROMAPI_RunBootloader(void * arg)478 static inline void ROMAPI_RunBootloader(void *arg)
479 {
480 ROM_API->run_bootloader(arg);
481 }
482
483 /*!
484 * @brief Get the UUID
485 *
486 * @param uuid UUID data array
487 *
488 */
ROMAPI_GetUUID(uint8_t * uuid)489 static inline void ROMAPI_GetUUID(uint8_t *uuid)
490 {
491 #define MCXA_UUID_ADDR (0x01100800U)
492 #define MCXA_UUID_SIZE (16U)
493
494 uint8_t *p = (uint8_t *)MCXA_UUID_ADDR;
495 for (uint8_t i = 0; i < MCXA_UUID_SIZE; i++)
496 {
497 *uuid = *p;
498 uuid++;
499 p++;
500 }
501 }
502
503 /* @} */
504
505 /*! @} */
506
507 #endif /* _FSL_RESET_H_ */
508