To use this file copy and paste this:    // #URL-lib "http://pin1.org/forthlib/flb/IASI2/IASI2-b.flb"   into BV Terminal 3 or here to download.

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // IASI2 interface // This library is use for the new IASI version 2 devices // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

// HISTORY: // Dec 2008 Version b of this libraty stored the o/p from the device // or devices to a buffer, i-buffer

// CONSTANTS: &E0010000 constant U1DLL &E0010004 constant U1DLM &E001000C constant U1LCR 62 constant I-ACK // '>' 20 constant BMAX BMAX vspace$ i-buffer // o/p goes into here


Full Contents of File

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// IASI2 interface
// This library is use for the new IASI version 2 devices
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

// HISTORY:
// Dec 2008 Version b of this libraty stored the o/p from the device
// or devices to a buffer, i-buffer

// REQUIRED:
// #URL-lib "http://pin1.org/forthlib/flb/General/soft1.flb"
// #URL-lib "http://pin1.org/forthlib/flb/General/strings.flb"


// CONSTANTS:
&E0010000  constant  U1DLL
&E0010004  constant  U1DLM
&E001000C  constant  U1LCR
62  constant  I-ACK  // '>'
20  constant  BMAX
BMAX  vspace$  i-buffer  // o/p goes into here

// -----------------------------------------------------
// Communication set up for UART1
// set baud rate with 1 stop and 8 data
// no parity
// Baud rates for IASO2 devices are seleceted from
// 9600, 14400, 19200 and 38400
: baud1  { rate --- }
        rate  16  *  10  / // multiply rate by 1.6
        PCLK  swap  / // divide by PCLK
        5  +  10  / // round up and div by 10
        256  u/mod
        &83  U1LCR  !  // 2 stop 8 bits (&87 is 2 stop bit)
        U1DLM  !          // high divisor
        U1DLL  !          // low devisor
        &3  U1LCR  !    // DLAB=0, 1 stop 8 data
;       

// -----------------------------------------------------
// returns baud rate for device 1
// ( --- rate )
: baud1@
        &83  U1LCR  !  // access to U1DLM,LL
        U1DLM  @          // high divisor
        256  *
        U1DLL  @          // low devisor
        +
        &3  U1LCR  !    // DLAB=0, 1 stop 8 data
        // now calculate from these, baud rate
        16  *  pclk  swap  u/mod swap drop
;       

// -----------------------------------------------------
// used for terminating a command, typical use is
// after sending command, example i.' BT"fred"' cr1
: cr113  emit1  ;             

// -----------------------------------------------------
// Send string to IASI device using UART1
// addr is the address of a 0 terminated string
// max string length 255 chars
: stype1 { addr --- }
        addr  255  +          // end
        addr                      // start
        do
                i  c@  0= 
                if 
                        leave
                else
                        i  c@  emit1         
                then
        next       
; 

// -----------------------------------------------------
// This is the same as u. but uses emit1 and
// stype1 to print to UART1
// prints n as ASCII
// ( n --- )
: iu.<#  #s  #>  stype1  ;               

// -----------------------------------------------------
// gets a key form UART1 and will time out
// if no key is available. This saves complex
// code using key1? and prevents system
// crashing, set for time out of 50ms.
// It also has another purpose in that it will wait for a
// device to respond to a command
// meant for ASCII, return 0 if not valid
// ( --- r-val )
: i-in
        0 
        50000
        for
                key1?
                if
                        drop
                        key1
                        leave
                then     
        next                                 
;
// -----------------------------------------------------
// expects I-ACK in input stream, returns true if there
: i-ack? ( -- t/f)
        i-in  I-ACK  =
;       

// -----------------------------------------------------
// waits for device to respond and fills i-buffer
// returns when ACK is recieved or times out
: i-send ( -- [i-buffer] )
int# bcount  0
        0  i-buffer  c!  // empty buffer
        begin
                i-in  ?dup  0  <>
        while
                dup  // for I-ACK test
                i-buffer  bcount  +  c!  // store
                1  +>  bcount
                bcount  BMAX  >  if  ."  buffer  full"  abort  then
                I-ACK  =  if
                        0  i-buffer  bcount  1  +  +  c!  // terminate
                        escape 
                then  // finished when I_ACK recieved
        repeat
        0  i-buffer  bcount  1  +  +  c!  // terminate
;               
// -----------------------------------------------------
// prints contents of i-buffer if any
// contents are terminated by 0
// ( --- )
: i-buff.
        i-buffer  stype     
;

// -----------------------------------------------------
// clear buffer contents.
// ( --- )
: i-cbuff
        BMAX  for  0  i  i-buffer  +  c!  next
        // and hw buffer
        key1?
        if
                begin
                        key1  drop
                        key1?  0= 
                until
        then               
;

// -----------------------------------------------------
// sends CR to establish the baud rate and then inverts
// all connected devices
// ( --- )
: i-autobaud
        3  for 
                cr1  10  ms 
        next
        10  ms
        4  emit1  cr1      // set to non-inverted mode
        100  ms            // device needs time to set
        i-cbuff       
;

// -----------------------------------------------------
// determins number of devices connected
// use i-connect for initialisation as this also establishes
// the Baud rate
: i-ndev ( -- #devices )
int# devices  0
        i-cbuff            // clear buffer
        1  emit1  cr1    // send broadcast
        780  ms            // all device range
        i-send            // now fill buffer
        -1                      // buffer increment
        begin
                1+  dup  i-buffer  +  c@  ?dup  0  <>
        while
                I-ACK  =  if  1  +>  devices  then  // count ack's
        repeat     
        drop  // buffer count
        devices
;

// -----------------------------------------------------
// Initialise, Initialises devices connected, and returns
// number of devices connected. i-buffer will contain the
// string with the devices in
: i-connect ( -- devices)
        i-autobaud
        i-ndev
;
                   
// -----------------------------------------------------
// determins if a particular device is connected
// returns -1 if so
// 97 i-device will return 1 if 'a' is connected
// 0 otherwise
: i-device { address -- 1|0 }
int# found  0
        i-ndev            // fill buffer
        if
                -1                      // buffer increment
                begin
                        1+  dup  i-buffer  +  c@  ?dup  0  <>
                while
                        address  =  if  1  +>  found  then  // count ack's
                repeat     
                drop  // buffer count
                found    // leave result
        else
                ."  No  devices  connected"
                0      // leave 0
        then                       
;

// -----------------------------------------------------
// Command interface
// -----------------------------------------------------

// -----------------------------------------------------
// Reset all devices, establish baud rate and return
// number of devices connected
: i-resetall ( -- devices)
        3  emit1  cr1      // reset
        i-connect                // does rest
;       

// -----------------------------------------------------
// sets address -- only one device should be connected
// otherwise this will not work
//
: i-setaddress { old new -- t/f }
        i-cbuff
        old  emit1  [char]  U  emit1  cr1    // unlock
        // U command does not return I-ACK
        old  emit1  [char]  A  emit1  new  emit1
        i-ack?
;       

// -----------------------------------------------------
// write to EEPROM as text, the command example is
// aB10 'hello'
// need to supply an address where the text is so this
// would work:
// 97 10 s" 'hello'" i-commandB
: i-commandB { adr eeadr text -- t/f}
        i-cbuff
        adr  emit1  [char]  B  emit1 
        eeadr  iu.    // send as ASCII coded number
        text  stype1  cr1
        i-ack?
;

// -----------------------------------------------------
// turn off I-ACK (not a good idea for these commands)
: i-commandC ( addr -- t/f)
        i-cbuff
        emit1  [char]  C  emit1  cr1
        i-ack?
;
 
// -----------------------------------------------------
// delay device, note ACK does not come back until
// after delay so will wait here until ack is returned
: i-commandD ( addr -- t/f )
        emit1  [char]  D  emit1 
        iu.  cr1
        begin
            i-ack?
        -1  =  until
;                           

// -----------------------------------------------------
// turn off error reporting
: i-commandE ( addr -- t/f)
        i-cbuff
        emit1  [char]  E  emit1  cr1
        i-ack?
;

// -----------------------------------------------------
// factory reset no re-initialisation is required after
// this command
// the command is aFYeS
: i-commandF ( addr -- t/f)
        i-cbuff
        emit1  [char]  F  emit1
        [char]  Y  emit1  [char]  e  emit1  [char]  S  emit1  cr1 
        i-ack?
;

// -----------------------------------------------------
// read from eeprom, the device command is
// aG10 3 where 10 is the start address and 3 is the number
// of bytes to read. This will put the bytes in the i/p
// buffer and can be read by i-in
: i-commandG { adr start bytes -- }
        adr  emit1  [char]  G  emit1
        start  iu.  bytes  iu.
;
       

// -----------------------------------------------------
// used for interfacing with device, see i-send
// and i-get, this word is not used on its own
// it gets and sends to UART1 the text in the TIB
// which is the text following the word
: (i-ipb)     
        i-cbuff          // clear ipb
        13  word          // get i/p from stream
        stype1  // send word to uart1
        cr1                  // get IASI to process it
;

// -----------------------------------------------------
// utility for sending and receiving from UART2
// sends text following word, must all be on 1 line
// use: I-SENDIT bt"hello"
// must be a space following the D of send
// ( --- )
: i-sendit
        (i-ipb)
        i-buff.          // print result
        cr
;

// -----------------------------------------------------
// Report on the connected devices
: i-report
        i-connect
        cr  ."  Number  of  devices  connected  "  u.
        i-buff.
;           

// -----------------------------------------------------
// Utilities
// -----------------------------------------------------
// -----------------------------------------------------
// gets a decimal number stored in i-buffer and terminated
// by I-ACK, e.g. 255> will return 255
// returns number and -1 if there is a number else returns
// just 0
: i-gn ( -- num, -1 | 0 )
int bc  num  mult
        0  =>  num
        1  =>  mult
        i-buffer  0  I-ACK  instr$      // find ack
        dup  =>  bc
        0  <>  // okay
        if
                begin
                        -1  +>  bc                // work backwards
                        bc  i-buffer  +  c@  48  -  // ascii > decimal
                        mult  *  +>  num
                        mult  10  *  =>  mult
                        bc  0=
                until
                num  -1
        else
                0     
        then
;                 

: xi-connect  ;