1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_flashiap.h"
10 
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.flashiap"
14 #endif
15 
16 #define HZ_TO_KHZ_DIV 1000UL
17 
18 /*******************************************************************************
19  * Code
20  ******************************************************************************/
21 
translate_iap_status(int32_t status)22 static status_t translate_iap_status(int32_t status)
23 {
24     /* Translate IAP return code to sdk status code */
25     if (status == (int32_t)kStatus_Success)
26     {
27         return status;
28     }
29     else
30     {
31         return MAKE_STATUS((int32_t)kStatusGroup_FLASHIAP, status);
32     }
33 }
34 
35 /*!
36  * brief	Prepare sector for write operation
37 
38  * This function prepares sector(s) for write/erase operation. This function must be
39  * called before calling the FLASHIAP_CopyRamToFlash() or FLASHIAP_EraseSector() or
40  * FLASHIAP_ErasePage() function. The end sector must be greater than or equal to
41  * start sector number.
42  *
43  * deprecated Do not use this function. It has benn moved to iap driver.
44  *
45  * param startSector Start sector number.
46  * param endSector End sector number.
47  *
48  * retval #kStatus_FLASHIAP_Success Api was executed successfully.
49  * retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down.
50  * retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked.
51  * retval #kStatus_FLASHIAP_InvalidSector Sector number is invalid or end sector number
52  *         is greater than start sector number.
53  * retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy.
54  */
FLASHIAP_PrepareSectorForWrite(uint32_t startSector,uint32_t endSector)55 status_t FLASHIAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector)
56 {
57     uint32_t command[5] = {0x00U};
58     uint32_t result[4]  = {0x00U};
59 
60     command[0] = (uint32_t)kIapCmd_FLASHIAP_PrepareSectorforWrite;
61     command[1] = startSector;
62     command[2] = endSector;
63     iap_entry(command, result);
64 
65     return translate_iap_status((int32_t)result[0]);
66 }
67 
68 /*!
69  * brief	Copy RAM to flash.
70 
71  * This function programs the flash memory. Corresponding sectors must be prepared
72  * via FLASHIAP_PrepareSectorForWrite before calling calling this function. The addresses
73  * should be a 256 byte boundary and the number of bytes should be 256 | 512 | 1024 | 4096.
74  *
75  * deprecated Do not use this function. It has benn moved to iap driver.
76  *
77  * param dstAddr Destination flash address where data bytes are to be written.
78  * param srcAddr Source ram address from where data bytes are to be read.
79  * param numOfBytes Number of bytes to be written.
80  * param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the
81  *                        rom IAP function.
82  *
83  * retval #kStatus_FLASHIAP_Success Api was executed successfully.
84  * retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down.
85  * retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked.
86  * retval #kStatus_FLASHIAP_SrcAddrError Source address is not on word boundary.
87  * retval #kStatus_FLASHIAP_DstAddrError Destination address is not on a correct boundary.
88  * retval #kStatus_FLASHIAP_SrcAddrNotMapped Source address is not mapped in the memory map.
89  * retval #kStatus_FLASHIAP_DstAddrNotMapped Destination address is not mapped in the memory map.
90  * retval #kStatus_FLASHIAP_CountError Byte count is not multiple of 4 or is not a permitted value.
91  * retval #kStatus_FLASHIAP_NotPrepared Command to prepare sector for write operation was not executed.
92  * retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy.
93  */
FLASHIAP_CopyRamToFlash(uint32_t dstAddr,uint32_t * srcAddr,uint32_t numOfBytes,uint32_t systemCoreClock)94 status_t FLASHIAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock)
95 {
96     uint32_t command[5] = {0x00U};
97     uint32_t result[4]  = {0x00U};
98 
99     command[0] = (uint32_t)kIapCmd_FLASHIAP_CopyRamToFlash;
100     command[1] = dstAddr;
101     command[2] = (uint32_t)srcAddr;
102     command[3] = numOfBytes;
103     command[4] = systemCoreClock / HZ_TO_KHZ_DIV;
104     iap_entry(command, result);
105 
106     return translate_iap_status((int32_t)result[0]);
107 }
108 
109 /*!
110  * brief	Erase sector
111 
112  * This function erases sector(s). The end sector must be greater than or equal to
113  * start sector number. FLASHIAP_PrepareSectorForWrite must be called before
114  * calling this function.
115  *
116  * deprecated Do not use this function. It has benn moved to iap driver.
117  *
118  * param startSector Start sector number.
119  * param endSector End sector number.
120  * param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the
121  *                        rom IAP function.
122  *
123  * retval #kStatus_FLASHIAP_Success Api was executed successfully.
124  * retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down.
125  * retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked.
126  * retval #kStatus_FLASHIAP_InvalidSector Sector number is invalid or end sector number
127  *         is greater than start sector number.
128  * retval #kStatus_FLASHIAP_NotPrepared Command to prepare sector for write operation was not executed.
129  * retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy.
130  */
FLASHIAP_EraseSector(uint32_t startSector,uint32_t endSector,uint32_t systemCoreClock)131 status_t FLASHIAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock)
132 {
133     uint32_t command[5] = {0x00U};
134     uint32_t result[4]  = {0x00U};
135 
136     command[0] = (uint32_t)kIapCmd_FLASHIAP_EraseSector;
137     command[1] = startSector;
138     command[2] = endSector;
139     command[3] = systemCoreClock / HZ_TO_KHZ_DIV;
140     iap_entry(command, result);
141 
142     return translate_iap_status((int32_t)result[0]);
143 }
144 
145 /*!
146 
147  * This function erases page(s). The end page must be greater than or equal to
148  * start page number. Corresponding sectors must be prepared via FLASHIAP_PrepareSectorForWrite
149  * before calling calling this function.
150  *
151  * deprecated Do not use this function. It has benn moved to iap driver.
152  *
153  * param startPage Start page number
154  * param endPage End page number
155  * param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the
156  *                        rom IAP function.
157  *
158  * retval #kStatus_FLASHIAP_Success Api was executed successfully.
159  * retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down.
160  * retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked.
161  * retval #kStatus_FLASHIAP_InvalidSector Page number is invalid or end page number
162  *         is greater than start page number
163  * retval #kStatus_FLASHIAP_NotPrepared Command to prepare sector for write operation was not executed.
164  * retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy.
165  */
FLASHIAP_ErasePage(uint32_t startPage,uint32_t endPage,uint32_t systemCoreClock)166 status_t FLASHIAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock)
167 {
168     uint32_t command[5] = {0x00U};
169     uint32_t result[4]  = {0x00U};
170 
171     command[0] = (uint32_t)kIapCmd_FLASHIAP_ErasePage;
172     command[1] = startPage;
173     command[2] = endPage;
174     command[3] = systemCoreClock / HZ_TO_KHZ_DIV;
175     iap_entry(command, result);
176 
177     return translate_iap_status((int32_t)result[0]);
178 }
179 
180 /*!
181  * brief Blank check sector(s)
182  *
183  * Blank check single or multiples sectors of flash memory. The end sector must be greater than or equal to
184  * start sector number. It can be used to verify the sector eraseure after FLASHIAP_EraseSector call.
185  *
186  * deprecated Do not use this function. It has benn moved to iap driver.
187  *
188  * param	startSector	: Start sector number. Must be greater than or equal to start sector number
189  * param	endSector	: End sector number
190  * retval #kStatus_FLASHIAP_Success One or more sectors are in erased state.
191  * retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down.
192  * retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked.
193  * retval #kStatus_FLASHIAP_SectorNotblank One or more sectors are not blank.
194  */
FLASHIAP_BlankCheckSector(uint32_t startSector,uint32_t endSector)195 status_t FLASHIAP_BlankCheckSector(uint32_t startSector, uint32_t endSector)
196 {
197     uint32_t command[5] = {0x00U};
198     uint32_t result[4]  = {0x00U};
199 
200     command[0] = (uint32_t)kIapCmd_FLASHIAP_BlankCheckSector;
201     command[1] = startSector;
202     command[2] = endSector;
203     iap_entry(command, result);
204 
205     return translate_iap_status((int32_t)result[0]);
206 }
207 
208 /*!
209  * brief Compare memory contents of flash with ram.
210 
211  * This function compares the contents of flash and ram. It can be used to verify the flash
212  * memory contents after FLASHIAP_CopyRamToFlash call.
213  *
214  * deprecated Do not use this function. It has benn moved to iap driver.
215  *
216  * param dstAddr Destination flash address.
217  * param srcAddr Source ram address.
218  * param numOfBytes Number of bytes to be compared.
219  *
220  * retval #kStatus_FLASHIAP_Success Contents of flash and ram match.
221  * retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down.
222  * retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked.
223  * retval #kStatus_FLASHIAP_AddrError Address is not on word boundary.
224  * retval #kStatus_FLASHIAP_AddrNotMapped Address is not mapped in the memory map.
225  * retval #kStatus_FLASHIAP_CountError Byte count is not multiple of 4 or is not a permitted value.
226  * retval #kStatus_FLASHIAP_CompareError Destination and source memory contents do not match.
227  */
FLASHIAP_Compare(uint32_t dstAddr,uint32_t * srcAddr,uint32_t numOfBytes)228 status_t FLASHIAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes)
229 {
230     uint32_t command[5] = {0x00U};
231     uint32_t result[4]  = {0x00U};
232 
233     command[0] = (uint32_t)kIapCmd_FLASHIAP_Compare;
234     command[1] = dstAddr;
235     command[2] = (uint32_t)srcAddr;
236     command[3] = numOfBytes;
237     iap_entry(command, result);
238 
239     return translate_iap_status((int32_t)result[0]);
240 }
241