1 /******************************************************************************
2 * Filename: flash.c
3 * Revised: 2015-11-02 14:35:00 +0100 (Mon, 02 Nov 2015)
4 * Revision: 44906
5 *
6 * Description: Driver for on chip Flash.
7 *
8 * Copyright (c) 2015, 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 <driverlib/flash.h>
41 #include <driverlib/rom.h>
42 #include <driverlib/chipinfo.h>
43
44 //*****************************************************************************
45 //
46 // Handle support for DriverLib in ROM:
47 // This section will undo prototype renaming made in the header file
48 //
49 //*****************************************************************************
50 #if !defined(DOXYGEN)
51 #undef FlashPowerModeSet
52 #define FlashPowerModeSet NOROM_FlashPowerModeSet
53 #undef FlashPowerModeGet
54 #define FlashPowerModeGet NOROM_FlashPowerModeGet
55 #undef FlashProtectionSet
56 #define FlashProtectionSet NOROM_FlashProtectionSet
57 #undef FlashProtectionGet
58 #define FlashProtectionGet NOROM_FlashProtectionGet
59 #undef FlashProtectionSave
60 #define FlashProtectionSave NOROM_FlashProtectionSave
61 #undef FlashSectorErase
62 #define FlashSectorErase NOROM_FlashSectorErase
63 #undef FlashProgram
64 #define FlashProgram NOROM_FlashProgram
65 #undef FlashEfuseReadRow
66 #define FlashEfuseReadRow NOROM_FlashEfuseReadRow
67 #undef FlashDisableSectorsForWrite
68 #define FlashDisableSectorsForWrite NOROM_FlashDisableSectorsForWrite
69 #endif
70
71 //*****************************************************************************
72 //
73 // Default values for security control in customer configuration area in flash
74 // top sector.
75 //
76 //*****************************************************************************
77 const uint8_t g_pui8CcfgDefaultSec[] = {0xFF, 0xFF, 0xFF, 0xC5,
78 0xFF, 0xFF, 0xFF, 0xFF,
79 0xC5, 0xFF, 0xFF, 0xFF,
80 0xC5, 0xC5, 0xC5, 0xFF,
81 0xC5, 0xC5, 0xC5, 0xFF
82 };
83
84 typedef uint32_t (* FlashPrgPointer_t) (uint8_t *, uint32_t, uint32_t);
85
86 typedef uint32_t (* FlashSectorErasePointer_t) (uint32_t);
87
88 //*****************************************************************************
89 //
90 // Function prototypes for static functions
91 //
92 //*****************************************************************************
93 static void SetReadMode(void);
94
95 //*****************************************************************************
96 //
97 //! Set power mode
98 //
99 //*****************************************************************************
100 void
FlashPowerModeSet(uint32_t ui32PowerMode,uint32_t ui32BankGracePeriode,uint32_t ui32PumpGracePeriode)101 FlashPowerModeSet(uint32_t ui32PowerMode, uint32_t ui32BankGracePeriode,
102 uint32_t ui32PumpGracePeriode)
103 {
104 //
105 // Check the arguments.
106 //
107 ASSERT(ui32PowerMode == FLASH_PWR_ACTIVE_MODE ||
108 ui32PowerMode == FLASH_PWR_OFF_MODE ||
109 ui32PowerMode == FLASH_PWR_DEEP_STDBY_MODE);
110 ASSERT(ui32BankGracePeriode <= 0xFF);
111 ASSERT(ui32PumpGracePeriode <= 0xFFFF);
112
113 switch(ui32PowerMode)
114 {
115 case FLASH_PWR_ACTIVE_MODE:
116 //
117 // Set bank power mode to ACTIVE.
118 //
119 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
120 (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
121 ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_ACTIVE;
122
123 //
124 // Set charge pump power mode to ACTIVE mode.
125 //
126 HWREG(FLASH_BASE + FLASH_O_FPAC1) =
127 (HWREG(FLASH_BASE + FLASH_O_FPAC1) & ~FLASH_FPAC1_PUMPPWR_M) | (1 << FLASH_FPAC1_PUMPPWR_S);
128 break;
129
130 case FLASH_PWR_OFF_MODE:
131 //
132 // Set bank grace periode.
133 //
134 HWREG(FLASH_BASE + FLASH_O_FBAC) =
135 (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
136 ((ui32BankGracePeriode << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
137
138 //
139 // Set pump grace periode.
140 //
141 HWREG(FLASH_BASE + FLASH_O_FPAC2) =
142 (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
143 ((ui32PumpGracePeriode << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
144
145 //
146 // Set bank power mode to SLEEP.
147 //
148 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &= ~FLASH_FBFALLBACK_BANKPWR0_M;
149
150 //
151 // Set charge pump power mode to SLEEP mode.
152 //
153 HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
154 break;
155
156 case FLASH_PWR_DEEP_STDBY_MODE:
157 //
158 // Set bank grace periode.
159 //
160 HWREG(FLASH_BASE + FLASH_O_FBAC) =
161 (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
162 ((ui32BankGracePeriode << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
163
164 //
165 // Set pump grace periode.
166 //
167 HWREG(FLASH_BASE + FLASH_O_FPAC2) =
168 (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
169 ((ui32PumpGracePeriode << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
170
171 //
172 // Set bank power mode to DEEP STANDBY mode.
173 //
174 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
175 (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
176 ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_DEEP_STDBY;
177
178 //
179 // Set charge pump power mode to STANDBY mode.
180 //
181 HWREG(FLASH_BASE + FLASH_O_FPAC1) |= FLASH_FPAC1_PUMPPWR_M;
182 break;
183 }
184 }
185
186 //*****************************************************************************
187 //
188 //! Get current configured power mode
189 //
190 //*****************************************************************************
191 uint32_t
FlashPowerModeGet(void)192 FlashPowerModeGet(void)
193 {
194 uint32_t ui32PowerMode;
195 uint32_t ui32BankPwrMode;
196
197 ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
198 FLASH_FBFALLBACK_BANKPWR0_M;
199
200 if(ui32BankPwrMode == FBFALLBACK_SLEEP)
201 {
202 ui32PowerMode = FLASH_PWR_OFF_MODE;
203 }
204 else if(ui32BankPwrMode == FBFALLBACK_DEEP_STDBY)
205 {
206 ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
207 }
208 else
209 {
210 ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
211 }
212
213 //
214 // Return power mode.
215 //
216 return(ui32PowerMode);
217 }
218
219 //*****************************************************************************
220 //
221 //! Set sector protection
222 //
223 //*****************************************************************************
224 void
FlashProtectionSet(uint32_t ui32SectorAddress,uint32_t ui32ProtectMode)225 FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
226 {
227 uint32_t ui32SectorNumber;
228
229 //
230 // Check the arguments.
231 //
232 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
233 FlashSectorSizeGet()));
234 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
235
236 if(ui32ProtectMode == FLASH_WRITE_PROTECT)
237 {
238 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
239 FlashSectorSizeGet();
240 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
241
242 if(ui32SectorNumber <= 31)
243 {
244 HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
245 HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
246 }
247 else if(ui32SectorNumber <= 63)
248 {
249 HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
250 (1 << (ui32SectorNumber & 0x1F));
251 HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
252 (1 << (ui32SectorNumber & 0x1F));
253 }
254
255 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
256 }
257 }
258
259 //*****************************************************************************
260 //
261 //! Get sector protection
262 //
263 //*****************************************************************************
264 uint32_t
FlashProtectionGet(uint32_t ui32SectorAddress)265 FlashProtectionGet(uint32_t ui32SectorAddress)
266 {
267 uint32_t ui32SectorProtect;
268 uint32_t ui32SectorNumber;
269
270 //
271 // Check the arguments.
272 //
273 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
274 FlashSectorSizeGet()));
275 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
276
277 ui32SectorProtect = FLASH_NO_PROTECT;
278 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
279
280 if(ui32SectorNumber <= 31)
281 {
282 if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
283 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
284 {
285 ui32SectorProtect = FLASH_WRITE_PROTECT;
286 }
287 }
288 else if(ui32SectorNumber <= 63)
289 {
290 if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
291 (1 << (ui32SectorNumber & 0x1F))) &&
292 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
293 (1 << (ui32SectorNumber & 0x1F))))
294 {
295 ui32SectorProtect = FLASH_WRITE_PROTECT;
296 }
297 }
298
299 return(ui32SectorProtect);
300 }
301
302 //*****************************************************************************
303 //
304 //! Save sector protection to make it permanent
305 //
306 //*****************************************************************************
307 uint32_t
FlashProtectionSave(uint32_t ui32SectorAddress)308 FlashProtectionSave(uint32_t ui32SectorAddress)
309 {
310 uint32_t ui32ErrorReturn;
311 uint32_t ui32SectorNumber;
312 uint32_t ui32CcfgSectorAddr;
313 uint32_t ui32ProgBuf;
314
315 ui32ErrorReturn = FAPI_STATUS_SUCCESS;
316
317 //
318 // Check the arguments.
319 //
320 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
321 FlashSectorSizeGet()));
322 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
323
324 if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
325 {
326 //
327 // Find sector number for specified sector.
328 //
329 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
330 ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
331
332 //
333 // Adjust CCFG address to the 32-bit CCFG word holding the
334 // protect-bit for the specified sector.
335 //
336 ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
337
338 //
339 // Find value to program by setting the protect-bit which
340 // corresponds to specified sector number, to 0.
341 // Leave other protect-bits unchanged.
342 //
343 ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
344 *(uint32_t *)ui32CcfgSectorAddr;
345
346 ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr,
347 CCFG_SIZE_SECT_PROT);
348 }
349
350 //
351 // Return status.
352 //
353 return(ui32ErrorReturn);
354 }
355
356 //*****************************************************************************
357 //
358 //! Erase a flash sector
359 //
360 //*****************************************************************************
361 uint32_t
FlashSectorErase(uint32_t ui32SectorAddress)362 FlashSectorErase(uint32_t ui32SectorAddress)
363 {
364 uint32_t ui32ErrorReturn;
365 FlashSectorErasePointer_t FuncPointer;
366
367 //
368 // Check the arguments.
369 //
370 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
371 FlashSectorSizeGet()));
372 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
373
374 //
375 // Call ROM function
376 //
377 FuncPointer = (uint32_t (*)(uint32_t)) (ROM_API_FLASH_TABLE[5]);
378 ui32ErrorReturn = FuncPointer(ui32SectorAddress);
379
380 //
381 // Enable standby in flash bank since ROM function migth have disabled it
382 //
383 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
384
385 //
386 // Return status of operation.
387 //
388 return(ui32ErrorReturn);
389
390 }
391
392
393 //*****************************************************************************
394 //
395 //! Programs unprotected main bank flash sectors
396 //
397 //*****************************************************************************
398 uint32_t
FlashProgram(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)399 FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
400 {
401 uint32_t ui32ErrorReturn;
402 FlashPrgPointer_t FuncPointer;
403
404 //
405 // Check the arguments.
406 //
407 ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
408
409 //
410 // Call ROM function
411 //
412 FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ROM_API_FLASH_TABLE[6]);
413 ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
414
415 //
416 // Enable standby in flash bank since ROM function migth have disabled it
417 //
418 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
419
420 //
421 // Return status of operation.
422 //
423 return(ui32ErrorReturn);
424
425 }
426
427 //*****************************************************************************
428 //
429 //! Reads efuse data from specified row
430 //
431 //*****************************************************************************
432 bool
FlashEfuseReadRow(uint32_t * pui32EfuseData,uint32_t ui32RowAddress)433 FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
434 {
435 bool bStatus;
436
437 //
438 // Make sure the clock for the efuse is enabled
439 //
440 HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
441
442 //
443 // Set timing for EFUSE read operations.
444 //
445 HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
446 FLASH_EFUSEREAD_READCLOCK_M);
447
448 //
449 // Clear status register.
450 //
451 HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
452
453 //
454 // Select the FuseROM block 0.
455 //
456 HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
457
458 //
459 // Start the read operation.
460 //
461 HWREG(FLASH_BASE + FLASH_O_EFUSE) =
462 (DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
463 (ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
464
465 //
466 // Wait for operation to finish.
467 //
468 while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
469 {
470 }
471
472 //
473 // Check if error reported.
474 //
475 if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
476 {
477 //
478 // Set error status.
479 //
480 bStatus = 1;
481
482 //
483 // Clear data.
484 //
485 *pui32EfuseData = 0;
486 }
487 else
488 {
489 //
490 // Set ok status.
491 //
492 bStatus = 0;
493
494 //
495 // No error. Get data from data register.
496 //
497 *pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
498 }
499
500 //
501 // Disable the efuse clock to conserve power
502 //
503 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
504
505 //
506 // Return the data.
507 //
508 return(bStatus);
509 }
510
511
512 //*****************************************************************************
513 //
514 //! Disables all sectors for erase and programming on the active bank
515 //
516 //*****************************************************************************
517 void
FlashDisableSectorsForWrite(void)518 FlashDisableSectorsForWrite(void)
519 {
520 //
521 // Configure flash back to read mode
522 //
523 SetReadMode();
524
525 //
526 // Disable Level 1 Protection.
527 //
528 HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
529
530 //
531 // Disable all sectors for erase and programming.
532 //
533 HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
534
535 //
536 // Enable Level 1 Protection.
537 //
538 HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
539
540 //
541 // Protect sectors from sector erase.
542 //
543 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
544 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
545 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
546 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
547 }
548
549 //*****************************************************************************
550 //
551 //! \internal
552 //! Used to set flash in read mode.
553 //!
554 //! Flash is configured with values loaded from OTP dependent on the current
555 //! regulator mode.
556 //!
557 //! \return None.
558 //
559 //*****************************************************************************
560 static void
SetReadMode(void)561 SetReadMode(void)
562 {
563 uint32_t ui32TrimValue;
564 uint32_t ui32Value;
565
566 //
567 // Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
568 // VIN_AT_X and VIN_BY_PASS for read mode
569 //
570 if(HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL) &
571 AON_SYSCTL_PWRCTL_EXT_REG_MODE)
572 {
573 // Select trim values for external regulator mode:
574 // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
575 // COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 6:5)
576 // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
577 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
578
579 ui32TrimValue =
580 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
581
582 ui32Value = ((ui32TrimValue &
583 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
584 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
585 FLASH_CFG_STANDBY_MODE_SEL_S;
586
587 ui32Value |= ((ui32TrimValue &
588 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
589 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
590 FLASH_CFG_STANDBY_PW_SEL_S;
591
592 // Configure DIS_STANDBY (OTP offset 0x308 bit 4).
593 // Configure DIS_IDLE (OTP offset 0x308 bit 3).
594 ui32Value |= ((ui32TrimValue &
595 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
596 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
597 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
598 FLASH_CFG_DIS_IDLE_S;
599
600 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
601 ~(FLASH_CFG_STANDBY_MODE_SEL_M |
602 FLASH_CFG_STANDBY_PW_SEL_M |
603 FLASH_CFG_DIS_STANDBY_M |
604 FLASH_CFG_DIS_IDLE_M)) | ui32Value;
605
606 // Check if sample and hold functionality is disabled.
607 if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
608 {
609 //
610 // Wait for disabled sample and hold functionality to be stable.
611 //
612 while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
613 {
614 }
615 }
616
617 // Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
618 ui32Value = ((ui32TrimValue &
619 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
620 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
621 FLASH_FSEQPMP_VIN_AT_X_S;
622
623 // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
624 // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
625 // VIN_BY_PASS should be 1
626 if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
627 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
628 {
629 ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
630 }
631
632 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
633 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
634 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
635 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
636 FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
637 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
638 }
639 else
640 {
641 // Select trim values for internal regulator mode:
642 // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
643 // COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 14:13)
644 // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
645 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
646
647 ui32TrimValue =
648 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
649
650 ui32Value = ((ui32TrimValue &
651 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
652 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
653 FLASH_CFG_STANDBY_MODE_SEL_S;
654
655 ui32Value |= ((ui32TrimValue &
656 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
657 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
658 FLASH_CFG_STANDBY_PW_SEL_S;
659
660 // Configure DIS_STANDBY (OTP offset 0x308 bit 12).
661 // Configure DIS_IDLE (OTP offset 0x308 bit 11).
662 ui32Value |= ((ui32TrimValue &
663 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
664 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
665 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
666 FLASH_CFG_DIS_IDLE_S;
667
668 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
669 ~(FLASH_CFG_STANDBY_MODE_SEL_M |
670 FLASH_CFG_STANDBY_PW_SEL_M |
671 FLASH_CFG_DIS_STANDBY_M |
672 FLASH_CFG_DIS_IDLE_M)) | ui32Value;
673
674 // Check if sample and hold functionality is disabled.
675 if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
676 {
677 //
678 // Wait for disabled sample and hold functionality to be stable.
679 //
680 while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
681 {
682 }
683 }
684
685 // Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
686 ui32Value = (((ui32TrimValue &
687 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
688 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
689 FLASH_FSEQPMP_VIN_AT_X_S);
690
691 // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
692 // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
693 // VIN_BY_PASS should be 1
694 if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
695 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
696 {
697 ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
698 }
699
700 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
701 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
702 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
703 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
704 FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
705 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
706 }
707 }
708
709 //*****************************************************************************
710 //
711 // HAPI Flash program function
712 //
713 //*****************************************************************************
714 uint32_t
MemBusWrkAroundHapiProgramFlash(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)715 MemBusWrkAroundHapiProgramFlash(uint8_t *pui8DataBuffer, uint32_t ui32Address,
716 uint32_t ui32Count)
717 {
718 uint32_t ui32ErrorReturn;
719 FlashPrgPointer_t FuncPointer;
720 uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (5 * 4));
721
722 //
723 // Call ROM function
724 //
725 FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ui32RomAddr);
726 ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
727
728 //
729 // Enable standby in flash bank since ROM function migth have disabled it
730 //
731 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
732
733 //
734 // Return status of operation.
735 //
736 return(ui32ErrorReturn);
737 }
738
739 //*****************************************************************************
740 //
741 // HAPI Flash sector erase function
742 //
743 //*****************************************************************************
744 uint32_t
MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)745 MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)
746 {
747 uint32_t ui32ErrorReturn;
748
749 FlashSectorErasePointer_t FuncPointer;
750 uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (3 * 4));
751
752 //
753 // Call ROM function
754 //
755 FuncPointer = (uint32_t (*)(uint32_t)) (ui32RomAddr);
756 ui32ErrorReturn = FuncPointer(ui32Address);
757
758 //
759 // Enable standby in flash bank since ROM function migth have disabled it
760 //
761 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
762
763 //
764 // Return status of operation.
765 //
766 return(ui32ErrorReturn);
767 }
768