flash/nor: Add support for TI CC26xx/CC13xx flash
[openocd.git] / contrib / loaders / flash / cc26xx / flash.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 ******************************************************************************/
34
35 #include <stdint.h>
36 #include <stdbool.h>
37 #include "flash.h"
38
39 /******************************************************************************
40 *
41 * Defines for accesses to the security control in the customer configuration
42 * area in flash top sector.
43 *
44 ******************************************************************************/
45 #define CCFG_OFFSET_SECURITY CCFG_O_BL_CONFIG
46 #define CCFG_SIZE_SECURITY 0x00000014
47
48 /******************************************************************************
49 *
50 * Default values for security control in customer configuration area in flash
51 * top sector.
52 *
53 ******************************************************************************/
54 const uint8_t g_ccfg_default_sec[] = {
55 0xFF, 0xFF, 0xFF, 0xC5,
56 0xFF, 0xFF, 0xFF, 0xFF,
57 0xC5, 0xFF, 0xFF, 0xFF,
58 0xC5, 0xC5, 0xC5, 0xFF,
59 0xC5, 0xC5, 0xC5, 0xFF
60 };
61
62 typedef uint32_t (*flash_prg_pntr_t) (uint8_t *, uint32_t, uint32_t);
63 typedef uint32_t (*flash_sector_erase_pntr_t) (uint32_t);
64
65 /******************************************************************************
66 *
67 * Function prototypes for static functions
68 *
69 ******************************************************************************/
70 static void issue_fsm_command(flash_state_command_t command);
71 static void enable_sectors_for_write(void);
72 static uint32_t scale_cycle_values(uint32_t specified_timing,
73 uint32_t scale_value);
74 static void set_write_mode(void);
75 static void trim_for_write(void);
76 static void set_read_mode(void);
77
78 /******************************************************************************
79 *
80 * Erase a flash sector
81 *
82 ******************************************************************************/
83 uint32_t flash_sector_erase(uint32_t sector_address)
84 {
85 uint32_t error_return;
86 flash_sector_erase_pntr_t func_pntr;
87
88 /* Call ROM function */
89 func_pntr = (uint32_t (*)(uint32_t))(ROM_API_FLASH_TABLE[5]);
90 error_return = func_pntr(sector_address);
91
92 /* Enable standby because ROM function might have disabled it */
93 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;
94
95 /* Return status of operation. */
96 return error_return;
97 }
98
99 /******************************************************************************
100 *
101 * Erase all unprotected sectors in the flash main bank
102 *
103 ******************************************************************************/
104 uint32_t flash_bank_erase(bool force_precondition)
105 {
106 uint32_t error_return;
107 uint32_t sector_address;
108 uint32_t reg_val;
109
110 /* Enable all sectors for erase. */
111 enable_sectors_for_write();
112
113 /* Clear the Status register. */
114 issue_fsm_command(FAPI_CLEAR_STATUS);
115
116 /* Enable erase of all sectors and enable precondition if required. */
117 reg_val = HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE);
118 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
119 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0x00000000;
120 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0x00000000;
121 if (force_precondition)
122 HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
123 FLASH_FSM_ST_MACHINE_DO_PRECOND;
124 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
125
126 /* Issue the bank erase command to the FSM. */
127 issue_fsm_command(FAPI_ERASE_BANK);
128
129 /* Wait for erase to finish. */
130 while (flash_check_fsm_for_ready() == FAPI_STATUS_FSM_BUSY)
131 ;
132
133 /* Update status. */
134 error_return = flash_check_fsm_for_error();
135
136 /* Disable sectors for erase. */
137 flash_disable_sectors_for_write();
138
139 /* Set configured precondition mode since it may have been forced on. */
140 if (!(reg_val & FLASH_FSM_ST_MACHINE_DO_PRECOND)) {
141 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
142 HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &=
143 ~FLASH_FSM_ST_MACHINE_DO_PRECOND;
144 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
145 }
146
147 /* Program security data to default values in the customer configuration */
148 /* area within the flash top sector if erase was successful. */
149 if (error_return == FAPI_STATUS_SUCCESS) {
150 sector_address = FLASHMEM_BASE + flash_size_get() -
151 flash_sector_size_get();
152 error_return = flash_program((uint8_t *)g_ccfg_default_sec,
153 (sector_address + CCFG_OFFSET_SECURITY),
154 CCFG_SIZE_SECURITY);
155 }
156
157 /* Return status of operation. */
158 return error_return;
159 }
160
161 /******************************************************************************
162 *
163 * Programs unprotected main bank flash sectors
164 *
165 ******************************************************************************/
166 uint32_t flash_program(uint8_t *data_buffer, uint32_t address, uint32_t count)
167 {
168 uint32_t error_return;
169 flash_prg_pntr_t func_pntr;
170
171 /* Call ROM function */
172 func_pntr = (uint32_t (*)(uint8_t *, uint32_t, uint32_t))
173 (ROM_API_FLASH_TABLE[6]);
174 error_return = func_pntr(data_buffer, address, count);
175
176 /* Enable standby because ROM function might have disabled it */
177 HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;
178
179 /* Return status of operation. */
180 return error_return;
181 }
182
183 /******************************************************************************
184 *
185 * Disables all sectors for erase and programming on the active bank
186 *
187 ******************************************************************************/
188 void flash_disable_sectors_for_write(void)
189 {
190 /* Configure flash back to read mode */
191 set_read_mode();
192
193 /* Disable Level 1 Protection. */
194 HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
195
196 /* Disable all sectors for erase and programming. */
197 HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
198
199 /* Enable Level 1 Protection. */
200 HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
201
202 /* Protect sectors from sector erase. */
203 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
204 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
205 HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
206 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
207 }
208
209 /******************************************************************************
210 *
211 * Issues a command to the Flash State Machine.
212 *
213 ******************************************************************************/
214 static void issue_fsm_command(flash_state_command_t command)
215 {
216 /* Enable write to FSM register. */
217 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
218
219 /* Issue FSM command. */
220 HWREG(FLASH_BASE + FLASH_O_FSM_CMD) = command;
221
222 /* Start command execute. */
223 HWREG(FLASH_BASE + FLASH_O_FSM_EXECUTE) = FLASH_CMD_EXEC;
224
225 /* Disable write to FSM register. */
226 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
227 }
228
229 /******************************************************************************
230 *
231 * Enables all sectors for erase and programming on the active bank.
232 *
233 * This function disables the idle reading power reduction mode, selects the
234 * flash bank and enables all sectors for erase and programming on the active
235 * bank.
236 * Sectors may be protected from programming depending on the value of the
237 * FLASH_O_FSM_BSLPx registers.
238 * Sectors may be protected from erase depending on the value of the
239 * FLASH_O_FSM_BSLEx registers. Additional sector erase protection is set by
240 * the FLASH_O_FSM_SECTOR1 register.
241 *
242 ******************************************************************************/
243 static void enable_sectors_for_write(void)
244 {
245 /* Trim flash module for program/erase operation. */
246 trim_for_write();
247
248 /* Configure flash to write mode */
249 set_write_mode();
250
251 /* Select flash bank. */
252 HWREG(FLASH_BASE + FLASH_O_FMAC) = 0x00;
253
254 /* Disable Level 1 Protection. */
255 HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
256
257 /* Enable all sectors for erase and programming. */
258 HWREG(FLASH_BASE + FLASH_O_FBSE) = 0xFFFF;
259
260 /* Enable Level 1 Protection */
261 HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
262 }
263
264 /******************************************************************************
265 *
266 * Trims the Flash Bank and Flash Pump for program/erase functionality
267 *
268 * This trimming will make it possible to perform erase and program operations
269 * of the flash. Trim values are loaded from factory configuration area
270 * (referred to as FCGF1). The trimming done by this function is valid until
271 * reset of the flash module.
272 *
273 * Some registers shall be written with a value that is a number of FCLK
274 * cycles. The trim values controlling these registers have a value of
275 * number of half us. FCLK = SysClk / ((RWAIT+1) x 2).
276 *
277 ******************************************************************************/
278 static void trim_for_write(void)
279 {
280 uint32_t value;
281 uint32_t temp_val;
282 uint32_t fclk_scale;
283 uint32_t rwait;
284
285 /* Return if flash is already trimmed for program/erase operations. */
286 if (HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_WRT_TRIMMED)
287 return;
288
289 /* Configure the FSM registers */
290
291 /* Enable access to the FSM registers. */
292 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
293
294 /* Determine the scaling value to be used on timing related trim values. */
295 /* The value is based on the flash module clock frequency and RWAIT */
296 rwait = (HWREG(FLASH_BASE + FLASH_O_FRDCTL) &
297 FLASH_FRDCTL_RWAIT_M) >> FLASH_FRDCTL_RWAIT_S;
298 fclk_scale = (16 * FLASH_MODULE_CLK_FREQ) / (rwait + 1);
299
300 /* Configure Program pulse width bits 15:0. */
301 /* (FCFG1 offset 0x188 bits 15:0). */
302 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &
303 FCFG1_FLASH_PROG_EP_PROGRAM_PW_M) >>
304 FCFG1_FLASH_PROG_EP_PROGRAM_PW_S;
305
306 value = scale_cycle_values(value, fclk_scale);
307
308 HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) =
309 (HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) &
310 ~FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M) |
311 ((value << FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_S) &
312 FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M);
313
314 /* Configure Erase pulse width bits 31:0. */
315 /* (FCFG1 offset 0x18C bits 31:0). */
316 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_ERA_PW) &
317 FCFG1_FLASH_ERA_PW_ERASE_PW_M) >>
318 FCFG1_FLASH_ERA_PW_ERASE_PW_S;
319
320 value = scale_cycle_values(value, fclk_scale);
321
322 HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) =
323 (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) &
324 ~FLASH_FSM_ERA_PW_FSM_ERA_PW_M) |
325 ((value << FLASH_FSM_ERA_PW_FSM_ERA_PW_S) &
326 FLASH_FSM_ERA_PW_FSM_ERA_PW_M);
327
328 /* Configure no of flash clock cycles from EXECUTEZ going low to the the
329 verify data can be read in the program verify mode bits 7:0. */
330 /* (FCFG1 offset 0x174 bits 23:16). */
331 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
332 FCFG1_FLASH_C_E_P_R_PV_ACCESS_M) >>
333 FCFG1_FLASH_C_E_P_R_PV_ACCESS_S;
334
335 value = scale_cycle_values(value, fclk_scale);
336
337 HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
338 (HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
339 ~FLASH_FSM_EX_VAL_EXE_VALD_M) |
340 ((value << FLASH_FSM_EX_VAL_EXE_VALD_S) &
341 FLASH_FSM_EX_VAL_EXE_VALD_M);
342
343 /* Configure the number of flash clocks from the start of the Read mode at
344 the end of the operations until the FSM clears the BUSY bit in FMSTAT. */
345 /* (FCFG1 offset 0x178 bits 23:16). */
346 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
347 FCFG1_FLASH_P_R_PV_RH_M) >>
348 FCFG1_FLASH_P_R_PV_RH_S;
349
350 HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) =
351 (HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) &
352 ~FLASH_FSM_RD_H_RD_H_M) |
353 ((value << FLASH_FSM_RD_H_RD_H_S) &
354 FLASH_FSM_RD_H_RD_H_M);
355
356 /* Configure Program hold time */
357 /* (FCFG1 offset 0x178 bits 31:24). */
358 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
359 FCFG1_FLASH_P_R_PV_PH_M) >>
360 FCFG1_FLASH_P_R_PV_PH_S;
361
362 value = scale_cycle_values(value, fclk_scale);
363
364 HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) =
365 (HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) &
366 ~FLASH_FSM_P_OH_PGM_OH_M) |
367 ((value << FLASH_FSM_P_OH_PGM_OH_S) &
368 FLASH_FSM_P_OH_PGM_OH_M);
369
370 /* Configure Erase hold time */
371 /* (FCFG1 offset 0x17C bits 31:24). */
372 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &
373 FCFG1_FLASH_EH_SEQ_EH_M) >>
374 FCFG1_FLASH_EH_SEQ_EH_S;
375
376 value = scale_cycle_values(value, fclk_scale);
377
378 HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) =
379 (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) &
380 ~FLASH_FSM_ERA_OH_ERA_OH_M) |
381 ((value << FLASH_FSM_ERA_OH_ERA_OH_S) &
382 FLASH_FSM_ERA_OH_ERA_OH_M);
383
384 /* Configure Program verify row switch time */
385 /* (FCFG1 offset0x178 bits 15:8). */
386 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
387 FCFG1_FLASH_P_R_PV_PVH_M) >>
388 FCFG1_FLASH_P_R_PV_PVH_S;
389
390 value = scale_cycle_values(value, fclk_scale);
391
392 HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) =
393 (HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) &
394 ~FLASH_FSM_PE_VH_PGM_VH_M) |
395 ((value << FLASH_FSM_PE_VH_PGM_VH_S) &
396 FLASH_FSM_PE_VH_PGM_VH_M);
397
398 /* Configure Program Operation Setup time */
399 /* (FCFG1 offset 0x170 bits 31:24). */
400 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
401 FCFG1_FLASH_E_P_PSU_M) >>
402 FCFG1_FLASH_E_P_PSU_S;
403
404 HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
405 (HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
406 ~FLASH_FSM_PE_OSU_PGM_OSU_M) |
407 ((value << FLASH_FSM_PE_OSU_PGM_OSU_S) &
408 FLASH_FSM_PE_OSU_PGM_OSU_M);
409
410 /* Configure Erase Operation Setup time */
411 /* (FCGF1 offset 0x170 bits 23:16). */
412 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
413 FCFG1_FLASH_E_P_ESU_M) >>
414 FCFG1_FLASH_E_P_ESU_S;
415
416 HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
417 (HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
418 ~FLASH_FSM_PE_OSU_ERA_OSU_M) |
419 ((value << FLASH_FSM_PE_OSU_ERA_OSU_S) &
420 FLASH_FSM_PE_OSU_ERA_OSU_M);
421
422 /* Confgure Program Verify Setup time */
423 /* (FCFG1 offset 0x170 bits 15:8). */
424 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
425 FCFG1_FLASH_E_P_PVSU_M) >>
426 FCFG1_FLASH_E_P_PVSU_S;
427
428 HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
429 (HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
430 ~FLASH_FSM_PE_VSU_PGM_VSU_M) |
431 ((value << FLASH_FSM_PE_VSU_PGM_VSU_S) &
432 FLASH_FSM_PE_VSU_PGM_VSU_M);
433
434 /* Configure Erase Verify Setup time */
435 /* (FCFG1 offset 0x170 bits 7:0). */
436 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
437 FCFG1_FLASH_E_P_EVSU_M) >>
438 FCFG1_FLASH_E_P_EVSU_S;
439
440 HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
441 (HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
442 ~FLASH_FSM_PE_VSU_ERA_VSU_M) |
443 ((value << FLASH_FSM_PE_VSU_ERA_VSU_S) &
444 FLASH_FSM_PE_VSU_ERA_VSU_M);
445
446 /* Configure Addr to EXECUTEZ low setup time */
447 /* (FCFG1 offset 0x174 bits 15:12). */
448 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
449 FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_M) >>
450 FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_S;
451
452 HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) =
453 (HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) &
454 ~FLASH_FSM_CMP_VSU_ADD_EXZ_M) |
455 ((value << FLASH_FSM_CMP_VSU_ADD_EXZ_S) &
456 FLASH_FSM_CMP_VSU_ADD_EXZ_M);
457
458 /* Configure Voltage Status Count */
459 /* (FCFG1 offset 0x17C bits 15:12). */
460 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &
461 FCFG1_FLASH_EH_SEQ_VSTAT_M) >>
462 FCFG1_FLASH_EH_SEQ_VSTAT_S;
463
464 HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) =
465 (HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) &
466 ~FLASH_FSM_VSTAT_VSTAT_CNT_M) |
467 ((value << FLASH_FSM_VSTAT_VSTAT_CNT_S) &
468 FLASH_FSM_VSTAT_VSTAT_CNT_M);
469
470 /* Configure Repeat Verify action setup */
471 /* (FCFG1 offset 0x174 bits 31:24). */
472 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
473 FCFG1_FLASH_C_E_P_R_RVSU_M) >>
474 FCFG1_FLASH_C_E_P_R_RVSU_S;
475
476 HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
477 (HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
478 ~FLASH_FSM_EX_VAL_REP_VSU_M) |
479 ((value << FLASH_FSM_EX_VAL_REP_VSU_S) &
480 FLASH_FSM_EX_VAL_REP_VSU_M);
481
482 /* Configure Maximum Programming Pulses */
483 /* (FCFG1 offset 0x184 bits 15:0). */
484 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PP) &
485 FCFG1_FLASH_PP_MAX_PP_M) >>
486 FCFG1_FLASH_PP_MAX_PP_S;
487
488 HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
489 (HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
490 ~FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M) |
491 ((value << FLASH_FSM_PRG_PUL_MAX_PRG_PUL_S) &
492 FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M);
493
494 /* Configure Beginning level for VHVCT used during erase modes */
495 /* (FCFG1 offset 0x180 bits 31:16). */
496 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &
497 FCFG1_FLASH_VHV_E_VHV_E_START_M) >>
498 FCFG1_FLASH_VHV_E_VHV_E_START_S;
499
500 HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
501 (HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
502 ~FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M) |
503 ((value << FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_S) &
504 FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M);
505
506 /* Configure Maximum EC Level */
507 /* (FCFG1 offset 0x2B0 bits 21:18). */
508 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
509 FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_M) >>
510 FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_S;
511
512 HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
513 (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
514 ~FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M) |
515 ((value << FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_S) &
516 FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M);
517
518 /* Configure Maximum Erase Pulses */
519 /* (FCFG1 offset 0x188 bits 31:16). */
520 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &
521 FCFG1_FLASH_PROG_EP_MAX_EP_M) >>
522 FCFG1_FLASH_PROG_EP_MAX_EP_S;
523
524 HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
525 (HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
526 ~FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M) |
527 ((value << FLASH_FSM_ERA_PUL_MAX_ERA_PUL_S) &
528 FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M);
529
530 /* Configure the VHVCT Step Size. This is the number of erase pulses that
531 must be completed for each level before the FSM increments the
532 CUR_EC_LEVEL to the next higher level. Actual erase pulses per level
533 equals (EC_STEP_SIZE +1). The stepping is only needed for the VHVCT
534 voltage. */
535 /* (FCFG1 offset 0x2B0 bits 31:23). */
536 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
537 FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_M) >>
538 FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_S;
539
540 HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) =
541 (HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) &
542 ~FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M) |
543 ((value << FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_S) &
544 FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M);
545
546 /* Configure the hight of each EC step. This is the number of counts that
547 the CUR_EC_LEVEL will increment when going to a new level. Actual count
548 size equals (EC_STEP_HEIGHT + 1). The stepping applies only to the VHVCT
549 voltage.
550 The read trim value is decremented by 1 before written to the register
551 since actual counts equals (register value + 1). */
552 /* (FCFG1 offset 0x180 bits 15:0). */
553 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &
554 FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_M) >>
555 FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_S;
556
557 HWREG(FLASH_BASE + FLASH_O_FSM_EC_STEP_HEIGHT) = ((value - 1) &
558 FLASH_FSM_EC_STEP_HEIGHT_EC_STEP_HEIGHT_M);
559
560 /* Configure Precondition used in erase operations */
561 /* (FCFG1 offset 0x2B0 bit 22). */
562 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
563 FCFG1_FLASH_OTP_DATA3_DO_PRECOND_M) >>
564 FCFG1_FLASH_OTP_DATA3_DO_PRECOND_S;
565
566 HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) =
567 (HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &
568 ~FLASH_FSM_ST_MACHINE_DO_PRECOND_M) |
569 ((value << FLASH_FSM_ST_MACHINE_DO_PRECOND_S) &
570 FLASH_FSM_ST_MACHINE_DO_PRECOND_M);
571
572 /* Enable the recommended Good Time function. */
573 HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
574 FLASH_FSM_ST_MACHINE_ONE_TIME_GOOD;
575
576 /* Disable write access to FSM registers. */
577 HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
578
579 /* Configure the voltage registers */
580
581 /* Unlock voltage registers (0x2080 - 0x2098). */
582 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
583
584 /* Configure voltage level for the specified pump voltage of high
585 voltage supply input during erase operation VHVCT_E and TRIM13_E */
586 /* (FCFG1 offset 0x190 bits[3:0] and bits[11:8]). */
587 temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);
588
589 value = ((temp_val & FCFG1_FLASH_VHV_TRIM13_E_M)>>
590 FCFG1_FLASH_VHV_TRIM13_E_S) << FLASH_FVHVCT1_TRIM13_E_S;
591 value |= ((temp_val & FCFG1_FLASH_VHV_VHV_E_M)>>
592 FCFG1_FLASH_VHV_VHV_E_S) << FLASH_FVHVCT1_VHVCT_E_S;
593
594 HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
595 ~(FLASH_FVHVCT1_TRIM13_E_M | FLASH_FVHVCT1_VHVCT_E_M)) | value;
596
597 /* Configure voltage level for the specified pump voltage of high voltage
598 supply input during program verify operation VHVCT_PV and TRIM13_PV */
599 /* (OTP offset 0x194 bits[19:16] and bits[27:24]). */
600 temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV);
601
602 value = ((temp_val & FCFG1_FLASH_VHV_PV_TRIM13_PV_M) >>
603 FCFG1_FLASH_VHV_PV_TRIM13_PV_S) << FLASH_FVHVCT1_TRIM13_PV_S;
604 value |= ((temp_val & FCFG1_FLASH_VHV_PV_VHV_PV_M) >>
605 FCFG1_FLASH_VHV_PV_VHV_PV_S) << FLASH_FVHVCT1_VHVCT_PV_S;
606
607 HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
608 ~(FLASH_FVHVCT1_TRIM13_PV_M | FLASH_FVHVCT1_VHVCT_PV_M)) | value;
609
610 /* Configure voltage level for the specified pump voltage of high voltage
611 supply input during program operation VHVCT_P and TRIM13_P */
612 /* (FCFG1 offset 0x190 bits[19:16] and bits[27:24]). */
613 temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);
614
615 value = ((temp_val & FCFG1_FLASH_VHV_TRIM13_P_M) >>
616 FCFG1_FLASH_VHV_TRIM13_P_S) << FLASH_FVHVCT2_TRIM13_P_S;
617 value |= ((temp_val & FCFG1_FLASH_VHV_VHV_P_M) >>
618 FCFG1_FLASH_VHV_VHV_P_S) << FLASH_FVHVCT2_VHVCT_P_S;
619
620 HWREG(FLASH_BASE + FLASH_O_FVHVCT2) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT2) &
621 ~(FLASH_FVHVCT2_TRIM13_P_M | FLASH_FVHVCT2_VHVCT_P_M)) | value;
622
623 /* Configure voltage level for the specified pump voltage of wordline power
624 supply for read mode */
625 /* (FCFG1 offset 0x198 Bits 15:8). */
626 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
627 FCFG1_FLASH_V_V_READ_M) >> FCFG1_FLASH_V_V_READ_S;
628
629 HWREG(FLASH_BASE + FLASH_O_FVREADCT) =
630 (HWREG(FLASH_BASE + FLASH_O_FVREADCT) &
631 ~FLASH_FVREADCT_VREADCT_M) |
632 ((value << FLASH_FVREADCT_VREADCT_S) &
633 FLASH_FVREADCT_VREADCT_M);
634
635 /* Configure the voltage level for the VCG 2.5 CT pump voltage */
636 /* (FCFG1 offset 0x194 bits 15:8). */
637 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV) &
638 FCFG1_FLASH_VHV_PV_VCG2P5_M) >>
639 FCFG1_FLASH_VHV_PV_VCG2P5_S;
640
641 HWREG(FLASH_BASE + FLASH_O_FVNVCT) =
642 (HWREG(FLASH_BASE + FLASH_O_FVNVCT) &
643 ~FLASH_FVNVCT_VCG2P5CT_M) |
644 ((value << FLASH_FVNVCT_VCG2P5CT_S) &
645 FLASH_FVNVCT_VCG2P5CT_M);
646
647 /* Configure the voltage level for the specified pump voltage of high
648 current power input during program operation */
649 /* (FCFG1 offset 0x198 bits 31:24). */
650 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
651 FCFG1_FLASH_V_VSL_P_M) >>
652 FCFG1_FLASH_V_VSL_P_S;
653
654 HWREG(FLASH_BASE + FLASH_O_FVSLP) =
655 (HWREG(FLASH_BASE + FLASH_O_FVSLP) &
656 ~FLASH_FVSLP_VSL_P_M) |
657 ((value << FLASH_FVSLP_VSL_P_S) &
658 FLASH_FVSLP_VSL_P_M);
659
660 /* Configure the voltage level for the specified pump voltage of wordline
661 power supply during programming operations */
662 /* (OTP offset 0x198 bits 23:16). */
663 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
664 FCFG1_FLASH_V_VWL_P_M) >>
665 FCFG1_FLASH_V_VWL_P_S;
666
667 HWREG(FLASH_BASE + FLASH_O_FVWLCT) =
668 (HWREG(FLASH_BASE + FLASH_O_FVWLCT) &
669 ~FLASH_FVWLCT_VWLCT_P_M) |
670 ((value << FLASH_FVWLCT_VWLCT_P_S) &
671 FLASH_FVWLCT_VWLCT_P_M);
672
673 /* Configure the pump's TRIM_1P7 port pins. */
674 /* (FCFG1 offset 0x2B0 bits 17:16). */
675 value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
676 FCFG1_FLASH_OTP_DATA3_TRIM_1P7_M) >>
677 FCFG1_FLASH_OTP_DATA3_TRIM_1P7_S;
678
679 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
680 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
681 ~FLASH_FSEQPMP_TRIM_1P7_M) |
682 ((value << FLASH_FSEQPMP_TRIM_1P7_S) &
683 FLASH_FSEQPMP_TRIM_1P7_M);
684
685 /* Lock the voltage registers. */
686 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
687
688 /* Set trimmed flag. */
689 HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
690 HWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_WRT_TRIMMED;
691 HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
692 }
693
694 /******************************************************************************
695 *
696 * Used to scale the TI OTP values based on the FClk scaling value.
697 *
698 ******************************************************************************/
699 static uint32_t scale_cycle_values(uint32_t specified_timing,
700 uint32_t scale_value)
701 {
702 uint32_t scaled_value = (specified_timing * scale_value) >> 6;
703 return scaled_value;
704 }
705
706 /******************************************************************************
707 *
708 * Used to set flash in read mode.
709 *
710 * Flash is configured with values loaded from OTP dependent on the current
711 * regulator mode.
712 *
713 ******************************************************************************/
714 static void set_read_mode(void)
715 {
716 uint32_t trim_value;
717 uint32_t value;
718
719 /* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
720 VIN_AT_X and VIN_BY_PASS for read mode */
721 if (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
722 AON_PMCTL_PWRCTL_EXT_REG_MODE) {
723
724 /* Select trim values for external regulator mode:
725 Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
726 Configure STANDBY_PW_SEL (OTP offset 0x308 bit 6:5)
727 Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
728 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
729
730 trim_value =
731 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
732
733 value = ((trim_value &
734 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
735 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
736 FLASH_CFG_STANDBY_MODE_SEL_S;
737
738 value |= ((trim_value &
739 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
740 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
741 FLASH_CFG_STANDBY_PW_SEL_S;
742
743 /* Configure DIS_STANDBY (OTP offset 0x308 bit 4).
744 Configure DIS_IDLE (OTP offset 0x308 bit 3). */
745 value |= ((trim_value &
746 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
747 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
748 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
749 FLASH_CFG_DIS_IDLE_S;
750
751 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
752 ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
753 FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
754
755 /* Check if sample and hold functionality is disabled. */
756 if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
757 /* Wait for disabled sample and hold functionality to be stable. */
758 while (!(HWREG(FLASH_BASE+FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
759 ;
760 }
761
762 /* Configure VIN_AT_X (OTP offset 0x308 bits 2:0) */
763 value = ((trim_value &
764 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
765 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
766 FLASH_FSEQPMP_VIN_AT_X_S;
767
768 /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
769 If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
770 VIN_BY_PASS should be 1 */
771 if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
772 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
773 value |= FLASH_FSEQPMP_VIN_BY_PASS;
774
775 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
776 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
777 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
778 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
779 FLASH_FSEQPMP_VIN_AT_X_M)) | value;
780 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
781 } else {
782
783 /* Select trim values for internal regulator mode:
784 Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
785 COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 14:13)
786 Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
787 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
788
789 trim_value =
790 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
791
792 value = ((trim_value &
793 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
794 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
795 FLASH_CFG_STANDBY_MODE_SEL_S;
796
797 value |= ((trim_value &
798 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
799 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
800 FLASH_CFG_STANDBY_PW_SEL_S;
801
802 /* Configure DIS_STANDBY (OTP offset 0x308 bit 12).
803 Configure DIS_IDLE (OTP offset 0x308 bit 11). */
804 value |= ((trim_value &
805 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
806 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
807 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
808 FLASH_CFG_DIS_IDLE_S;
809
810 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
811 ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
812 FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
813
814 /* Check if sample and hold functionality is disabled. */
815 if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
816 /* Wait for disabled sample and hold functionality to be stable. */
817 while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
818 ;
819 }
820
821 /* Configure VIN_AT_X (OTP offset 0x308 bits 10:8) */
822 value = (((trim_value &
823 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
824 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
825 FLASH_FSEQPMP_VIN_AT_X_S);
826
827 /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
828 If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
829 VIN_BY_PASS should be 1 */
830 if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
831 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
832 value |= FLASH_FSEQPMP_VIN_BY_PASS;
833
834 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
835 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
836 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
837 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
838 FLASH_FSEQPMP_VIN_AT_X_M)) | value;
839 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
840 }
841 }
842
843 /******************************************************************************
844 *
845 * Used to set flash in write mode.
846 *
847 * Flash is configured with values loaded from OTP dependent on the current
848 * regulator mode.
849 *
850 ******************************************************************************/
851 static void set_write_mode(void)
852 {
853 uint32_t trim_value;
854 uint32_t value;
855
856 /* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
857 VIN_AT_X and VIN_BY_PASS for program/erase mode */
858 if (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
859 AON_PMCTL_PWRCTL_EXT_REG_MODE) {
860
861 /* Select trim values for external regulator mode:
862 Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 23)
863 Configure STANDBY_PW_SEL (OTP offset 0x308 bit 22:21)
864 Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
865 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
866
867 trim_value =
868 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
869
870 value = ((trim_value &
871 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_M) >>
872 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_S) <<
873 FLASH_CFG_STANDBY_MODE_SEL_S;
874
875 value |= ((trim_value &
876 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_M) >>
877 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_S) <<
878 FLASH_CFG_STANDBY_PW_SEL_S;
879
880 /* Configure DIS_STANDBY (OTP offset 0x308 bit 20).
881 Configure DIS_IDLE (OTP offset 0x308 bit 19). */
882 value |= ((trim_value &
883 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_WRT_M |
884 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_M)) >>
885 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_S) <<
886 FLASH_CFG_DIS_IDLE_S;
887
888 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
889 ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
890 FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
891
892 /* Check if sample and hold functionality is disabled. */
893 if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
894 /* Wait for disabled sample and hold functionality to be stable. */
895 while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
896 ;
897 }
898
899 /* Configure VIN_AT_X (OTP offset 0x308 bits 18:16) */
900 value = ((trim_value &
901 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_M) >>
902 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_S) <<
903 FLASH_FSEQPMP_VIN_AT_X_S;
904
905 /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
906 If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
907 VIN_BY_PASS should be 1 */
908 if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
909 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
910 value |= FLASH_FSEQPMP_VIN_BY_PASS;
911
912 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
913 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
914 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
915 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
916 FLASH_FSEQPMP_VIN_AT_X_M)) | value;
917 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
918 } else {
919 /* Select trim values for internal regulator mode:
920 Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 31)
921 COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 30:29)
922 Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
923 HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
924
925 trim_value =
926 HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
927
928 value = ((trim_value &
929 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_M) >>
930 FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_S) <<
931 FLASH_CFG_STANDBY_MODE_SEL_S;
932
933 value |= ((trim_value &
934 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_M) >>
935 FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_S) <<
936 FLASH_CFG_STANDBY_PW_SEL_S;
937
938 /* Configure DIS_STANDBY (OTP offset 0x308 bit 28).
939 Configure DIS_IDLE (OTP offset 0x308 bit 27). */
940 value |= ((trim_value &
941 (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_WRT_M |
942 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_M)) >>
943 FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_S) <<
944 FLASH_CFG_DIS_IDLE_S;
945
946 HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
947 ~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
948 FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
949
950 /* Check if sample and hold functionality is disabled. */
951 if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
952 /* Wait for disabled sample and hold functionality to be stable. */
953 while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
954 ;
955 }
956
957 /* Configure VIN_AT_X (OTP offset 0x308 bits 26:24) */
958 value = ((trim_value &
959 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_M) >>
960 FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_S) <<
961 FLASH_FSEQPMP_VIN_AT_X_S;
962
963 /* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
964 If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
965 VIN_BY_PASS should be 1 */
966 if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
967 FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
968 value |= FLASH_FSEQPMP_VIN_BY_PASS;
969
970 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
971 HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
972 (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
973 ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
974 FLASH_FSEQPMP_VIN_AT_X_M)) | value;
975 HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
976 }
977 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)