3535import java .io .FileDescriptor ;
3636import java .io .FileInputStream ;
3737import java .io .FileOutputStream ;
38+ import java .io .IOException ;
3839import java .io .InputStream ;
3940import java .io .OutputStream ;
4041
4748class UsbConnection implements IOIOConnection {
4849 private static final String TAG = UsbConnection .class .getSimpleName ();
4950 private static final int SOFT_RESET = 0x01 ;
51+ private static final int HARD_RESET = 0x00 ;
52+ private static final int MAX_RETRIES = 10 ;
5053 private ConnectionState state ;
5154 private FixedReadBufferedInputStream inputStream ;
5255 private OutputStream outputStream ;
@@ -73,17 +76,8 @@ public boolean canClose() {
7376 public synchronized void disconnect () {
7477 Log .i (TAG , "disconnect entered" );
7578 if (this .state != ConnectionState .DISCONNECTED ) {
76- this .state = ConnectionState .DISCONNECTED ;
7779 IOUtil .setError ("USB disconnected" );
78- if (fileDescriptor != null ) {
79- try {
80- fileDescriptor .close ();
81- } catch (java .io .IOException e ) {
82- IOUtil .setError ("Failed to close file descriptor" );
83- Log .e (TAG , "Failed to close file descriptor." , e );
84- }
85- fileDescriptor = null ;
86- }
80+ close ();
8781 }
8882 Log .d (TAG , "leaving disconnect" );
8983 }
@@ -103,10 +97,6 @@ public synchronized void waitForConnect() {
10397 if (state != ConnectionState .INIT ) {
10498 throw new IllegalStateException ("waitForConnect() may only be called once" );
10599 }
106- this .fileDescriptor = UsbUtil .getParcelFileDescriptor ();
107- if (this .fileDescriptor == null ) {
108- throw new IOIOException ("Failed to obtain descriptor" );
109- }
110100 if (open ()) {
111101 state = ConnectionState .CONNECTED ;
112102 } else {
@@ -119,34 +109,87 @@ protected void finalize() {
119109 disconnect ();
120110 }
121111
112+ private void close () {
113+ state = ConnectionState .DISCONNECTED ;
114+ try {
115+ if (inputStream != null ) {
116+ inputStream .close ();
117+ }
118+ if (outputStream != null ) {
119+ outputStream .close ();
120+ }
121+ if (fileDescriptor != null ) {
122+ fileDescriptor .close ();
123+ }
124+ inputStream = null ;
125+ outputStream = null ;
126+ fileDescriptor = null ;
127+ } catch (java .io .IOException e ) {
128+ IOUtil .setError ("Failed to close file descriptor: " + e );
129+ Log .e (TAG , "Failed to close file descriptor." , e );
130+ }
131+ }
132+
133+ private void handleResetResponse (int attempt ) throws IOException {
134+ if (attempt > 0 ) {
135+ int response = inputStream .read ();
136+ Log .e (TAG , "Response:" + response + " available:" + inputStream .available ());
137+ if (response != SOFT_RESET ) {
138+ // fail
139+ if (inputStream .available () == 0 ) {
140+ try {
141+ Thread .sleep (100 );
142+ }
143+ catch (InterruptedException e ) {
144+ throw new IOIOException (e );
145+ }
146+ }
147+ handleResetResponse (attempt - 1 );
148+ }
149+ } else {
150+ throw new IOIOException ("USB connection failure" );
151+ }
152+ }
153+
122154 private boolean open () {
123155 boolean result = false ;
124156 Log .i (TAG , "open() entered" );
125157
126158 try {
127- FileDescriptor fd = fileDescriptor .getFileDescriptor ();
128- inputStream = new FixedReadBufferedInputStream (new FileInputStream (fd ), 1024 );
129- outputStream = new BufferedOutputStream (new FileOutputStream (fd ), 1024 );
130- outputStream .write (SOFT_RESET );
131- outputStream .flush ();
132- int response = inputStream .read ();
133- if (response == SOFT_RESET ) {
134- result = true ;
135- } else {
136- IOUtil .setError ("Unexpected response: " + response );
137- }
159+ openStreams ();
160+ resetBoard ();
161+ handleResetResponse (MAX_RETRIES );
162+ result = true ;
138163 } catch (java .io .IOException e ) {
139164 IOUtil .setError ("Failed to open streams: " + e );
140165 } finally {
141166 if (!result ) {
142- try {
143- fileDescriptor .close ();
144- } catch (java .io .IOException e ) {
145- Log .e (TAG , "Failed to close file descriptor." , e );
146- }
147- fileDescriptor = null ;
167+ close ();
148168 }
149169 }
150170 return result ;
151171 }
172+
173+ private void openStreams () {
174+ this .fileDescriptor = UsbUtil .getParcelFileDescriptor ();
175+ if (this .fileDescriptor == null ) {
176+ throw new IOIOException ("Failed to obtain descriptor" );
177+ }
178+ FileDescriptor fd = fileDescriptor .getFileDescriptor ();
179+ inputStream = new FixedReadBufferedInputStream (new FileInputStream (fd ), 1024 );
180+ outputStream = new BufferedOutputStream (new FileOutputStream (fd ), 1024 );
181+ }
182+
183+ private void resetBoard () throws IOException {
184+ if (IOUtil .getHardReset ()) {
185+ outputStream .write (HARD_RESET );
186+ outputStream .write ('I' );
187+ outputStream .write ('O' );
188+ outputStream .write ('I' );
189+ outputStream .write ('O' );
190+ } else {
191+ outputStream .write (SOFT_RESET );
192+ }
193+ outputStream .flush ();
194+ }
152195}
0 commit comments