@@ -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
0 commit comments