1 /******************************************************************************
2 * Filename: flash.c
3 * Revised: 2020-05-14 17:23:02 +0200 (Thu, 14 May 2020)
4 * Revision: 57519
5 *
6 * Description: Driver for on chip Flash.
7 *
8 * Copyright (c) 2015 - 2020, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include "../inc/hw_types.h"
40 #include "../inc/hw_ccfg.h"
41 #include "flash.h"
42 #include "rom.h"
43 #include "chipinfo.h"
44
45 //*****************************************************************************
46 //
47 // Handle support for DriverLib in ROM:
48 // This section will undo prototype renaming made in the header file
49 //
50 //*****************************************************************************
51 #if !defined(DOXYGEN)
52 #undef FlashPowerModeSet
53 #define FlashPowerModeSet NOROM_FlashPowerModeSet
54 #undef FlashPowerModeGet
55 #define FlashPowerModeGet NOROM_FlashPowerModeGet
56 #undef FlashProtectionSet
57 #define FlashProtectionSet NOROM_FlashProtectionSet
58 #undef FlashProtectionGet
59 #define FlashProtectionGet NOROM_FlashProtectionGet
60 #undef FlashProtectionSave
61 #define FlashProtectionSave NOROM_FlashProtectionSave
62 #undef FlashSectorErase
63 #define FlashSectorErase NOROM_FlashSectorErase
64 #undef FlashProgram
65 #define FlashProgram NOROM_FlashProgram
66 #undef FlashEfuseReadRow
67 #define FlashEfuseReadRow NOROM_FlashEfuseReadRow
68 #undef FlashDisableSectorsForWrite
69 #define FlashDisableSectorsForWrite NOROM_FlashDisableSectorsForWrite
70 #endif
71
72
73 //*****************************************************************************
74 //
75 // Defines for accesses to the security control in the customer configuration
76 // area in flash top sector.
77 //
78 //*****************************************************************************
79 #define CCFG_OFFSET_SECURITY CCFG_O_BL_CONFIG
80 #define CCFG_OFFSET_SECT_PROT CCFG_O_CCFG_PROT_31_0
81 #define CCFG_SIZE_SECURITY 0x00000014
82 #define CCFG_SIZE_SECT_PROT 0x00000004
83
84 //*****************************************************************************
85 //
86 // Default values for security control in customer configuration area in flash
87 // top sector.
88 //
89 //*****************************************************************************
90 const uint8_t g_pui8CcfgDefaultSec[] = {0xFF, 0xFF, 0xFF, 0xC5,
91 0xFF, 0xFF, 0xFF, 0xFF,
92 0xC5, 0xFF, 0xFF, 0xFF,
93 0xC5, 0xC5, 0xC5, 0xFF,
94 0xC5, 0xC5, 0xC5, 0xFF
95 };
96
97 typedef uint32_t (* FlashPrgPointer_t) (uint8_t *, uint32_t, uint32_t);
98
99 typedef uint32_t (* FlashSectorErasePointer_t) (uint32_t);
100
101 //*****************************************************************************
102 //
103 // Function prototypes for static functions
104 //
105 //*****************************************************************************
106 static void SetReadMode(void);
107
108 //*****************************************************************************
109 //
110 // Set power mode
111 //
112 //*****************************************************************************
113 void
FlashPowerModeSet(uint32_t ui32PowerMode,uint32_t ui32BankGracePeriod,uint32_t ui32PumpGracePeriod)114 FlashPowerModeSet(uint32_t ui32PowerMode, uint32_t ui32BankGracePeriod,
115 uint32_t ui32PumpGracePeriod)
116 {
117 // Check the arguments.
118 ASSERT(ui32PowerMode == FLASH_PWR_ACTIVE_MODE ||
119 ui32PowerMode == FLASH_PWR_OFF_MODE ||
120 ui32PowerMode == FLASH_PWR_DEEP_STDBY_MODE);
121 ASSERT(ui32BankGracePeriod <= 0xFF);
122 ASSERT(ui32PumpGracePeriod <= 0xFFFF);
123
124 // Initialize flag requesting deprecated power mode
125 HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
126 HWREG(FLASH_BASE + FLASH_O_FWFLAG) &= ~FW_PWRMODE_DEPRECATED;
127 HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
128
129 switch(ui32PowerMode)
130 {
131 case FLASH_PWR_ACTIVE_MODE:
132 // Set bank power mode to ACTIVE.
133 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
134 (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
135 ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_ACTIVE;
136
137 // Set charge pump power mode to ACTIVE mode.
138 HWREG(FLASH_BASE + FLASH_O_FPAC1) =
139 (HWREG(FLASH_BASE + FLASH_O_FPAC1) & ~FLASH_FPAC1_PUMPPWR_M) | (1 << FLASH_FPAC1_PUMPPWR_S);
140 break;
141
142 case FLASH_PWR_DEEP_STDBY_MODE:
143 // Deprecated power mode requested. Set flag.
144 HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
145 HWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_PWRMODE_DEPRECATED;
146 HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
147 // Fall through to force FLASH_PWR_OFF_MODE power mode
148 case FLASH_PWR_OFF_MODE:
149 // Set bank grace period.
150 HWREG(FLASH_BASE + FLASH_O_FBAC) =
151 (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
152 ((ui32BankGracePeriod << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
153
154 // Set pump grace period.
155 HWREG(FLASH_BASE + FLASH_O_FPAC2) =
156 (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
157 ((ui32PumpGracePeriod << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
158
159 // Set bank power mode to SLEEP.
160 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &= ~FLASH_FBFALLBACK_BANKPWR0_M;
161
162 // Set charge pump power mode to SLEEP mode.
163 HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
164 break;
165 }
166 }
167
168 //*****************************************************************************
169 //
170 // Get current configured power mode
171 //
172 //*****************************************************************************
173 uint32_t
FlashPowerModeGet(void)174 FlashPowerModeGet(void)
175 {
176 uint32_t ui32PowerMode;
177 uint32_t ui32BankPwrMode;
178
179 ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
180 FLASH_FBFALLBACK_BANKPWR0_M;
181
182 if((ui32BankPwrMode == FBFALLBACK_SLEEP) &&
183 ((HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_PWRMODE_DEPRECATED) == FW_PWRMODE_DEPRECATED))
184 {
185 ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
186 }
187 else if((ui32BankPwrMode == FBFALLBACK_SLEEP) &&
188 ((HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_PWRMODE_DEPRECATED) == 0))
189 {
190 ui32PowerMode = FLASH_PWR_OFF_MODE;
191 }
192 else
193 {
194 ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
195 }
196
197 // Return power mode.
198 return(ui32PowerMode);
199 }
200
201 //*****************************************************************************
202 //
203 // Set sector protection
204 //
205 //*****************************************************************************
206 void
FlashProtectionSet(uint32_t ui32SectorAddress,uint32_t ui32ProtectMode)207 FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
208 {
209 uint32_t ui32SectorNumber;
210
211 // Check the arguments.
212 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
213 FlashSectorSizeGet()));
214 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
215
216 if(ui32ProtectMode == FLASH_WRITE_PROTECT)
217 {
218 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
219 FlashSectorSizeGet();
220 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
221
222 if(ui32SectorNumber <= 31)
223 {
224 HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
225 HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
226 }
227 else if(ui32SectorNumber <= 63)
228 {
229 HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
230 (1 << (ui32SectorNumber & 0x1F));
231 HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
232 (1 << (ui32SectorNumber & 0x1F));
233 }
234
235 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
236 }
237 }
238
239 //*****************************************************************************
240 //
241 // Get sector protection
242 //
243 //*****************************************************************************
244 uint32_t
FlashProtectionGet(uint32_t ui32SectorAddress)245 FlashProtectionGet(uint32_t ui32SectorAddress)
246 {
247 uint32_t ui32SectorProtect;
248 uint32_t ui32SectorNumber;
249
250 // Check the arguments.
251 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
252 FlashSectorSizeGet()));
253 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
254
255 ui32SectorProtect = FLASH_NO_PROTECT;
256 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
257
258 if(ui32SectorNumber <= 31)
259 {
260 if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
261 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
262 {
263 ui32SectorProtect = FLASH_WRITE_PROTECT;
264 }
265 }
266 else if(ui32SectorNumber <= 63)
267 {
268 if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
269 (1 << (ui32SectorNumber & 0x1F))) &&
270 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
271 (1 << (ui32SectorNumber & 0x1F))))
272 {
273 ui32SectorProtect = FLASH_WRITE_PROTECT;
274 }
275 }
276
277 return(ui32SectorProtect);
278 }
279
280 //*****************************************************************************
281 //
282 // Save sector protection to make it permanent
283 //
284 //*****************************************************************************
285 uint32_t
FlashProtectionSave(uint32_t ui32SectorAddress)286 FlashProtectionSave(uint32_t ui32SectorAddress)
287 {
288 uint32_t ui32ErrorReturn;
289 uint32_t ui32SectorNumber;
290 uint32_t ui32CcfgSectorAddr;
291 uint32_t ui32ProgBuf;
292
293 ui32ErrorReturn = FAPI_STATUS_SUCCESS;
294
295 // Check the arguments.
296 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
297 FlashSectorSizeGet()));
298 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
299
300 if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
301 {
302 // Find sector number for specified sector.
303 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
304 ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
305
306 // Adjust CCFG address to the 32-bit CCFG word holding the
307 // protect-bit for the specified sector.
308 ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
309
310 // Find value to program by setting the protect-bit which
311 // corresponds to specified sector number, to 0.
312 // Leave other protect-bits unchanged.
313 ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
314 *(uint32_t *)ui32CcfgSectorAddr;
315
316 ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr,
317 CCFG_SIZE_SECT_PROT);
318 }
319
320 // Return status.
321 return(ui32ErrorReturn);
322 }
323
324 //*****************************************************************************
325 //
326 // Erase a flash sector
327 //
328 //*****************************************************************************
329 uint32_t
FlashSectorErase(uint32_t ui32SectorAddress)330 FlashSectorErase(uint32_t ui32SectorAddress)
331 {
332 uint32_t ui32ErrorReturn;
333 FlashSectorErasePointer_t FuncPointer;
334
335 // Check the arguments.
336 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
337 FlashSectorSizeGet()));
338 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
339
340 // Call ROM function that handles the actual erase operation
341 FuncPointer = (uint32_t (*)(uint32_t)) (ROM_API_FLASH_TABLE[5]);
342 ui32ErrorReturn = FuncPointer(ui32SectorAddress);
343
344 // Enable standby in flash bank since ROM function might have disabled it
345 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
346
347 // Return status of operation.
348 return(ui32ErrorReturn);
349
350 }
351
352
353 //*****************************************************************************
354 //
355 // Programs unprotected main bank flash sectors
356 //
357 //*****************************************************************************
358 uint32_t
FlashProgram(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)359 FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
360 {
361 uint32_t ui32ErrorReturn;
362 FlashPrgPointer_t FuncPointer;
363
364 // Check the arguments.
365 ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
366
367 // Call ROM function that handles the actual program operation
368 FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ROM_API_FLASH_TABLE[6]);
369 ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
370
371 // Enable standby in flash bank since ROM function might have disabled it
372 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
373
374 // Return status of operation.
375 return(ui32ErrorReturn);
376
377 }
378
379 //*****************************************************************************
380 //
381 // Reads efuse data from specified row
382 //
383 //*****************************************************************************
384 bool
FlashEfuseReadRow(uint32_t * pui32EfuseData,uint32_t ui32RowAddress)385 FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
386 {
387 bool bStatus;
388
389 // Make sure the clock for the efuse is enabled
390 HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
391
392 // Set timing for EFUSE read operations.
393 HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
394 FLASH_EFUSEREAD_READCLOCK_M);
395
396 // Clear status register.
397 HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
398
399 // Select the FuseROM block 0.
400 HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
401
402 // Start the read operation.
403 HWREG(FLASH_BASE + FLASH_O_EFUSE) =
404 (DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
405 (ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
406
407 // Wait for operation to finish.
408 while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
409 {
410 }
411
412 // Check if error reported.
413 if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
414 {
415 // Set error status.
416 bStatus = 1;
417
418 // Clear data.
419 *pui32EfuseData = 0;
420 }
421 else
422 {
423 // Set ok status.
424 bStatus = 0;
425
426 // No error. Get data from data register.
427 *pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
428 }
429
430 // Disable the efuse clock to conserve power
431 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
432
433 // Return the data.
434 return(bStatus);
435 }
436
437
438 //*****************************************************************************
439 //
440 // Disables all sectors for erase and programming on the active bank
441 //
442 //*****************************************************************************
443 void
FlashDisableSectorsForWrite(void)444 FlashDisableSectorsForWrite(void)
445 {
446 // Configure flash back to read mode
447 SetReadMode();
448
449 // Disable Level 1 Protection.
450 HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
451
452 // Disable all sectors for erase and programming.
453 HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
454
455 // Enable Level 1 Protection.
456 HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
457
458 // Protect sectors from sector erase.
459 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
460 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
461 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
462 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
463 }
464
465 //*****************************************************************************
466 //
467 //! \internal
468 //! Used to set flash in read mode.
469 //!
470 //! Flash is configured with values loaded from OTP dependent on the current
471 //! regulator mode.
472 //!
473 //! \return None.
474 //
475 //*****************************************************************************
476 static void
SetReadMode(void)477 SetReadMode(void)
478 {
479 uint32_t ui32TrimValue;
480 uint32_t ui32Value;
481
482 // Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
483 // VIN_AT_X and VIN_BY_PASS for read mode
484 if(HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
485 AON_PMCTL_PWRCTL_EXT_REG_MODE)
486 {
487 // Select trim values for external regulator mode:
488 // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
489 // COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 6:5)
490 // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
491 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
492
493 ui32TrimValue =
494 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
495
496 ui32Value = ((ui32TrimValue &
497 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
498 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
499 FLASH_CFG_STANDBY_MODE_SEL_S;
500
501 ui32Value |= ((ui32TrimValue &
502 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
503 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
504 FLASH_CFG_STANDBY_PW_SEL_S;
505
506 // Configure DIS_STANDBY (OTP offset 0x308 bit 4).
507 // Configure DIS_IDLE (OTP offset 0x308 bit 3).
508 ui32Value |= ((ui32TrimValue &
509 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
510 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
511 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
512 FLASH_CFG_DIS_IDLE_S;
513
514 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
515 ~(FLASH_CFG_STANDBY_MODE_SEL_M |
516 FLASH_CFG_STANDBY_PW_SEL_M |
517 FLASH_CFG_DIS_STANDBY_M |
518 FLASH_CFG_DIS_IDLE_M)) | ui32Value;
519
520 // Check if sample and hold functionality is disabled.
521 if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
522 {
523 // Wait for disabled sample and hold functionality to be stable.
524 while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
525 {
526 }
527 }
528
529 // Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
530 ui32Value = ((ui32TrimValue &
531 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
532 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
533 FLASH_FSEQPMP_VIN_AT_X_S;
534
535 // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
536 // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
537 // VIN_BY_PASS should be 1
538 if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
539 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
540 {
541 ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
542 }
543
544 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
545 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
546 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
547 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
548 FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
549 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
550 }
551 else
552 {
553 // Select trim values for internal regulator mode:
554 // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
555 // COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 14:13)
556 // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
557 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
558
559 ui32TrimValue =
560 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
561
562 ui32Value = ((ui32TrimValue &
563 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
564 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
565 FLASH_CFG_STANDBY_MODE_SEL_S;
566
567 ui32Value |= ((ui32TrimValue &
568 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
569 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
570 FLASH_CFG_STANDBY_PW_SEL_S;
571
572 // Configure DIS_STANDBY (OTP offset 0x308 bit 12).
573 // Configure DIS_IDLE (OTP offset 0x308 bit 11).
574 ui32Value |= ((ui32TrimValue &
575 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
576 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
577 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
578 FLASH_CFG_DIS_IDLE_S;
579
580 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
581 ~(FLASH_CFG_STANDBY_MODE_SEL_M |
582 FLASH_CFG_STANDBY_PW_SEL_M |
583 FLASH_CFG_DIS_STANDBY_M |
584 FLASH_CFG_DIS_IDLE_M)) | ui32Value;
585
586 // Check if sample and hold functionality is disabled.
587 if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
588 {
589 // Wait for disabled sample and hold functionality to be stable.
590 while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
591 {
592 }
593 }
594
595 // Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
596 ui32Value = (((ui32TrimValue &
597 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
598 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
599 FLASH_FSEQPMP_VIN_AT_X_S);
600
601 // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
602 // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
603 // VIN_BY_PASS should be 1
604 if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
605 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
606 {
607 ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
608 }
609
610 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
611 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
612 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
613 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
614 FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
615 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
616 }
617 }
618
619 //*****************************************************************************
620 //
621 // HAPI Flash program function
622 //
623 //*****************************************************************************
624 uint32_t
MemBusWrkAroundHapiProgramFlash(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)625 MemBusWrkAroundHapiProgramFlash(uint8_t *pui8DataBuffer, uint32_t ui32Address,
626 uint32_t ui32Count)
627 {
628 uint32_t ui32ErrorReturn;
629 FlashPrgPointer_t FuncPointer;
630 uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (5 * 4));
631
632 // Call ROM function
633 FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ui32RomAddr);
634 ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
635
636 // Enable standby in flash bank since ROM function might have disabled it
637 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
638
639 // Return status of operation.
640 return(ui32ErrorReturn);
641 }
642
643 //*****************************************************************************
644 //
645 // HAPI Flash sector erase function
646 //
647 //*****************************************************************************
648 uint32_t
MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)649 MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)
650 {
651 uint32_t ui32ErrorReturn;
652
653 FlashSectorErasePointer_t FuncPointer;
654 uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (3 * 4));
655
656 // Call ROM function
657 FuncPointer = (uint32_t (*)(uint32_t)) (ui32RomAddr);
658 ui32ErrorReturn = FuncPointer(ui32Address);
659
660 // Enable standby in flash bank since ROM function might have disabled it
661 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
662
663 // Return status of operation.
664 return(ui32ErrorReturn);
665 }
666