#INCLUDE "external_srv_ffi_pragmas.occ"
#INCLUDE "out.occ"

VAL INT MILLIS          IS 1:
VAL INT SECONDS         IS (1000 * MILLIS):

VAL INT FLASH.BUFFER      IS #00100000:
VAL INT FLASH.BUFFER.SIZE IS #DECAF:

PROC delay.millis(VAL INT milli)
  TIMER tim:
  INT t:
  SEQ
    tim ? t
    tim ? AFTER t PLUS (milli * MILLIS)
:

PROC delay.seconds (VAL INT sec)
  delay.millis(sec * SECONDS)
:

-- This is the wrapper for outputting bytes
-- to the console. It replaces a notional
-- "screen?" channel end.
PROC print.bytes(CHAN BYTE ch?)
  BYTE c:
  WHILE TRUE
    SEQ
      ch ? c
      ffi.print.char(c)
:

PROC poll.uart (CHAN BYTE ch!)
  INT ready:
  BYTE char:
  WHILE TRUE
    SEQ
      ffi.uart0.char(ready, char)
      WHILE (ready = 0)
        SEQ
          RESCHEDULE()
          ffi.uart0.char(ready, char)
      ch ! char
:

PROC console.loop(CHAN BYTE c.in?, c.out!)
  INITIAL INT tbc.length IS 0:
  PLACED [FLASH.BUFFER.SIZE]BYTE flash.buffer FLASH.BUFFER:
  BYTE c:
  WHILE TRUE
    SEQ
      c.in ? c
      IF
        -- CAMERA ---------------------
        c = 'I'
          ffi.get.frame()
        c = 'a'
          ffi.camera.reset(160)
        c = 'b'
          ffi.camera.reset(320)
        c = 'c'
          ffi.camera.reset(640)
        -- MOTORS ---------------------
        c = 'M'
          ffi.motor.command()
        c = '+'
          ffi.motor.increase.base.speed()
        c = '-'
          ffi.motor.decrease.base.speed()
        c = '.'
          ffi.motor.action(c)
        (c > 47) AND (c < 58)
          ffi.motor.action(c)
        -- LASERS ---------------------
        c = 'l'
          ffi.lasers.on()
        c = 'L'
          ffi.lasers.off()
        -- MESSAGES -------------------
        c = 't'
          ffi.serial.out.time()
        c = 'V'
          ffi.serial.out.version() 
        -- UPLOAD ---------------------
        c ='X'
          ffi.xmodem.receive(tbc.length)
        c = 'D'
          ffi.serial.out.flashbuffer()
        (c = 'Q') AND (tbc.length > 0)
          start.user.program(flash.buffer, tbc.length)
        (c = 'W') AND (tbc.length > 0)
          end.user.program(flash.buffer, tbc.length)
        TRUE
          SKIP
:


PROC main ()
  CHAN BYTE c.in, c.out:
  PAR
    poll.uart(c.in!)
    console.loop(c.in?, c.out!)
    print.bytes(c.out?)
:
