@@ -51,6 +51,12 @@ To add a new serial device, you must add an object to
5151 var flowControlXOFF = false ;
5252 /// Set up when flow control received - if no response is received we start sending anyway
5353 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 ;
5460
5561
5662 function init ( ) {
@@ -159,6 +165,88 @@ To add a new serial device, you must add an object to
159165 return openSerialInternal ( serialPort , connectCallback , disconnectCallback , 5 ) ;
160166 }
161167
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+
162250 var openSerialInternal = function ( serialPort , connectCallback , disconnectCallback , attempts ) {
163251 /* If openSerial is called, we need to have called getPorts first
164252 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
214302 connectCallback = undefined ;
215303 } ) ;
216304 }
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
263307 currentDevice = undefined ;
264308 if ( writeTimeout !== undefined )
265309 clearTimeout ( writeTimeout ) ;
0 commit comments