1
1
package org .stm32flash ;
2
2
3
3
import java .io .IOException ;
4
+ import java .io .UnsupportedEncodingException ;
4
5
import java .util .ArrayList ;
5
6
import java .util .Arrays ;
6
7
import java .util .concurrent .TimeoutException ;
@@ -19,7 +20,7 @@ public class STM32Device {
19
20
20
21
private static final int CMD_READ_MAX_SIZE = 256 ;
21
22
private static final int CMD_WRITE_MAX_SIZE = 256 ;
22
- private static final int CMD_EXTENDED_ERASE_MAX_PAGES = 512 ;
23
+ private static final int CMD_EXTENDED_ERASE_MAX_PAGES = 256 ;
23
24
24
25
enum eraseParam {
25
26
MASS_ERASE ((byte ) 0xff );
@@ -30,8 +31,6 @@ enum eraseParam {
30
31
}
31
32
}
32
33
33
- private static final int READ_TIMEOUT_DEFAULT = 1 * 1000 ;
34
- private static final int ACK_TIMEOUT_DEFAULT = 1 * 1000 ;
35
34
enum ExtendedEraseParam {
36
35
BANK2_ERASE (0xfffd ),
37
36
BANK1_ERASE (0xfffe ),
@@ -49,6 +48,9 @@ public byte[] getByteValue() {
49
48
return b ;
50
49
}
51
50
}
51
+
52
+ private static final int READ_TIMEOUT_DEFAULT = 4 * 1000 ;
53
+ private static final int ACK_TIMEOUT_DEFAULT = 10 * 1000 ;
52
54
private static final int ACK_TIMEOUT_INIT = 3 * 1000 ;
53
55
private static final int ACK_TIMEOUT_MASS_ERASE = 30 * 1000 ;
54
56
@@ -282,13 +284,16 @@ public boolean eraseFlash(int startAddress, int len) throws IOException, Timeout
282
284
int pageCount = (endPage - startPage ) + 1 ;
283
285
284
286
if (mDebug )
285
- System .out .println ("eraseFlash 0x" + Integer .toHexString (startAddress ) + ":0x" + Integer .toHexString (endAddress ) + " : " + pageCount + " pages to erase. (" + startPage + ":" + endPage + ")." );
287
+ System .out .println ("eraseFlash 0x" + Integer .toHexString (startAddress ) + ":0x" + Integer .toHexString (endAddress ) + " : " +
288
+ pageCount + " " + pagesSizes [0 ] + "b pages to erase. (" + startPage + ":" + endPage + ")." );
286
289
287
290
if (mUseExtendedErase ) {
288
291
int pagesToErase = pageCount ;
289
292
while (pagesToErase > 0 ) {
290
293
// we need limit number of erased pages per extended erase command
291
- // because some boots apparently do not like massive page list..
294
+ // because some devices apparently do not like massive page list.
295
+ // nb: AN mention a maxium number of sector per device for that
296
+ // command, but this does not seem to be specified anywhere.
292
297
pageCount = Math .min (pagesToErase , CMD_EXTENDED_ERASE_MAX_PAGES );
293
298
294
299
byte [][] pageList = new byte [pageCount ][2 ];
@@ -394,6 +399,79 @@ public boolean writeFlash(byte[] flash, boolean compare) throws IOException, Tim
394
399
return true ;
395
400
}
396
401
402
+ public boolean readoutProtect () throws IOException , TimeoutException {
403
+ return readoutProtect (mSTM32DevInfo .getFlashStart (), mSTM32DevInfo .getFlashSize ());
404
+ }
405
+
406
+ private boolean readoutProtect (int start , int len ) throws IOException , TimeoutException {
407
+ return multiplePageCommand (STM32Command .ReadoutProtect , start , len );
408
+ }
409
+
410
+ public boolean readoutUnprotect () throws IOException , TimeoutException {
411
+ return readoutUnprotect (mSTM32DevInfo .getFlashStart (), mSTM32DevInfo .getFlashSize ());
412
+ }
413
+
414
+ private boolean readoutUnprotect (int start , int len ) throws IOException , TimeoutException {
415
+ return multiplePageCommand (STM32Command .ReadoutUnprotect , start , len );
416
+ }
417
+
418
+ public boolean writeUnprotect () throws IOException , TimeoutException {
419
+ return writeUnprotect (mSTM32DevInfo .getFlashStart (), mSTM32DevInfo .getFlashSize ());
420
+ }
421
+
422
+ private boolean writeUnprotect (int start , int len ) throws IOException , TimeoutException {
423
+ return multiplePageCommand (STM32Command .WriteUnprotect , start , len );
424
+ }
425
+
426
+ public boolean writeProtect () throws IOException , TimeoutException {
427
+ return writeProtect (mSTM32DevInfo .getFlashStart (), mSTM32DevInfo .getFlashSize ());
428
+ }
429
+
430
+ private boolean writeProtect (int start , int len ) throws IOException , TimeoutException {
431
+ return multiplePageCommand (STM32Command .WriteProtect , start , len );
432
+ }
433
+
434
+ private boolean multiplePageCommand (STM32Command command , int startAddress , int len ) throws IOException , TimeoutException {
435
+ int [] pagesSizes = mSTM32DevInfo .getPagesSize ();
436
+ int endAddress = startAddress + len ;
437
+
438
+ if (pagesSizes .length > 1 )
439
+ throw new UnsupportedOperationException ("target has multiple pages size, no support yet, use EraseAll." );
440
+
441
+ int startPage = getFlashAddressPage (startAddress );
442
+ int endPage = getFlashAddressPage (endAddress - 1 );
443
+ int pageCount = (endPage - startPage ) + 1 ;
444
+
445
+ if (mDebug )
446
+ System .out .println ("multiplePageCommand " + command + " 0x" + Integer .toHexString (startAddress ) + ":0x" + Integer .toHexString (endAddress ) + " : " +
447
+ pageCount + " " + pagesSizes [0 ] + "b pages. (" + startPage + ":" + endPage + ")." );
448
+
449
+ int pagesToErase = pageCount ;
450
+ while (pagesToErase > 0 ) {
451
+ pageCount = Math .min (pagesToErase , 255 );
452
+
453
+ byte [][] pageList = new byte [pageCount ][2 ];
454
+ for (int i = 0 ; i < pageCount ; i ++) {
455
+ int page = (startPage + i );
456
+ if (mDebug )
457
+ System .out .println ("adding page " + page + " to list." );
458
+ pageList [i ][0 ] = (byte ) (page >> 8 );
459
+ pageList [i ][1 ] = (byte ) (page & 0xff );
460
+ }
461
+
462
+ if (!cmdGenericReadWriteProtectUnprotect (command , pageList ))
463
+ return false ;
464
+
465
+ startPage += pageCount ;
466
+ pagesToErase -= pageCount ;
467
+ }
468
+
469
+ System .out .println (" Done." );
470
+ complete (true );
471
+
472
+ return true ;
473
+ }
474
+
397
475
public boolean reset () throws IOException , TimeoutException {
398
476
if (!cmdWriteMemory (mSTM32DevInfo .getRamStart () + 6 * 1024 , stm_reset_code ))
399
477
return false ;
@@ -572,6 +650,9 @@ private boolean cmdExtendedErase(byte[][] pages) throws IOException, TimeoutExce
572
650
if (mDebug )
573
651
System .out .println ("cmdExtendedErase: " + pages .length + " pages" );
574
652
653
+ if (pages .length > 512 )
654
+ System .out .println ("cmdExtendedErase: Sending command with " + pages .length + " pages, brace yourself for strange behaviour." );
655
+
575
656
if (!writeCommand (STM32Command .ExtendedErase ))
576
657
return false ;
577
658
@@ -595,6 +676,21 @@ private boolean cmdExtendedErase(ExtendedEraseParam param) throws IOException, T
595
676
return readAck (ACK_TIMEOUT_MASS_ERASE );
596
677
}
597
678
679
+ private boolean cmdGenericReadWriteProtectUnprotect (STM32Command command , byte [][] pages ) throws IOException , TimeoutException {
680
+ if (mDebug )
681
+ System .out .println (command + ": " + pages .length + " pages" );
682
+
683
+ if (pages .length > 255 )
684
+ return false ;
685
+
686
+ if (!writeCommand (command ))
687
+ return false ;
688
+
689
+ writePagesWithChecksum (pages );
690
+
691
+ return readAck (ACK_TIMEOUT_DEFAULT );
692
+ }
693
+
598
694
private boolean cmdGo (int address ) throws IOException , TimeoutException {
599
695
if (mDebug )
600
696
System .out .println ("cmdGo: 0x" + Integer .toHexString (address ));
@@ -632,6 +728,8 @@ private boolean readAck(int timeout) throws IOException, TimeoutException {
632
728
}
633
729
634
730
private boolean writeCommand (STM32Command command ) throws IOException , TimeoutException {
731
+ if (mDebug )
732
+ System .out .println ("writeCommand: " + command + " 0x" + Integer .toHexString (command .getCommandCode () & 0xff ));
635
733
write (new byte [] { command .getCommandCode (), (byte ) ~command .getCommandCode ()});
636
734
return readAck ();
637
735
}
0 commit comments