XO-1.75 OpenFirmware serial terminal

James Cameron quozl at laptop.org
Tue Mar 27 05:52:39 EDT 2012


This is a serial terminal implementation for an XO-1.75 using Open
Firmware.

Allows a laptop to be a host for a target laptop through a crossover
cable.

Use cases:

- field diagnosis when a computer with a serial port is not available,
  but adequate quantities of XO-1.75 are available,

- diagnosis of EC serial port output, using one laptop,

- logging of kernel serial console output using Open Firmware,

- serial terminal for other 3.3V serial devices, such as routers, single
  board computers, microcontrollers,

- serial terminal for an Arduino (with a suitable level converter).

Caution: the program turns off the Open Firmware serial console when it
starts, to avoid unpleasant interaction between the Open Firmware ok
prompt and any connected device.  Connecting the cable before the
program is started may result in each laptop screaming at the other
repeatedly.

Credit to the existing Open Firmware serial port FIFO queue
implementation.  Couldn't have made it stable without it.

-- 
James Cameron
http://quozl.linux.org.au/
-------------- next part --------------
\ serial.fth

\ usage:
\    ok fl u:\serial.fth
\    ok serial
\    connect cable last

\ cable to cable crossover pin map
\    gnd to gnd                 (orange to orange)
\    tx to rx                   (green to red)
\    rx to tx                   (red to green)
\    3.3v not connected         (black)

\ queue implementation copied from dev/16550pkg/16550.fth
d# 32768 constant /q

struct
   /n field >head
   /n field >tail
   /q field >qdata
constant /qstruct

/qstruct instance buffer: read-q

: init-q  ( q -- )  0 over >head !  0 swap >tail !   ;
: inc-q-ptr  ( pointer-addr -- )
   dup @  ca1+  dup /q  =  if  drop 0  then  swap !
;

: enque  ( new-entry q -- )
   >r
   r@ >tail @  r@ >head @  2dup >  if  - /q  then  1-     ( entry tail head )
   <>  if  r@ >qdata  r@ >tail @ ca+ c!  r@ >tail inc-q-ptr  else  drop  then
   r> drop
;

: deque?  ( q -- false | entry true )
   >r
   r@ >head @  r@ >tail @  <>  if
      r@ >qdata  r@ >head @  ca+ c@  r@ >head inc-q-ptr  true
   else
      false
   then
   r> drop
;

\ end of queue implementation

\ serial interrupt handler for received data
: si ( -- )  ukey read-q enque  ;

\ interrupt enable register UART_IER, table 1993, page 1547
: ier@  ( -- b )  h# 1 uart@  ;
: ier!  ( b -- )  h# 1 uart!  ;

\ receiver data available interrupt enable
: ravie-on   ( -- )  ier@ 1 or ier!  ;
: ravie-off  ( -- )  ier@ 1 invert and ier!  ;

\ modem control register UART_MCR, table 1999, page 1555
: mcr@  ( -- b )  h# 4 uart@  ;
: mcr!  ( b -- )  h# 4 uart!  ;

\ OUT2 signal control, enable UART interrupts
: out2-on   ( -- )  mcr@ 8 or mcr!  ;
: out2-off  ( -- )  mcr@ 8 invert and mcr!  ;

\ enable serial interrupt
: esi
   ['] si d# 24 interrupt-handler!
   d# 24 enable-interrupt
   ravie-on
   out2-on
;

\ disable serial interrupt
: dsi
   out2-off
   ravie-off
   d# 24 disable-interrupt
;

\ stop using the serial port as console
\ (necessary to avoid noise from interconnected hosts)
: serial-off
   fallback-out-ih remove-output
   fallback-in-ih remove-input
;

\ resume using the serial port as console
: serial-on
   fallback-out-ih add-output
   fallback-in-ih add-input
;

0 value serial-state
: serial
   serial-off
   read-q init-q
   esi
   1 to serial-state
   ." serial terminal ready, use c-a to exit." cr
   begin
      key?  if
         key
         dup 1 =  if  0 to serial-state  then  \ c-a
         uemit
      then
      begin
         read-q deque?
      while
         emit
      repeat
      serial-state 0=
   until
   dsi
   cr ." serial terminal stopped." cr
;


More information about the Devel mailing list