Skip to content

Commit 9a9f078

Browse files
author
Guillaume Revaillot
committed
stm32device: add lock/unlock stuff
1 parent d53f26e commit 9a9f078

File tree

2 files changed

+138
-5
lines changed

2 files changed

+138
-5
lines changed

src/main/java/org/stm32flash/STM32Device.java

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.stm32flash;
22

33
import java.io.IOException;
4+
import java.io.UnsupportedEncodingException;
45
import java.util.ArrayList;
56
import java.util.Arrays;
67
import java.util.concurrent.TimeoutException;
@@ -19,7 +20,7 @@ public class STM32Device {
1920

2021
private static final int CMD_READ_MAX_SIZE = 256;
2122
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;
2324

2425
enum eraseParam {
2526
MASS_ERASE((byte) 0xff);
@@ -30,8 +31,6 @@ enum eraseParam {
3031
}
3132
}
3233

33-
private static final int READ_TIMEOUT_DEFAULT = 1 * 1000;
34-
private static final int ACK_TIMEOUT_DEFAULT = 1 * 1000;
3534
enum ExtendedEraseParam {
3635
BANK2_ERASE(0xfffd),
3736
BANK1_ERASE(0xfffe),
@@ -49,6 +48,9 @@ public byte[] getByteValue() {
4948
return b;
5049
}
5150
}
51+
52+
private static final int READ_TIMEOUT_DEFAULT = 4 * 1000;
53+
private static final int ACK_TIMEOUT_DEFAULT = 10 * 1000;
5254
private static final int ACK_TIMEOUT_INIT = 3 * 1000;
5355
private static final int ACK_TIMEOUT_MASS_ERASE = 30 * 1000;
5456

@@ -282,13 +284,16 @@ public boolean eraseFlash(int startAddress, int len) throws IOException, Timeout
282284
int pageCount = (endPage - startPage) + 1;
283285

284286
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 + ").");
286289

287290
if (mUseExtendedErase) {
288291
int pagesToErase = pageCount;
289292
while (pagesToErase > 0) {
290293
// 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.
292297
pageCount = Math.min(pagesToErase, CMD_EXTENDED_ERASE_MAX_PAGES);
293298

294299
byte[][] pageList = new byte[pageCount][2];
@@ -394,6 +399,79 @@ public boolean writeFlash(byte[] flash, boolean compare) throws IOException, Tim
394399
return true;
395400
}
396401

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+
397475
public boolean reset() throws IOException, TimeoutException {
398476
if (!cmdWriteMemory(mSTM32DevInfo.getRamStart() + 6 * 1024, stm_reset_code))
399477
return false;
@@ -572,6 +650,9 @@ private boolean cmdExtendedErase(byte[][] pages) throws IOException, TimeoutExce
572650
if (mDebug)
573651
System.out.println("cmdExtendedErase: " + pages.length + " pages");
574652

653+
if (pages.length > 512)
654+
System.out.println("cmdExtendedErase: Sending command with " + pages.length + " pages, brace yourself for strange behaviour.");
655+
575656
if (!writeCommand(STM32Command.ExtendedErase))
576657
return false;
577658

@@ -595,6 +676,21 @@ private boolean cmdExtendedErase(ExtendedEraseParam param) throws IOException, T
595676
return readAck(ACK_TIMEOUT_MASS_ERASE);
596677
}
597678

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+
598694
private boolean cmdGo(int address) throws IOException, TimeoutException {
599695
if (mDebug)
600696
System.out.println("cmdGo: 0x" + Integer.toHexString(address));
@@ -632,6 +728,8 @@ private boolean readAck(int timeout) throws IOException, TimeoutException {
632728
}
633729

634730
private boolean writeCommand(STM32Command command) throws IOException, TimeoutException {
731+
if (mDebug)
732+
System.out.println("writeCommand: " + command + " 0x" + Integer.toHexString(command.getCommandCode() & 0xff));
635733
write(new byte[] { command.getCommandCode(), (byte) ~command.getCommandCode()});
636734
return readAck();
637735
}

src/main/java/org/stm32flash/STM32Flasher.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,41 @@ public void disconnect() {
4040
mSTM32Device.disconnect();
4141
}
4242

43+
public boolean unlockFlashWrite() throws IOException, TimeoutException {
44+
if (!mSTM32Device.isConnected()) {
45+
if (!mSTM32Device.connect())
46+
return false;
47+
return false;
48+
}
49+
return mSTM32Device.writeUnprotect();
50+
}
51+
52+
public boolean lockFlashWrite() throws IOException, TimeoutException {
53+
if (!mSTM32Device.isConnected()) {
54+
if (!mSTM32Device.connect())
55+
return false;
56+
}
57+
return mSTM32Device.writeProtect();
58+
}
59+
60+
61+
public boolean lockFlashRead() throws IOException, TimeoutException {
62+
if (!mSTM32Device.isConnected()) {
63+
if (!mSTM32Device.connect())
64+
return false;
65+
}
66+
return mSTM32Device.readoutProtect();
67+
}
68+
69+
70+
public boolean unlockFlashRead() throws IOException, TimeoutException {
71+
if (!mSTM32Device.isConnected()) {
72+
if (!mSTM32Device.connect())
73+
return false;
74+
}
75+
return mSTM32Device.readoutUnprotect();
76+
}
77+
4378
public enum EraseMode {
4479
Partial,
4580
Full,

0 commit comments

Comments
 (0)