// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // IASI2 interface // This library is use for the new IASI version 2 devices // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // HISTORY: // // REQUIRED: // #URL-lib "http://pin1.org/forthlib/flb/General/soft1.flb" // // CONSTANTS: &E0010000 constant U1DLL &E0010004 constant U1DLM &E001000C constant U1LCR 62 constant I-ACK // '>' // ----------------------------------------------------- // 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 ! // 1 stop 8 bits 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 : cr1 13 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 50 for key1? if drop key1 leave then 1 ms next ; // ----------------------------------------------------- // prints contents of uart1 buffer if any // i-buff-dot // ( --- ) : i-buff. begin i-in dup if emit -1 // dont quit loop then 0= until ; // ----------------------------------------------------- // clear buffer contents, does not use // i-in as this simply needs clearing // ( --- ) : i-cbuff begin key1? if key1 drop then key1? 0= until ; // ----------------------------------------------------- // simply sends 4 cr to device to establish baud rate // ( --- ) : i-autobaud 4 for cr1 50 ms next 100 ms 4 emit1 cr1 // set to non-inverted mode i-cbuff ; // ----------------------------------------------------- // gets a single byte output from device // gets a single byte followed by ack, returns // -1 if valid byte 0 if not : i-get ( --- [byte, t], f) i-in // get the byte i-in I-ACK = if -1 else drop 0 then ; // ----------------------------------------------------- // determins number of devices connected : i-ndev ( -- #devices ) 1 emit1 cr1 // send broadcast 780 ms // all device range 0 begin i-get if drop 1+ 1 else 0 then 0= until ; // ----------------------------------------------------- // Initialise, Initialises devices connected, and returns // number of devices connected : 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 : i-device { address -- t/f } 1 emit1 cr1 // broadcast begin i-get if address = if -1 escape then else 0 escape then again ; // ----------------------------------------------------- // expects I-ACK in input stream, returns true if there : i-ack? ( -- t/f) i-in I-ACK = ; // ----------------------------------------------------- // uses instead of cr1 to confirm command accepted // also gives device time to reply so commands are not missed : i-wait ( -- ) cr1 i-ack? 0= abort" No ack from device" ; // ----------------------------------------------------- // 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 cr1 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-SEND bt"hello" // must be a space following the D of send // ( --- ) : i-send (i-ipb) i-buff. // print result cr ; // ----------------------------------------------------- // Report on the connected devices : i-report i-connect cr ." Number of devices connected " u. 1 emit1 cr1 // send broadcast 780 ms // all device range cr ." device addresses " begin i-get if dup emit space [char] ( emit u. ." ), " -1 else 0 then 0= until ;