1 /******************************************************************************
2 * Filename: flash.c
3 * Revised: 2020-02-14 11:30:20 +0100 (Fri, 14 Feb 2020)
4 * Revision: 56760
5 *
6 * Description: Driver for on chip Flash.
7 *
8 * Copyright (c) 2015 - 2017, 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 switch(ui32PowerMode)
125 {
126 case FLASH_PWR_ACTIVE_MODE:
127 // Set bank power mode to ACTIVE.
128 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
129 (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
130 ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_ACTIVE;
131
132 // Set charge pump power mode to ACTIVE mode.
133 HWREG(FLASH_BASE + FLASH_O_FPAC1) =
134 (HWREG(FLASH_BASE + FLASH_O_FPAC1) & ~FLASH_FPAC1_PUMPPWR_M) | (1 << FLASH_FPAC1_PUMPPWR_S);
135 break;
136
137 case FLASH_PWR_OFF_MODE:
138 // Set bank grace period.
139 HWREG(FLASH_BASE + FLASH_O_FBAC) =
140 (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
141 ((ui32BankGracePeriod << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
142
143 // Set pump grace period.
144 HWREG(FLASH_BASE + FLASH_O_FPAC2) =
145 (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
146 ((ui32PumpGracePeriod << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
147
148 // Set bank power mode to SLEEP.
149 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &= ~FLASH_FBFALLBACK_BANKPWR0_M;
150
151 // Set charge pump power mode to SLEEP mode.
152 HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
153 break;
154
155 case FLASH_PWR_DEEP_STDBY_MODE:
156 // Set bank grace period.
157 HWREG(FLASH_BASE + FLASH_O_FBAC) =
158 (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
159 ((ui32BankGracePeriod << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
160
161 // Set pump grace period.
162 HWREG(FLASH_BASE + FLASH_O_FPAC2) =
163 (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
164 ((ui32PumpGracePeriod << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
165
166 // Set bank power mode to DEEP STANDBY mode.
167 HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
168 (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
169 ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_DEEP_STDBY;
170
171 // Set charge pump power mode to STANDBY mode.
172 HWREG(FLASH_BASE + FLASH_O_FPAC1) |= FLASH_FPAC1_PUMPPWR_M;
173 break;
174 }
175 }
176
177 //*****************************************************************************
178 //
179 // Get current configured power mode
180 //
181 //*****************************************************************************
182 uint32_t
FlashPowerModeGet(void)183 FlashPowerModeGet(void)
184 {
185 uint32_t ui32PowerMode;
186 uint32_t ui32BankPwrMode;
187
188 ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
189 FLASH_FBFALLBACK_BANKPWR0_M;
190
191 if(ui32BankPwrMode == FBFALLBACK_SLEEP)
192 {
193 ui32PowerMode = FLASH_PWR_OFF_MODE;
194 }
195 else if(ui32BankPwrMode == FBFALLBACK_DEEP_STDBY)
196 {
197 ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
198 }
199 else
200 {
201 ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
202 }
203
204 // Return power mode.
205 return(ui32PowerMode);
206 }
207
208 //*****************************************************************************
209 //
210 // Set sector protection
211 //
212 //*****************************************************************************
213 void
FlashProtectionSet(uint32_t ui32SectorAddress,uint32_t ui32ProtectMode)214 FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
215 {
216 uint32_t ui32SectorNumber;
217
218 // Check the arguments.
219 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
220 FlashSectorSizeGet()));
221 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
222
223 if(ui32ProtectMode == FLASH_WRITE_PROTECT)
224 {
225 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
226 FlashSectorSizeGet();
227 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
228
229 if(ui32SectorNumber <= 31)
230 {
231 HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
232 HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
233 }
234 else if(ui32SectorNumber <= 63)
235 {
236 HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
237 (1 << (ui32SectorNumber & 0x1F));
238 HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
239 (1 << (ui32SectorNumber & 0x1F));
240 }
241
242 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
243 }
244 }
245
246 //*****************************************************************************
247 //
248 // Get sector protection
249 //
250 //*****************************************************************************
251 uint32_t
FlashProtectionGet(uint32_t ui32SectorAddress)252 FlashProtectionGet(uint32_t ui32SectorAddress)
253 {
254 uint32_t ui32SectorProtect;
255 uint32_t ui32SectorNumber;
256
257 // Check the arguments.
258 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
259 FlashSectorSizeGet()));
260 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
261
262 ui32SectorProtect = FLASH_NO_PROTECT;
263 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
264
265 if(ui32SectorNumber <= 31)
266 {
267 if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
268 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
269 {
270 ui32SectorProtect = FLASH_WRITE_PROTECT;
271 }
272 }
273 else if(ui32SectorNumber <= 63)
274 {
275 if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
276 (1 << (ui32SectorNumber & 0x1F))) &&
277 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
278 (1 << (ui32SectorNumber & 0x1F))))
279 {
280 ui32SectorProtect = FLASH_WRITE_PROTECT;
281 }
282 }
283
284 return(ui32SectorProtect);
285 }
286
287 //*****************************************************************************
288 //
289 // Save sector protection to make it permanent
290 //
291 //*****************************************************************************
292 uint32_t
FlashProtectionSave(uint32_t ui32SectorAddress)293 FlashProtectionSave(uint32_t ui32SectorAddress)
294 {
295 uint32_t ui32ErrorReturn;
296 uint32_t ui32SectorNumber;
297 uint32_t ui32CcfgSectorAddr;
298 uint32_t ui32ProgBuf;
299
300 ui32ErrorReturn = FAPI_STATUS_SUCCESS;
301
302 // Check the arguments.
303 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
304 FlashSectorSizeGet()));
305 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
306
307 if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
308 {
309 // Find sector number for specified sector.
310 ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
311 ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
312
313 // Adjust CCFG address to the 32-bit CCFG word holding the
314 // protect-bit for the specified sector.
315 ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
316
317 // Find value to program by setting the protect-bit which
318 // corresponds to specified sector number, to 0.
319 // Leave other protect-bits unchanged.
320 ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
321 *(uint32_t *)ui32CcfgSectorAddr;
322
323 ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr,
324 CCFG_SIZE_SECT_PROT);
325 }
326
327 // Return status.
328 return(ui32ErrorReturn);
329 }
330
331 //*****************************************************************************
332 //
333 // Erase a flash sector
334 //
335 //*****************************************************************************
336 uint32_t
FlashSectorErase(uint32_t ui32SectorAddress)337 FlashSectorErase(uint32_t ui32SectorAddress)
338 {
339 uint32_t ui32ErrorReturn;
340 FlashSectorErasePointer_t FuncPointer;
341
342 // Check the arguments.
343 ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
344 FlashSectorSizeGet()));
345 ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
346
347 // Call ROM function that handles the actual erase operation
348 FuncPointer = (uint32_t (*)(uint32_t)) (ROM_API_FLASH_TABLE[5]);
349 ui32ErrorReturn = FuncPointer(ui32SectorAddress);
350
351 // Enable standby in flash bank since ROM function might have disabled it
352 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
353
354 // Return status of operation.
355 return(ui32ErrorReturn);
356
357 }
358
359
360 //*****************************************************************************
361 //
362 // Programs unprotected main bank flash sectors
363 //
364 //*****************************************************************************
365 uint32_t
FlashProgram(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)366 FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
367 {
368 uint32_t ui32ErrorReturn;
369 FlashPrgPointer_t FuncPointer;
370
371 // Check the arguments.
372 ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
373
374 // Call ROM function that handles the actual program operation
375 FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ROM_API_FLASH_TABLE[6]);
376 ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
377
378 // Enable standby in flash bank since ROM function might have disabled it
379 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
380
381 // Return status of operation.
382 return(ui32ErrorReturn);
383
384 }
385
386 //*****************************************************************************
387 //
388 // Reads efuse data from specified row
389 //
390 //*****************************************************************************
391 bool
FlashEfuseReadRow(uint32_t * pui32EfuseData,uint32_t ui32RowAddress)392 FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
393 {
394 bool bStatus;
395
396 // Make sure the clock for the efuse is enabled
397 HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
398
399 // Set timing for EFUSE read operations.
400 HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
401 FLASH_EFUSEREAD_READCLOCK_M);
402
403 // Clear status register.
404 HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
405
406 // Select the FuseROM block 0.
407 HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
408
409 // Start the read operation.
410 HWREG(FLASH_BASE + FLASH_O_EFUSE) =
411 (DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
412 (ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
413
414 // Wait for operation to finish.
415 while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
416 {
417 }
418
419 // Check if error reported.
420 if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
421 {
422 // Set error status.
423 bStatus = 1;
424
425 // Clear data.
426 *pui32EfuseData = 0;
427 }
428 else
429 {
430 // Set ok status.
431 bStatus = 0;
432
433 // No error. Get data from data register.
434 *pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
435 }
436
437 // Disable the efuse clock to conserve power
438 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
439
440 // Return the data.
441 return(bStatus);
442 }
443
444
445 //*****************************************************************************
446 //
447 // Disables all sectors for erase and programming on the active bank
448 //
449 //*****************************************************************************
450 void
FlashDisableSectorsForWrite(void)451 FlashDisableSectorsForWrite(void)
452 {
453 // Configure flash back to read mode
454 SetReadMode();
455
456 // Disable Level 1 Protection.
457 HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
458
459 // Disable all sectors for erase and programming.
460 HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
461
462 // Enable Level 1 Protection.
463 HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
464
465 // Protect sectors from sector erase.
466 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
467 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
468 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
469 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
470 }
471
472 //*****************************************************************************
473 //
474 //! \internal
475 //! Used to set flash in read mode.
476 //!
477 //! Flash is configured with values loaded from OTP dependent on the current
478 //! regulator mode.
479 //!
480 //! \return None.
481 //
482 //*****************************************************************************
483 static void
SetReadMode(void)484 SetReadMode(void)
485 {
486 uint32_t ui32TrimValue;
487 uint32_t ui32Value;
488
489 // Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
490 // VIN_AT_X and VIN_BY_PASS for read mode
491 if(HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
492 AON_PMCTL_PWRCTL_EXT_REG_MODE)
493 {
494 // Select trim values for external regulator mode:
495 // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
496 // COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 6:5)
497 // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
498 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
499
500 ui32TrimValue =
501 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
502
503 ui32Value = ((ui32TrimValue &
504 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
505 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
506 FLASH_CFG_STANDBY_MODE_SEL_S;
507
508 ui32Value |= ((ui32TrimValue &
509 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
510 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
511 FLASH_CFG_STANDBY_PW_SEL_S;
512
513 // Configure DIS_STANDBY (OTP offset 0x308 bit 4).
514 // Configure DIS_IDLE (OTP offset 0x308 bit 3).
515 ui32Value |= ((ui32TrimValue &
516 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
517 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
518 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
519 FLASH_CFG_DIS_IDLE_S;
520
521 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
522 ~(FLASH_CFG_STANDBY_MODE_SEL_M |
523 FLASH_CFG_STANDBY_PW_SEL_M |
524 FLASH_CFG_DIS_STANDBY_M |
525 FLASH_CFG_DIS_IDLE_M)) | ui32Value;
526
527 // Check if sample and hold functionality is disabled.
528 if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
529 {
530 // Wait for disabled sample and hold functionality to be stable.
531 while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
532 {
533 }
534 }
535
536 // Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
537 ui32Value = ((ui32TrimValue &
538 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
539 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
540 FLASH_FSEQPMP_VIN_AT_X_S;
541
542 // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
543 // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
544 // VIN_BY_PASS should be 1
545 if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
546 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
547 {
548 ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
549 }
550
551 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
552 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
553 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
554 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
555 FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
556 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
557 }
558 else
559 {
560 // Select trim values for internal regulator mode:
561 // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
562 // COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 14:13)
563 // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
564 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
565
566 ui32TrimValue =
567 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
568
569 ui32Value = ((ui32TrimValue &
570 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
571 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
572 FLASH_CFG_STANDBY_MODE_SEL_S;
573
574 ui32Value |= ((ui32TrimValue &
575 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
576 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
577 FLASH_CFG_STANDBY_PW_SEL_S;
578
579 // Configure DIS_STANDBY (OTP offset 0x308 bit 12).
580 // Configure DIS_IDLE (OTP offset 0x308 bit 11).
581 ui32Value |= ((ui32TrimValue &
582 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
583 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
584 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
585 FLASH_CFG_DIS_IDLE_S;
586
587 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
588 ~(FLASH_CFG_STANDBY_MODE_SEL_M |
589 FLASH_CFG_STANDBY_PW_SEL_M |
590 FLASH_CFG_DIS_STANDBY_M |
591 FLASH_CFG_DIS_IDLE_M)) | ui32Value;
592
593 // Check if sample and hold functionality is disabled.
594 if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
595 {
596 // Wait for disabled sample and hold functionality to be stable.
597 while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
598 {
599 }
600 }
601
602 // Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
603 ui32Value = (((ui32TrimValue &
604 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
605 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
606 FLASH_FSEQPMP_VIN_AT_X_S);
607
608 // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
609 // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
610 // VIN_BY_PASS should be 1
611 if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
612 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
613 {
614 ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
615 }
616
617 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
618 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
619 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
620 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
621 FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
622 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
623 }
624 }
625
626 //*****************************************************************************
627 //
628 // HAPI Flash program function
629 //
630 //*****************************************************************************
631 uint32_t
MemBusWrkAroundHapiProgramFlash(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)632 MemBusWrkAroundHapiProgramFlash(uint8_t *pui8DataBuffer, uint32_t ui32Address,
633 uint32_t ui32Count)
634 {
635 uint32_t ui32ErrorReturn;
636 FlashPrgPointer_t FuncPointer;
637 uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (5 * 4));
638
639 // Call ROM function
640 FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ui32RomAddr);
641 ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
642
643 // Enable standby in flash bank since ROM function might have disabled it
644 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
645
646 // Return status of operation.
647 return(ui32ErrorReturn);
648 }
649
650 //*****************************************************************************
651 //
652 // HAPI Flash sector erase function
653 //
654 //*****************************************************************************
655 uint32_t
MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)656 MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)
657 {
658 uint32_t ui32ErrorReturn;
659
660 FlashSectorErasePointer_t FuncPointer;
661 uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (3 * 4));
662
663 // Call ROM function
664 FuncPointer = (uint32_t (*)(uint32_t)) (ui32RomAddr);
665 ui32ErrorReturn = FuncPointer(ui32Address);
666
667 // Enable standby in flash bank since ROM function might have disabled it
668 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
669
670 // Return status of operation.
671 return(ui32ErrorReturn);
672 }
673