@@ -171,6 +171,8 @@ struct stm32l4_part_info {
171
171
const uint32_t flash_regs_base ;
172
172
const uint32_t * default_flash_regs ;
173
173
const uint32_t fsize_addr ;
174
+ const uint32_t otp_base ;
175
+ const uint32_t otp_size ;
174
176
};
175
177
176
178
struct stm32l4_flash_bank {
@@ -183,6 +185,7 @@ struct stm32l4_flash_bank {
183
185
uint32_t wrpxxr_mask ;
184
186
const struct stm32l4_part_info * part_info ;
185
187
const uint32_t * flash_regs ;
188
+ bool otp_enabled ;
186
189
};
187
190
188
191
/* human readable list of families this drivers supports (sorted alphabetically) */
@@ -263,6 +266,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
263
266
.flash_regs_base = 0x40022000 ,
264
267
.default_flash_regs = stm32l4_flash_regs ,
265
268
.fsize_addr = 0x1FFF75E0 ,
269
+ .otp_base = 0x1FFF7000 ,
270
+ .otp_size = 1024 ,
266
271
},
267
272
{
268
273
.id = 0x435 ,
@@ -274,6 +279,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
274
279
.flash_regs_base = 0x40022000 ,
275
280
.default_flash_regs = stm32l4_flash_regs ,
276
281
.fsize_addr = 0x1FFF75E0 ,
282
+ .otp_base = 0x1FFF7000 ,
283
+ .otp_size = 1024 ,
277
284
},
278
285
{
279
286
.id = 0x460 ,
@@ -285,6 +292,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
285
292
.flash_regs_base = 0x40022000 ,
286
293
.default_flash_regs = stm32l4_flash_regs ,
287
294
.fsize_addr = 0x1FFF75E0 ,
295
+ .otp_base = 0x1FFF7000 ,
296
+ .otp_size = 1024 ,
288
297
},
289
298
{
290
299
.id = 0x461 ,
@@ -296,6 +305,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
296
305
.flash_regs_base = 0x40022000 ,
297
306
.default_flash_regs = stm32l4_flash_regs ,
298
307
.fsize_addr = 0x1FFF75E0 ,
308
+ .otp_base = 0x1FFF7000 ,
309
+ .otp_size = 1024 ,
299
310
},
300
311
{
301
312
.id = 0x462 ,
@@ -307,6 +318,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
307
318
.flash_regs_base = 0x40022000 ,
308
319
.default_flash_regs = stm32l4_flash_regs ,
309
320
.fsize_addr = 0x1FFF75E0 ,
321
+ .otp_base = 0x1FFF7000 ,
322
+ .otp_size = 1024 ,
310
323
},
311
324
{
312
325
.id = 0x464 ,
@@ -318,6 +331,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
318
331
.flash_regs_base = 0x40022000 ,
319
332
.default_flash_regs = stm32l4_flash_regs ,
320
333
.fsize_addr = 0x1FFF75E0 ,
334
+ .otp_base = 0x1FFF7000 ,
335
+ .otp_size = 1024 ,
321
336
},
322
337
{
323
338
.id = 0x466 ,
@@ -329,6 +344,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
329
344
.flash_regs_base = 0x40022000 ,
330
345
.default_flash_regs = stm32l4_flash_regs ,
331
346
.fsize_addr = 0x1FFF75E0 ,
347
+ .otp_base = 0x1FFF7000 ,
348
+ .otp_size = 1024 ,
332
349
},
333
350
{
334
351
.id = 0x468 ,
@@ -340,6 +357,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
340
357
.flash_regs_base = 0x40022000 ,
341
358
.default_flash_regs = stm32l4_flash_regs ,
342
359
.fsize_addr = 0x1FFF75E0 ,
360
+ .otp_base = 0x1FFF7000 ,
361
+ .otp_size = 1024 ,
343
362
},
344
363
{
345
364
.id = 0x469 ,
@@ -351,6 +370,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
351
370
.flash_regs_base = 0x40022000 ,
352
371
.default_flash_regs = stm32l4_flash_regs ,
353
372
.fsize_addr = 0x1FFF75E0 ,
373
+ .otp_base = 0x1FFF7000 ,
374
+ .otp_size = 1024 ,
354
375
},
355
376
{
356
377
.id = 0x470 ,
@@ -362,6 +383,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
362
383
.flash_regs_base = 0x40022000 ,
363
384
.default_flash_regs = stm32l4_flash_regs ,
364
385
.fsize_addr = 0x1FFF75E0 ,
386
+ .otp_base = 0x1FFF7000 ,
387
+ .otp_size = 1024 ,
365
388
},
366
389
{
367
390
.id = 0x471 ,
@@ -373,6 +396,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
373
396
.flash_regs_base = 0x40022000 ,
374
397
.default_flash_regs = stm32l4_flash_regs ,
375
398
.fsize_addr = 0x1FFF75E0 ,
399
+ .otp_base = 0x1FFF7000 ,
400
+ .otp_size = 1024 ,
376
401
},
377
402
{
378
403
.id = 0x472 ,
@@ -384,6 +409,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
384
409
.flash_regs_base = 0x40022000 ,
385
410
.default_flash_regs = stm32l5_ns_flash_regs ,
386
411
.fsize_addr = 0x0BFA05E0 ,
412
+ .otp_base = 0x0BFA0000 ,
413
+ .otp_size = 512 ,
387
414
},
388
415
{
389
416
.id = 0x479 ,
@@ -395,6 +422,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
395
422
.flash_regs_base = 0x40022000 ,
396
423
.default_flash_regs = stm32l4_flash_regs ,
397
424
.fsize_addr = 0x1FFF75E0 ,
425
+ .otp_base = 0x1FFF7000 ,
426
+ .otp_size = 1024 ,
398
427
},
399
428
{
400
429
.id = 0x495 ,
@@ -406,6 +435,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
406
435
.flash_regs_base = 0x58004000 ,
407
436
.default_flash_regs = stm32l4_flash_regs ,
408
437
.fsize_addr = 0x1FFF75E0 ,
438
+ .otp_base = 0x1FFF7000 ,
439
+ .otp_size = 1024 ,
409
440
},
410
441
{
411
442
.id = 0x496 ,
@@ -417,6 +448,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
417
448
.flash_regs_base = 0x58004000 ,
418
449
.default_flash_regs = stm32l4_flash_regs ,
419
450
.fsize_addr = 0x1FFF75E0 ,
451
+ .otp_base = 0x1FFF7000 ,
452
+ .otp_size = 1024 ,
420
453
},
421
454
{
422
455
.id = 0x497 ,
@@ -428,6 +461,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
428
461
.flash_regs_base = 0x58004000 ,
429
462
.default_flash_regs = stm32l4_flash_regs ,
430
463
.fsize_addr = 0x1FFF75E0 ,
464
+ .otp_base = 0x1FFF7000 ,
465
+ .otp_size = 1024 ,
431
466
},
432
467
};
433
468
@@ -439,6 +474,10 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command)
439
474
if (CMD_ARGC < 6 )
440
475
return ERROR_COMMAND_SYNTAX_ERROR ;
441
476
477
+ /* fix-up bank base address: 0 is used for normal flash memory */
478
+ if (bank -> base == 0 )
479
+ bank -> base = STM32_FLASH_BANK_BASE ;
480
+
442
481
stm32l4_info = calloc (1 , sizeof (struct stm32l4_flash_bank ));
443
482
if (!stm32l4_info )
444
483
return ERROR_FAIL ; /* Checkme: What better error to use?*/
@@ -449,11 +488,43 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command)
449
488
bank -> write_start_alignment = bank -> write_end_alignment = 8 ;
450
489
451
490
stm32l4_info -> probed = false;
491
+ stm32l4_info -> otp_enabled = false;
452
492
stm32l4_info -> user_bank_size = bank -> size ;
453
493
454
494
return ERROR_OK ;
455
495
}
456
496
497
+ static inline bool stm32l4_is_otp (struct flash_bank * bank )
498
+ {
499
+ struct stm32l4_flash_bank * stm32l4_info = bank -> driver_priv ;
500
+ return bank -> base == stm32l4_info -> part_info -> otp_base ;
501
+ }
502
+
503
+ static int stm32l4_otp_enable (struct flash_bank * bank , bool enable )
504
+ {
505
+ struct stm32l4_flash_bank * stm32l4_info = bank -> driver_priv ;
506
+
507
+ if (!stm32l4_is_otp (bank ))
508
+ return ERROR_FAIL ;
509
+
510
+ char * op_str = enable ? "enabled" : "disabled" ;
511
+
512
+ LOG_INFO ("OTP memory (bank #%d) is %s%s for write commands" ,
513
+ bank -> bank_number ,
514
+ stm32l4_info -> otp_enabled == enable ? "already " : "" ,
515
+ op_str );
516
+
517
+ stm32l4_info -> otp_enabled = enable ;
518
+
519
+ return ERROR_OK ;
520
+ }
521
+
522
+ static inline bool stm32l4_otp_is_enabled (struct flash_bank * bank )
523
+ {
524
+ struct stm32l4_flash_bank * stm32l4_info = bank -> driver_priv ;
525
+ return stm32l4_info -> otp_enabled ;
526
+ }
527
+
457
528
static inline uint32_t stm32l4_get_flash_reg (struct flash_bank * bank , uint32_t reg_offset )
458
529
{
459
530
struct stm32l4_flash_bank * stm32l4_info = bank -> driver_priv ;
@@ -693,6 +764,11 @@ static int stm32l4_erase(struct flash_bank *bank, unsigned int first,
693
764
694
765
assert ((first <= last ) && (last < bank -> num_sectors ));
695
766
767
+ if (stm32l4_is_otp (bank )) {
768
+ LOG_ERROR ("cannot erase OTP memory" );
769
+ return ERROR_FLASH_OPER_UNSUPPORTED ;
770
+ }
771
+
696
772
if (bank -> target -> state != TARGET_HALTED ) {
697
773
LOG_ERROR ("Target not halted" );
698
774
return ERROR_TARGET_NOT_HALTED ;
@@ -749,6 +825,11 @@ static int stm32l4_protect(struct flash_bank *bank, int set, unsigned int first,
749
825
struct target * target = bank -> target ;
750
826
struct stm32l4_flash_bank * stm32l4_info = bank -> driver_priv ;
751
827
828
+ if (stm32l4_is_otp (bank )) {
829
+ LOG_ERROR ("cannot protect/unprotect OTP memory" );
830
+ return ERROR_FLASH_OPER_UNSUPPORTED ;
831
+ }
832
+
752
833
if (target -> state != TARGET_HALTED ) {
753
834
LOG_ERROR ("Target not halted" );
754
835
return ERROR_TARGET_NOT_HALTED ;
@@ -883,6 +964,11 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
883
964
{
884
965
int retval = ERROR_OK , retval2 ;
885
966
967
+ if (stm32l4_is_otp (bank ) && !stm32l4_otp_is_enabled (bank )) {
968
+ LOG_ERROR ("OTP memory is disabled for write commands" );
969
+ return ERROR_FAIL ;
970
+ }
971
+
886
972
if (bank -> target -> state != TARGET_HALTED ) {
887
973
LOG_ERROR ("Target not halted" );
888
974
return ERROR_TARGET_NOT_HALTED ;
@@ -1001,6 +1087,29 @@ static int stm32l4_probe(struct flash_bank *bank)
1001
1087
1002
1088
LOG_INFO ("device idcode = 0x%08" PRIx32 " (%s)" , stm32l4_info -> idcode , device_info );
1003
1089
1090
+ if (stm32l4_is_otp (bank )) {
1091
+ bank -> size = part_info -> otp_size ;
1092
+
1093
+ LOG_INFO ("OTP size is %d bytes, base address is " TARGET_ADDR_FMT , bank -> size , bank -> base );
1094
+
1095
+ /* OTP memory is considered as one sector */
1096
+ free (bank -> sectors );
1097
+ bank -> num_sectors = 1 ;
1098
+ bank -> sectors = alloc_block_array (0 , part_info -> otp_size , 1 );
1099
+
1100
+ if (!bank -> sectors ) {
1101
+ LOG_ERROR ("failed to allocate bank sectors" );
1102
+ return ERROR_FAIL ;
1103
+ }
1104
+
1105
+
1106
+ stm32l4_info -> probed = true;
1107
+ return ERROR_OK ;
1108
+ } else if (bank -> base != STM32_FLASH_BANK_BASE ) {
1109
+ LOG_ERROR ("invalid bank base address" );
1110
+ return ERROR_FAIL ;
1111
+ }
1112
+
1004
1113
/* get flash size from target. */
1005
1114
retval = target_read_u16 (target , part_info -> fsize_addr , & flash_size_kb );
1006
1115
@@ -1175,7 +1284,6 @@ static int stm32l4_probe(struct flash_bank *bank)
1175
1284
free (bank -> sectors );
1176
1285
1177
1286
bank -> size = (flash_size_kb + gap_size_kb ) * 1024 ;
1178
- bank -> base = STM32_FLASH_BANK_BASE ;
1179
1287
bank -> num_sectors = num_pages ;
1180
1288
bank -> sectors = malloc (sizeof (struct flash_sector ) * bank -> num_sectors );
1181
1289
if (bank -> sectors == NULL ) {
@@ -1227,6 +1335,7 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size)
1227
1335
1228
1336
if (stm32l4_info -> probed )
1229
1337
snprintf (buf + buf_len , buf_size - buf_len , " - %s-bank" ,
1338
+ stm32l4_is_otp (bank ) ? "OTP" :
1230
1339
stm32l4_info -> dual_bank_mode ? "Flash dual" : "Flash single" );
1231
1340
1232
1341
return ERROR_OK ;
@@ -1244,6 +1353,11 @@ static int stm32l4_mass_erase(struct flash_bank *bank)
1244
1353
struct target * target = bank -> target ;
1245
1354
struct stm32l4_flash_bank * stm32l4_info = bank -> driver_priv ;
1246
1355
1356
+ if (stm32l4_is_otp (bank )) {
1357
+ LOG_ERROR ("cannot erase OTP memory" );
1358
+ return ERROR_FLASH_OPER_UNSUPPORTED ;
1359
+ }
1360
+
1247
1361
uint32_t action = FLASH_MER1 ;
1248
1362
1249
1363
if (stm32l4_info -> part_info -> has_dual_bank )
@@ -1410,6 +1524,11 @@ COMMAND_HANDLER(stm32l4_handle_lock_command)
1410
1524
if (ERROR_OK != retval )
1411
1525
return retval ;
1412
1526
1527
+ if (stm32l4_is_otp (bank )) {
1528
+ LOG_ERROR ("cannot lock/unlock OTP memory" );
1529
+ return ERROR_FLASH_OPER_UNSUPPORTED ;
1530
+ }
1531
+
1413
1532
target = bank -> target ;
1414
1533
1415
1534
if (target -> state != TARGET_HALTED ) {
@@ -1439,6 +1558,11 @@ COMMAND_HANDLER(stm32l4_handle_unlock_command)
1439
1558
if (ERROR_OK != retval )
1440
1559
return retval ;
1441
1560
1561
+ if (stm32l4_is_otp (bank )) {
1562
+ LOG_ERROR ("cannot lock/unlock OTP memory" );
1563
+ return ERROR_FLASH_OPER_UNSUPPORTED ;
1564
+ }
1565
+
1442
1566
target = bank -> target ;
1443
1567
1444
1568
if (target -> state != TARGET_HALTED ) {
@@ -1456,6 +1580,33 @@ COMMAND_HANDLER(stm32l4_handle_unlock_command)
1456
1580
return ERROR_OK ;
1457
1581
}
1458
1582
1583
+ COMMAND_HANDLER (stm32l4_handle_otp_command )
1584
+ {
1585
+ if (CMD_ARGC < 2 )
1586
+ return ERROR_COMMAND_SYNTAX_ERROR ;
1587
+
1588
+ struct flash_bank * bank ;
1589
+ int retval = CALL_COMMAND_HANDLER (flash_command_get_bank , 0 , & bank );
1590
+ if (ERROR_OK != retval )
1591
+ return retval ;
1592
+
1593
+ if (!stm32l4_is_otp (bank )) {
1594
+ command_print (CMD , "the specified bank is not an OTP memory" );
1595
+ return ERROR_FAIL ;
1596
+ }
1597
+ if (strcmp (CMD_ARGV [1 ], "enable" ) == 0 )
1598
+ stm32l4_otp_enable (bank , true);
1599
+ else if (strcmp (CMD_ARGV [1 ], "disable" ) == 0 )
1600
+ stm32l4_otp_enable (bank , false);
1601
+ else if (strcmp (CMD_ARGV [1 ], "show" ) == 0 )
1602
+ command_print (CMD , "OTP memory bank #%d is %s for write commands." ,
1603
+ bank -> bank_number , stm32l4_otp_is_enabled (bank ) ? "enabled" : "disabled" );
1604
+ else
1605
+ return ERROR_COMMAND_SYNTAX_ERROR ;
1606
+
1607
+ return ERROR_OK ;
1608
+ }
1609
+
1459
1610
static const struct command_registration stm32l4_exec_command_handlers [] = {
1460
1611
{
1461
1612
.name = "lock" ,
@@ -1499,6 +1650,13 @@ static const struct command_registration stm32l4_exec_command_handlers[] = {
1499
1650
.usage = "bank_id" ,
1500
1651
.help = "Force re-load of device options (will cause device reset)." ,
1501
1652
},
1653
+ {
1654
+ .name = "otp" ,
1655
+ .handler = stm32l4_handle_otp_command ,
1656
+ .mode = COMMAND_EXEC ,
1657
+ .usage = "<bank_id> <enable|disable|show>" ,
1658
+ .help = "OTP (One Time Programmable) memory write enable/disable" ,
1659
+ },
1502
1660
COMMAND_REGISTRATION_DONE
1503
1661
};
1504
1662
0 commit comments