1 /******************************************************************************
2  *  Copyright (c) 2022-2023 Texas Instruments Incorporated
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions are met:
6  *
7  *  1) Redistributions of source code must retain the above copyright notice,
8  *     this list of conditions and the following disclaimer.
9  *
10  *  2) Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *
14  *  3) Neither the name of the copyright holder nor the names of its
15  *     contributors may be used to endorse or promote products derived from this
16  *     software without specific prior written permission.
17  *
18  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  *  POSSIBILITY OF SUCH DAMAGE.
29  *
30  ******************************************************************************/
31 
32 #ifndef __FLASH_H__
33 #define __FLASH_H__
34 
35 //*****************************************************************************
36 //
37 //! \addtogroup system_control_group
38 //! @{
39 //! \addtogroup flash_api
40 //! @{
41 //
42 //*****************************************************************************
43 
44 //*****************************************************************************
45 //
46 // If building with a C++ compiler, make all of the definitions in this header
47 // have a C binding.
48 //
49 //*****************************************************************************
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 #include <stdbool.h>
55 #include <stdint.h>
56 
57 #include "../inc/hw_types.h"
58 #include "../inc/hw_flash.h"
59 #include "../inc/hw_memmap.h"
60 #include "../inc/hw_ints.h"
61 #include "../inc/hw_fcfg.h"
62 #include "../inc/hw_vims.h"
63 #include "hapi.h"
64 #include "chipinfo.h"
65 #include "interrupt.h"
66 #include "debug.h"
67 
68 //*****************************************************************************
69 // Values that can be returned from the API functions
70 //*****************************************************************************
71 #define FAPI_STATUS_SUCCESS                     0x00000000 ///< Function completed successfully
72 #define FAPI_STATUS_FSM_BUSY                    0x00000001 ///< FSM is Busy
73 #define FAPI_STATUS_FSM_READY                   0x00000002 ///< FSM is Ready
74 #define FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH 0x00000003 ///< Incorrect parameter value
75 #define FAPI_STATUS_FSM_ERROR                   0x00000004 ///< Flash program/erase operation failed
76 #define FAPI_STATUS_ADDRESS_ERROR               0x00000005 ///< Address range or alignment error
77 #define FAPI_STATUS_INVALID_KEY                 0x00000010 ///< Invalid random jump protection key
78 
79 //*****************************************************************************
80 //
81 //! \brief Get size of a flash sector in number of bytes.
82 //!
83 //! This function will return the size of a flash sector in number of bytes.
84 //!
85 //! \return Returns size of a flash sector in number of bytes.
86 //
87 //*****************************************************************************
FlashGetSectorSize(void)88 __STATIC_INLINE uint32_t FlashGetSectorSize(void)
89 {
90     return (FLASH_MAIN_SECTOR_SIZE);
91 }
92 
93 //*****************************************************************************
94 //
95 //! \brief Get the size of the flash.
96 //!
97 //! This function returns the size of the flash main bank in number of bytes.
98 //!
99 //! \return Returns the flash size in number of bytes.
100 //
101 //*****************************************************************************
FlashGetSize(void)102 __STATIC_INLINE uint32_t FlashGetSize(void)
103 {
104     // Return flash size in number of bytes
105     return (FLASH_MAIN_SIZE);
106 }
107 
108 //*****************************************************************************
109 //
110 //! \brief Checks if the Flash state machine has detected an error.
111 //!
112 //! This function returns the status of the Flash State Machine indicating if
113 //! an error is detected or not. Primary use is to check if an Erase or
114 //! Program operation has failed.
115 //!
116 //! \note Please note that code can not execute in flash while any part of the flash
117 //! is being programmed or erased. This function must be called from ROM or
118 //! SRAM while any part of the flash is being programmed or erased.
119 //!
120 //! \return Returns status of Flash state machine:
121 //! - \ref FAPI_STATUS_FSM_ERROR
122 //! - \ref FAPI_STATUS_SUCCESS
123 //
124 //*****************************************************************************
FlashCheckFsmForError(void)125 __STATIC_INLINE uint32_t FlashCheckFsmForError(void)
126 {
127     if (HWREG(FLASH_BASE + FLASH_O_STATCMD) & FLASH_STATCMD_CMDPASS_M)
128     {
129         return (FAPI_STATUS_SUCCESS);
130     }
131     else
132     {
133         return (FAPI_STATUS_FSM_ERROR);
134     }
135 }
136 
137 //*****************************************************************************
138 //
139 //! \brief Checks if the Flash state machine is ready.
140 //!
141 //! This function returns the status of the Flash State Machine indicating if
142 //! it is ready to accept a new command or not. Primary use is to check if an
143 //! Erase or Program operation has finished.
144 //!
145 //! \note Please note that code can not execute in flash while any part of the flash
146 //! is being programmed or erased. This function must be called from ROM or
147 //! SRAMh while any part of the flash is being programmed or erased.
148 //!
149 //! \return Returns readiness status of Flash state machine:
150 //! - \ref FAPI_STATUS_FSM_READY
151 //! - \ref FAPI_STATUS_FSM_BUSY
152 //
153 //*****************************************************************************
FlashCheckFsmForReady(void)154 __STATIC_INLINE uint32_t FlashCheckFsmForReady(void)
155 {
156     uint32_t reg = HWREG(FLASH_BASE + FLASH_O_STATCMD);
157 
158     if (((reg & FLASH_STATCMD_CMDINPROGRESS_M) == 0) ||
159          (reg & FLASH_STATCMD_CMDDONE_M))
160     {
161         return (FAPI_STATUS_FSM_READY);
162     }
163     else
164     {
165         return (FAPI_STATUS_FSM_BUSY);
166     }
167 }
168 
169 //*****************************************************************************
170 //
171 //! \brief Erase a flash sector.
172 //!
173 //! This function will erase the specified flash sector. The function will
174 //! not return until the flash sector has been erased or an error condition
175 //! occurred. If flash top sector is erased the function will program the
176 //! the device security data bytes with default values. The device security
177 //! data located in the customer configuration area of the flash top sector,
178 //! must have valid values at all times. These values affect the configuration
179 //! of the device during boot.
180 //!
181 //! \warning Please note that code can not execute in flash while any part of the flash
182 //! is being programmed or erased. The application must disable interrupts that have
183 //! interrupt routines in flash. This function calls a ROM function which handles the
184 //! actual program operation.
185 //!
186 //! \param sectorAddress is the starting address in flash of the sector to be
187 //! erased.
188 //!
189 //! \return Returns the status of the sector erase:
190 //! - \ref FAPI_STATUS_SUCCESS                     : Success.
191 //! - \ref FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH : Invalid argument.
192 //! - \ref FAPI_STATUS_FSM_ERROR                   : A programming error is encountered.
193 //
194 //*****************************************************************************
FlashEraseSector(uint32_t sectorAddress)195 __STATIC_INLINE uint32_t FlashEraseSector(uint32_t sectorAddress)
196 {
197     // Store current configuration
198     uint32_t cchctrl                  = HWREG(VIMS_BASE + VIMS_O_CCHCTRL);
199     // Clear instruction cache
200     HWREG(VIMS_BASE + VIMS_O_CCHCTRL) = (VIMS_CCHCTRL_CCHMPEN_DIS | VIMS_CCHCTRL_CCHPFEN_DIS | VIMS_CCHCTRL_CCHEN_DIS);
201 
202     uint32_t retCode = HapiFlashSectorErase(FLASH_API_KEY, sectorAddress);
203 
204     // Restore configuration
205     HWREG(VIMS_BASE + VIMS_O_CCHCTRL) = cchctrl;
206 
207     return (retCode);
208 }
209 
210 /*****************************************************************************
211  * \brief Erase all unprotected sectors in the flash main bank
212  *
213  * This function will erase all unprotected main bank flash sectors. It will
214  * not return until the flash sectors has been erased or an error condition
215  * occurs.
216  *
217  * \warning Please note that code can not execute in flash while any part of
218  * the flash is being programmed or erased. The application must disable
219  * interrupts that have interrupt routines in flash.
220  *
221  * \return Returns the status of the sector erase:
222  * - \ref FAPI_STATUS_SUCCESS (0): Success
223  * - \ref FAPI_STATUS_FSM_ERROR  : An erase error is encountered.
224  *****************************************************************************/
FlashEraseBank(void)225 __STATIC_INLINE uint32_t FlashEraseBank(void)
226 {
227     // Store current configuration
228     uint32_t cchctrl = HWREG(VIMS_BASE + VIMS_O_CCHCTRL);
229 
230     // Clear instruction cache
231     HWREG(VIMS_BASE + VIMS_O_CCHCTRL) = (VIMS_CCHCTRL_CCHMPEN_DIS | VIMS_CCHCTRL_CCHPFEN_DIS | VIMS_CCHCTRL_CCHEN_DIS);
232 
233     uint32_t retCode = HapiFlashBankErase(FLASH_API_KEY);
234 
235     // Restore configuration
236     HWREG(VIMS_BASE + VIMS_O_CCHCTRL) = cchctrl;
237 
238     return (retCode);
239 }
240 
241 //*****************************************************************************
242 //
243 //! \brief Programs unprotected flash sectors in the main bank.
244 //!
245 //! This function programs a sequence of bytes into the on-chip flash.
246 //! Programming each location consists of the result of an AND operation
247 //! of the new data and the existing data; in other words bits that contain
248 //! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed
249 //! to 1. Therefore, a byte can be programmed multiple times as long as these
250 //! rules are followed; if a program operation attempts to change a 0 bit to
251 //! a 1 bit, that bit will not have its value changed.
252 //!
253 //! This function does not return until the data has been programmed or a
254 //! programming error occurs.
255 //!
256 //!
257 //! \warning Please note that code can not execute in flash while any part of the flash
258 //! is being programmed or erased. The application must disable interrupts that have
259 //! interrupt routines in flash. This function calls a ROM function which handles the
260 //! actual program operation.
261 //!
262 //! The \c dataBuffer pointer can not point to flash.
263 //!
264 //! \param dataBuffer is a pointer to the data to be programmed.
265 //! \param address is the starting address in flash to be programmed.
266 //! \param count is the number of bytes to be programmed.
267 //!
268 //! \return Returns status of the flash programming:
269 //! - \ref FAPI_STATUS_SUCCESS                     : Success.
270 //! - \ref FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH : Too many bytes were requested.
271 //! - \ref FAPI_STATUS_FSM_ERROR                   : A programming error is encountered.
272 //
273 //*****************************************************************************
FlashProgram(uint8_t * dataBuffer,uint32_t address,uint32_t count)274 __STATIC_INLINE uint32_t FlashProgram(uint8_t *dataBuffer, uint32_t address, uint32_t count)
275 {
276     // Store current configuration
277     uint32_t cchctrl = HWREG(VIMS_BASE + VIMS_O_CCHCTRL);
278 
279     // Clear instruction cache
280     HWREG(VIMS_BASE + VIMS_O_CCHCTRL) = (VIMS_CCHCTRL_CCHMPEN_DIS | VIMS_CCHCTRL_CCHPFEN_DIS | VIMS_CCHCTRL_CCHEN_DIS);
281 
282     uint32_t retCode = HapiFlashProgram(FLASH_API_KEY, dataBuffer, address, count);
283 
284     // Restore configuration
285     HWREG(VIMS_BASE + VIMS_O_CCHCTRL) = cchctrl;
286 
287     return (retCode);
288 }
289 
290 //*****************************************************************************
291 //
292 // Mark the end of the C bindings section for C++ compilers.
293 //
294 //*****************************************************************************
295 #ifdef __cplusplus
296 }
297 #endif
298 
299 //*****************************************************************************
300 //
301 //! Close the Doxygen group.
302 //! @}
303 //! @}
304 //
305 //*****************************************************************************
306 
307 #endif // __FLASH_H__
308