source: cpu/x86/pc/olpc/terminal.fth

Last change on this file was 3662, checked in by quozl, 11 months ago

OLPC - avoid duplicate file creation. #12684.

File size: 8.9 KB
Line 
1purpose: Serial terminal emulator
2\ See license at end of file
3
4vocabulary serial-terminal
5also serial-terminal definitions
6
7d# 1 value break-ms
8
9d# 80 constant /buf
10/buf buffer: buf
11
12
13\ queue implementation (adapted from dev/16550pkg/16550.fth)
14
15\ size of queues, approx 10 seconds at 115200 baud
16d# 144000 constant /q
17
18struct
19   /n field >head
20   /n field >tail
21   /q field >qdata
22constant /qstruct
23
24/qstruct buffer: read-q  \ for reading from serial
25/qstruct buffer: emit-q  \ for showing to display
26
27: init-q  ( q -- )  0 over >head !  0 swap >tail !   ;
28: inc-q-ptr  ( pointer-addr -- )
29   dup @  ca1+  dup /q  =  if  drop 0  then  swap !
30;
31
32: enque  ( new-entry q -- )
33   >r
34   r@ >tail @  r@ >head @  2dup >  if  - /q  then  1-     ( entry tail head )
35   <>  if  r@ >qdata  r@ >tail @ ca+ c!  r@ >tail inc-q-ptr  else  drop  then
36   r> drop
37;
38
39: deque?  ( q -- false | entry true )
40   >r
41   r@ >head @  r@ >tail @  <>  if
42      r@ >qdata  r@ >head @  ca+ c@  r@ >head inc-q-ptr  true
43   else
44      false
45   then
46   r> drop
47;
48
49\ end of queue implementation
50
51
52\ queued screen output
53
54: >q  ( adr len )
55   bounds  do  i c@  emit-q enque  loop
56;
57
58: q>  ( -- )
59   emit-q deque?  if  emit  then
60;
61
62\ end of queued screen output
63
64
65\ serial device independent interface
66
67defer serial-open   ( -- )
68defer serial-close  ( -- )
69defer serial-emit   ( key -- )
70defer serial-read   ( -- adr len )
71defer serial-break  ( -- )
72
73\ end of serial device independent interface
74
75
76\ internal serial device implementation
77
78\ interrupt enable register UART_IER, table 1993, page 1547
79: ier@  ( -- b )  h# 1 uart@  ;
80: ier!  ( b -- )  h# 1 uart!  ;
81
82\ receiver data available interrupt enable
83: ravie-on   ( -- )  ier@ h# 1 or ier!  ;
84: ravie-off  ( -- )  ier@ h# 1 invert and ier!  ;
85
86\ line control register UART_LCR, table 1998, page 1554
87: ulcr@  ( -- b )  h# 3 uart@  ;
88: ulcr!  ( b -- )  h# 3 uart!  ;
89
90\ set break
91: sb-on   ( -- )  ulcr@ h# 40 or ulcr!  ;
92: sb-off  ( -- )  ulcr@ h# 40 invert and ulcr!  ;
93
94\ modem control register UART_MCR, table 1999, page 1555
95: mcr@  ( -- b )  h# 4 uart@  ;
96: mcr!  ( b -- )  h# 4 uart!  ;
97
98\ OUT2 signal control, enable UART interrupts
99: out2-on   ( -- )  mcr@ h# 8 or mcr!  ;
100: out2-off  ( -- )  mcr@ h# 8 invert and mcr!  ;
101
102: uart-break
103   begin  uemit?  until
104   sb-on
105   break-ms ms
106   sb-off
107;
108
109\ IRQ number of console UART varies by platform
110\ FIXME: find a better way to store or find these
111[ifdef] olpc-cl1
112   d# 4 value irq#
113[then]
114[ifdef] mmp2
115   d# 24 value irq#
116[then]
117[ifdef] mmp3
118   d# 28 value irq#
119[then]
120
121\ serial interrupt handler for received data
122: si ( -- )  ukey read-q enque  ;
123
124\ enable serial interrupt
125: esi
126   ['] si irq# interrupt-handler!
127   irq# enable-interrupt
128   ravie-on
129   out2-on
130;
131
132\ disable serial interrupt
133: dsi
134   out2-off
135   ravie-off
136   irq# disable-interrupt
137;
138
139\ on XO-1.5, enable-serial disables the camera and adds the serial
140\ instance handles to the multiplexor.  on other models it is absent.
141[ifndef] enable-serial  \ present on XO-1.5
142: enable-serial ;
143[then]
144
145false value uart-console-off?  \ did we turn our uart console off?
146
147\ stop using the uart as console
148\ (necessary to avoid noise from interconnected hosts)
149: uart-console-off
150   fallback-out-ih remove-output
151   fallback-in-ih remove-input
152   true to uart-console-off?
153;
154
155\ resume using the uart as console
156: uart-console-on
157   uart-console-off? if
158      fallback-out-ih add-output
159      fallback-in-ih add-input
160      false to uart-console-off?
161   then
162;
163
164: uart-open
165   enable-serial
166   uart-console-off
167   read-q init-q
168   esi
169;
170
171: uart-close
172   dsi
173;
174
175: uart-read  ( -- adr len )
176   buf 0  ( adr len )
177   read-q deque?  0=  if  exit  then   ( adr len char )
178   begin                               ( adr len char )
179      >r 2dup + r> swap c! 1+          ( adr len' )
180      dup /buf =  if  exit  then  ( adr len' )
181      read-q deque?  0=
182   until                               ( adr len' )
183;
184
185\
186\ FIXME: XO-1, seen only once, ukey? did stop returning true, and ukey
187\ therefore hung waiting for ukey?
188\
189\ condition was cleared by  0 uart@  despite ukey? returning false
190\
191\ when it occurs again, try looking at fifo error summary bit, and
192\ line status reg, and consider comment from 16550.fth:
193\
194\ "I have seen conditions where a UART will report, via an interrupt,
195\ that a character is available, but the line status register won't
196\ report it."
197\
198
199: use-uart
200   uart-console-off
201   ['] uart-open   to  serial-open
202   ['] uart-close  to  serial-close
203   ['] uemit       to  serial-emit
204   ['] uart-read   to  serial-read
205   ['] uart-break  to  serial-break
206;
207
208\ end of internal serial device implementation
209
210
211\ USB serial device implementation
212
2130 value serial-ih
214
215: usb-open  ( -- )
216   " /usb/serial" open-dev ?dup if  to serial-ih  exit  then
217   [ifdef] olpc-cl1
218      \ XO-1.5
219      " /usb@10/serial" open-dev ?dup if  to serial-ih  exit  then
220      \ XO-1
221      " /usb@f,4/serial" open-dev ?dup if  to serial-ih  exit  then
222      " /usb@f,5/serial" open-dev ?dup if  to serial-ih  exit  then
223   [then]
224   true abort" can't open USB serial adapter"
225;
226
227: usb-close  ( -- )
228   serial-ih close-dev
229   0 to serial-ih
230;
231
232: usb-emit  ( key -- )
233   buf c! buf 1 " write" serial-ih $call-method  drop
234;
235
236: usb-read  ( -- adr len )
237   buf /buf " read" serial-ih $call-method      ( len )
238   dup -2 =  if  drop buf 0 exit  then          ( len )
239   buf swap                                     ( adr len )
240;
241
242: usb-break
243   " ftdi-break-on" serial-ih $call-method
244   1 ms
245   " ftdi-8n1" serial-ih $call-method
246;
247
248: use-usb
249   uart-console-on
250   ['] usb-open   to  serial-open
251   ['] usb-close  to  serial-close
252   ['] usb-emit   to  serial-emit
253   ['] usb-read   to  serial-read
254   ['] usb-break  to  serial-break
255;
256
257use-usb
258
259\ end of USB serial device implementation
260
261
262\ key bindings
263\ (match the screen(1) defaults)
264defer key-state  ( key -- )
265defer key-state-default  ( key -- )
266
267: reset-key-state  ['] key-state-default >data token@  to key-state  ;
268
269: key-state-exit  ( key -- )  serial-emit  ;  \ is not called
270
271: key-state-exit?  ( -- exit? )
272   ['] key-state >data token@  ['] key-state-exit  =
273;
274
275: key-state-c-a  ( key -- )  \ list of recognised c-a sequences
276   case
277      1 ( c-a )  of  1 serial-emit  reset-key-state   endof
278      2 ( c-b )  of  serial-break   reset-key-state   endof
279      [char] b   of  serial-break   reset-key-state   endof
280      [char] C   of  page           reset-key-state   endof
281      4 ( c-d )  of  ['] key-state-exit to key-state  endof
282      [char] k   of  ['] key-state-exit to key-state  endof
283      [char] K   of  ['] key-state-exit to key-state  endof
284      ( default )                   reset-key-state
285   endcase
286;
287
288: key-state-run  ( key -- )
289   dup 1 =  if  ['] key-state-c-a to key-state  drop exit  then  \ c-a
290   serial-emit ( )
291;
292
293' key-state-run to key-state-default
294
295\ end of key bindings
296
297
298\ main program
299
300: serial-help-0  ( -- )
301   green-letters
302   ." serial terminal:" cr
303   ."     use  c-a k  to exit," cr
304   ."     use  c-a c-b  to send break," cr
305   ."     use  c-a c-a  to send a c-a." cr
306   cancel cr
307;
308
309: serial-help-1  ( -- )
310   cr green-letters ." serial terminal: stopped." cancel cr
311;
312
313: outgoing  ( -- )  \ data leaving this host
314   key?  if  key  key-state  then
315;
316
317: incoming  ( -- )  \ data arriving at this host
318   serial-read  dup  if  >q  else  2drop  q>  then
319;
320
321: serial{
322   emit-q init-q  serial-open  reset-key-state  serial-help-0
323;
324
325: {serial}
326   begin  outgoing  incoming  key-state-exit?  until
327;
328
329: }serial
330   serial-close  serial-help-1
331;
332
333previous definitions  also serial-terminal
334
335: serial  serial{  {serial}  }serial  ;
336
337[ifdef] log-ih
338: serial-log  ( "filename" -- )
339   serial{
340   safe-parse-word
341   2dup ['] $delete  catch  if  2drop  then
342   $create-file to log-ih
343   log-ih add-output
344   {serial}
345   log-ih remove-output
346   log-ih close-dev
347   }serial
348;
349[then]
350
351: use-uart  use-uart  ;
352: use-usb   use-usb   ;
353
354previous
355
356\ LICENSE_BEGIN
357\ Copyright (c) 2013 FirmWorks
358\
359\ Permission is hereby granted, free of charge, to any person obtaining
360\ a copy of this software and associated documentation files (the
361\ "Software"), to deal in the Software without restriction, including
362\ without limitation the rights to use, copy, modify, merge, publish,
363\ distribute, sublicense, and/or sell copies of the Software, and to
364\ permit persons to whom the Software is furnished to do so, subject to
365\ the following conditions:
366\
367\ The above copyright notice and this permission notice shall be
368\ included in all copies or substantial portions of the Software.
369\
370\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
371\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
372\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
373\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
374\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
375\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
376\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
377\
378\ LICENSE_END
Note: See TracBrowser for help on using the repository browser.