Skip to content

Commit af728cf

Browse files
committed
STM32 DFU: more improvements
1 parent 7eda016 commit af728cf

File tree

3 files changed

+61
-18
lines changed

3 files changed

+61
-18
lines changed

examples/stm_dfu/src/main/java/net/codecrete/usb/dfu/DFU.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public static void main(String[] args) {
6464
System.out.println("Firmware successfully downloaded and verified");
6565

6666
device.startApplication();
67+
device.waitForDisconnect();
6768
System.out.println("DFU mode ended and firmware started");
6869

6970
device.close();

examples/stm_dfu/src/main/java/net/codecrete/usb/dfu/DFUDevice.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,27 @@ public void close() {
133133
usbDevice.close();
134134
}
135135

136+
/**
137+
* Waits until the device disconnects.
138+
* <p>
139+
* Disconnection is a side effect of leaving DFU mode.
140+
* </p>
141+
* <p>
142+
* If the device does not disconnect after 5 seconds,
143+
* an exception will be thrown.
144+
* </p>
145+
*/
146+
public void waitForDisconnect() {
147+
var waitingTime = 5000;
148+
while (waitingTime > 0 && usbDevice.isConnected()) {
149+
sleep(100);
150+
waitingTime -= 100;
151+
}
152+
153+
if (usbDevice.isConnected())
154+
throw new DFUException("Device did not restart (try disconnecting and reconnecting it)");
155+
}
156+
136157
/**
137158
* Clears an error status.
138159
*/
@@ -170,7 +191,7 @@ public DFUStatus getStatus() {
170191
public byte[] read(int address, int length) {
171192
expectState(DeviceState.DFU_IDLE, DeviceState.DFU_DNLOAD_IDLE);
172193
setAddress(address);
173-
exitDownloadMode();
194+
exitMode();
174195
expectState(DeviceState.DFU_IDLE, DeviceState.DFU_UPLOAD_IDLE);
175196

176197
var result = new byte[length];
@@ -187,20 +208,7 @@ public byte[] read(int address, int length) {
187208
blockNum += 1;
188209
}
189210

190-
// request zero length chunk to exit out of upload mode
191-
var transfer = createDfuControlTransfer(DFURequest.UPLOAD, blockNum);
192-
usbDevice.controlTransferIn(transfer, 0);
193-
194-
DFUStatus status;
195-
try {
196-
status = getStatus();
197-
} catch (DFUException e) {
198-
// Device might respond with an empty response; try again
199-
status = getStatus();
200-
}
201-
202-
if (status.state() != DeviceState.DFU_IDLE)
203-
throw new DFUException("Unexpected state after exiting from upload mode");
211+
exitMode();
204212

205213
return result;
206214
}
@@ -247,7 +255,7 @@ public void download(byte[] firmware) {
247255
transaction += 1;
248256
}
249257

250-
exitDownloadMode();
258+
exitMode();
251259
}
252260

253261
/**
@@ -327,7 +335,7 @@ private Page findPage(int address) {
327335
return Segment.findPage(segments, address);
328336
}
329337

330-
private void exitDownloadMode() {
338+
private void exitMode() {
331339
abort();
332340

333341
var status = getStatus();
@@ -340,6 +348,8 @@ private void exitDownloadMode() {
340348
public void startApplication() {
341349
expectState(DeviceState.DFU_IDLE, DeviceState.DFU_DNLOAD_IDLE);
342350

351+
// By sending a zero-length download packet and querying the status,
352+
// the device will leave DFU mode and restart.
343353
var transfer = createDfuControlTransfer(DFURequest.DOWNLOAD, 0);
344354
usbDevice.controlTransferOut(transfer, null);
345355

examples/stm_dfu/src/main/java/net/codecrete/usb/dfu/DFURequest.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,47 @@
1010
/**
1111
* DFU request.
1212
* <p>
13-
* See USB Device Class Specification for Device Firmware Upgrade, version 1.1.
13+
* See ST Microelectronics, application note AN3156.
1414
* </p>
1515
*/
1616
public enum DFURequest {
17+
/**
18+
* Requests the device to leave DFU mode and enter the application.
19+
* <p>
20+
* The Detach request is not meaningful in the case of the bootloader. The bootloader starts
21+
* with a system reset depending on the boot mode configuration settings, which means that
22+
* no other application is running at that time.
23+
* </p>
24+
*/
1725
DETACH,
26+
/**
27+
* Requests data transfer from Host to the device in order to load them
28+
* into device internal flash memory. Includes also erase commands.
29+
*/
1830
DOWNLOAD,
31+
/**
32+
* Requests data transfer from device to Host in order to load content
33+
* of device internal flash memory into a Host file.
34+
*/
1935
UPLOAD,
36+
/**
37+
* Requests device to send status report to the Host (including status
38+
* resulting from the last request execution and the state the device
39+
* enters immediately after this request).
40+
*/
2041
GET_STATUS,
42+
/**
43+
* Requests device to clear error status and move to next step.
44+
*/
2145
CLEAR_STATUS,
46+
/**
47+
* Requests the device to send only the state it enters immediately
48+
* after this request.
49+
*/
2250
GET_STATE,
51+
/**
52+
* Requests device to exit the current state/operation and enter idle
53+
* state immediately
54+
*/
2355
ABORT
2456
}

0 commit comments

Comments
 (0)