@@ -51,6 +51,12 @@ To add a new serial device, you must add an object to
51
51
var flowControlXOFF = false ;
52
52
/// Set up when flow control received - if no response is received we start sending anyway
53
53
var flowControlTimeout ;
54
+ /// used by rxDataHandler - last received character
55
+ let rxDataHandlerLastCh = 0 ;
56
+ /// used by rxDataHandler - used for parsing
57
+ let rxDataHandlerPacket = undefined ;
58
+ /// timeout for unfinished packet
59
+ let rxDataHandlerTimeout = undefined ;
54
60
55
61
56
62
function init ( ) {
@@ -159,6 +165,88 @@ To add a new serial device, you must add an object to
159
165
return openSerialInternal ( serialPort , connectCallback , disconnectCallback , 5 ) ;
160
166
}
161
167
168
+ var rxDataHandler = function ( data ) {
169
+ if ( ! ( data instanceof ArrayBuffer ) ) console . warn ( "Serial port implementation is not returning ArrayBuffers" )
170
+
171
+ // Filter incoming data to handle and remove control characters
172
+ const filteredData = new Uint8Array ( data ) . filter ( ( ch ) => {
173
+ let lastCh = rxDataHandlerLastCh ;
174
+ rxDataHandlerLastCh = ch ;
175
+
176
+ if ( rxDataHandlerPacket !== undefined ) {
177
+ rxDataHandlerPacket . push ( ch ) ;
178
+ let flags = ( rxDataHandlerPacket [ 0 ] << 8 ) | rxDataHandlerPacket [ 1 ] ;
179
+ let len = flags & 0x1FFF ;
180
+ let rxLen = rxDataHandlerPacket . length ;
181
+ if ( rxLen >= 2 && rxLen >= ( len + 2 ) ) {
182
+ console . log ( "Got packet end" ) ;
183
+ if ( rxDataHandlerTimeout ) {
184
+ clearTimeout ( rxDataHandlerTimeout ) ;
185
+ rxDataHandlerTimeout = undefined ;
186
+ }
187
+ emit ( "packet" , flags & 0xE000 , new Uint8Array ( rxDataHandlerPacket . slice ( 2 ) ) ) ;
188
+ rxDataHandlerPacket = undefined ; // stop packet reception
189
+ }
190
+ return false ; // don't pass data in packet through
191
+ } else switch ( ch ) {
192
+ case 16 : // DLE - potential start of packet (ignore)
193
+ return false ;
194
+
195
+ case 1 : // SOH - start of packet if after DLE
196
+ if ( lastCh == 16 /*DLE*/ ) {
197
+ console . log ( "Packet start received" ) ;
198
+ rxDataHandlerPacket = [ ] ;
199
+ rxDataHandlerTimeout = setTimeout ( ( ) => {
200
+ rxDataHandlerTimeout = undefined ;
201
+ console . log ( `Packet timeout (2s - contents ${ JSON . stringify ( rxDataHandlerPacket ) } )` ) ;
202
+ // TODO: emit packet error?
203
+ rxDataHandlerPacket = undefined ;
204
+ } , 2000 ) ;
205
+ return false ;
206
+ } else
207
+ return true ; // else pass through
208
+
209
+ case 17 : // XON
210
+ if ( Espruino . Config . SERIAL_FLOW_CONTROL && rxDataHandlerPacket === undefined ) {
211
+ console . log ( "XON received => resume upload" )
212
+ flowControlXOFF = false
213
+ if ( flowControlTimeout ) {
214
+ clearTimeout ( flowControlTimeout )
215
+ flowControlTimeout = undefined
216
+ }
217
+ }
218
+ return false ;
219
+
220
+ case 19 : // XOFF
221
+ if ( Espruino . Config . SERIAL_FLOW_CONTROL && rxDataHandlerPacket === undefined ) {
222
+ console . log ( "XOFF received => pause upload" )
223
+ flowControlXOFF = true
224
+ if ( flowControlTimeout ) clearTimeout ( flowControlTimeout )
225
+ flowControlTimeout = setTimeout ( function ( ) {
226
+ console . log (
227
+ `XOFF timeout (${ FLOW_CONTROL_RESUME_TIMEOUT } s) => resume upload anyway`
228
+ )
229
+ flowControlXOFF = false
230
+ flowControlTimeout = undefined
231
+ } , FLOW_CONTROL_RESUME_TIMEOUT )
232
+ }
233
+ return false ;
234
+
235
+ case 6 : // ACK
236
+ emit ( "ack" )
237
+ return false ;
238
+
239
+ case 21 : // NACK
240
+ emit ( "nack" )
241
+ return false ;
242
+ }
243
+
244
+ return true ;
245
+ } )
246
+
247
+ if ( readListener ) readListener ( filteredData . buffer )
248
+ } ;
249
+
162
250
var openSerialInternal = function ( serialPort , connectCallback , disconnectCallback , attempts ) {
163
251
/* If openSerial is called, we need to have called getPorts first
164
252
in order to figure out which one of the serial_ implementations
@@ -214,52 +302,8 @@ To add a new serial device, you must add an object to
214
302
connectCallback = undefined ;
215
303
} ) ;
216
304
}
217
- } , function ( data ) { // RECEIEVE DATA
218
- if ( ! ( data instanceof ArrayBuffer ) ) console . warn ( "Serial port implementation is not returning ArrayBuffers" )
219
-
220
- // Filter incoming data to handle and remove control characters
221
- const filteredData = new Uint8Array ( data ) . filter ( ( v ) => {
222
- switch ( v ) {
223
- case 17 : // XON
224
- if ( Espruino . Config . SERIAL_FLOW_CONTROL ) {
225
- console . log ( "XON received => resume upload" )
226
- flowControlXOFF = false
227
- if ( flowControlTimeout ) {
228
- clearTimeout ( flowControlTimeout )
229
- flowControlTimeout = undefined
230
- }
231
- }
232
- return false
233
-
234
- case 19 : // XOFF
235
- if ( Espruino . Config . SERIAL_FLOW_CONTROL ) {
236
- console . log ( "XOFF received => pause upload" )
237
- flowControlXOFF = true
238
- if ( flowControlTimeout ) clearTimeout ( flowControlTimeout )
239
- flowControlTimeout = setTimeout ( function ( ) {
240
- console . log (
241
- `XOFF timeout (${ FLOW_CONTROL_RESUME_TIMEOUT } s) => resume upload anyway`
242
- )
243
- flowControlXOFF = false
244
- flowControlTimeout = undefined
245
- } , FLOW_CONTROL_RESUME_TIMEOUT )
246
- }
247
- return false
248
-
249
- case 6 : // ACK
250
- emit ( "ack" )
251
- return false
252
-
253
- case 21 : // NACK
254
- emit ( "nack" )
255
- return false
256
- }
257
-
258
- return true
259
- } )
260
-
261
- if ( readListener ) readListener ( filteredData . buffer )
262
- } , function ( error ) { // DISCONNECT
305
+ } , rxDataHandler , // RECEIEVE DATA
306
+ function ( error ) { // DISCONNECT
263
307
currentDevice = undefined ;
264
308
if ( writeTimeout !== undefined )
265
309
clearTimeout ( writeTimeout ) ;
0 commit comments