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