Re: COM I/O

new topic     » goto parent     » topic index » view thread      » older message » newer message

--=====================_853300178==_

>Jacques, perhaps you could help with a further explanation of your
>inputw/outputw routines?
>
>Basically, I need to write a BBS Door program.
>

Hi,

   ports.e is not a library for com port usage,  it's meant to write to and
read from hardware I/O ports.   By this I mean it's for basic input/output
of bytes and words to any piece of hardware.  It's a wrap up for assembler
instructions IN and OUT.

You certainly can use it to write (or read) to com ports hardware.  But it's not
a simple matter. As I said previously, to do serious   COM port
communication you need
to HOOK the COM port interrupt with an interrupt service routine (written in
assembler) and I don't know how to do that from euphoria.  I did some try
without any success yet.

  A few month ago I did some test communication with modem, without hooking
the hardware interrupt. Not to miss any character the program have to
constantly poll the
com port in a loop. It's very restrictive.

  Anyway I send you the test code I did write at that time.


--=====================_853300178==_

-- access to serial ports by interrupt #14 services
-- by Jacques Deschenes

without warning

include machine.e
include ports.e
include bitwise.e

with trace
-- trace(1)
------------------------------------------------------------------
-- set parameters for specified com port
-- baud rate limited to 9600pbs
-- return 1 if secceed else 0
-- In case of error InitError containt error number

global integer InitError  -- set to error number or 0
global word Status   -- hold status word reported by last int #14 call.

constant bauds={110,150,300,600,1200,2400,4800,9600}

global constant
-- parity values
    cNONE =0, cODD=1, cEVEN=2,
--  errors codes
    cERR_INVALID_BAUD = 1,
    cERR_PARITY = 2,
    cERR_TIME_OUT = 3,
    cERR_FRAME = 4

constant -- status  bit mask
   mDATA_READY = power(2,8),  -- data ready bit
   mERASED = power(2,9),      -- data erased bit
   mPARITY = power(2,10),     -- parity error bit
   mFRAME =  power(2,11),     -- frame error bit
   mINTER =  power(2,12),     -- interrupt detected
   mTHR_EMPTY = power(2,13),  -- transmission hold register empty
   mTSR_EMPTY = power(2,14),  -- transmission shift register empty
   mTIME_OUT = power(2,15)    -- time out error

-- initCom
-- input AH = 0  DX = com_number - 1
-- return
--        AH serial interface status
--  bit 0 : data ready
--  bit 1 : data erased
--  bit 2 : parity error
--  bit 3 : framing error
--  bit 4 : interrupt detected
--  bit 5 : transmission hold register empty
--  bit 6 : transmission shift register empty
--  bit 7 : time out error (no answer from peripheral)
--        AL modem status (if there is a modem connected)
--  bit 0 :  (Delta) modem ready to transmit
--  bit 1 :  (delta) modem active
--  bit 2 :  (delta) phone ringing
--  bit 3 :  (delta) connected to other modem
--  bit 4 :  ready to transmit
--  bit 5 :  modem active
--  bit 6 :  phone ringing
--  bit 7 :  connected to othe modem

global function InitCom(integer ComNo, -- com port number (1,2,3,4)
                        integer BPS, -- bits per second, maximum 9600bps
                        integer WordLen, -- word length 7,8 bits
                        integer Stop, -- number of stop bits 1 or 2
                        integer Parity, --  none, even, odd
                        )
sequence r
integer bps, wl, stop, par
   bps = find(BPS,bauds)
   if not bps then
      InitError = cERR_INVALID_BAUD -- invalid baud rate
      return 0
   end if
   bps = (bps - 1)*32
   if WordLen = 7  then
     wl = 2
   else
     wl = 3
   end if
   if Stop = 1 then
     stop = 0
   else
    stop = 4
   end if
   par = Parity*8

   r = repeat(0,10)
   r[REG_AX] = bps + wl + stop + par
   r[REG_DX] = ComNo - 1
   r = dos_interrupt(#14,r)
   Status = r[REG_AX]
   if Status >= mTIME_OUT then
      InitError = cERR_TIME_OUT
      return 0
   else
      InitError = 0
      return 1
   end if
end function -- InitCom()

----------------------------------------------------------------------------
-- GetComStatus
global function GetComStatus(integer ComNo)
-- return status word
sequence r
    r = repeat(0,10)
    r[REG_AX] = #300
    r[REG_DX] = ComNo - 1
    r = dos_interrupt(#14,r)
    Status = r[REG_AX]
    return Status
end function -- GetComStatus()
----------------------------------------------------------------------------

procedure WriteC(integer ComNo, integer Char)
-- write a character to serial port.
sequence r
integer CurrentStatus
  CurrentStatus = GetComStatus(ComNo)
  while AND(CurrentStatus,mTSR_EMPTY)=0 do  -- wait until transmit shift
    CurrentStatus = GetComStatus(ComNo)     -- register is empty.
  end while
  if CurrentStatus < mTIME_OUT and AND(CurrentStatus,#6000)=#6000 then
    r = repeat(0,10)
    r[REG_DX] = ComNo - 1
    r[REG_AX] = #100 + Char
    r = dos_interrupt(#14,r)
    Status = r[REG_AX]
  end if
end procedure --WriteC()
----------------------------------------------------------------------------
function ReadC(integer ComNo)
-- read caracter from given Com port.
-- If no char available return -1
-- Set global variable Status
sequence r
integer CurrentStatus
  CurrentStatus = GetComStatus(ComNo)
  if CurrentStatus < mTIME_OUT and
     AND(CurrentStatus,mDATA_READY)=mDATA_READY then
    r = repeat(0,10)
    r[REG_DX] = ComNo - 1
    r[REG_AX] = #200
    r = dos_interrupt(#14,r)
    Status = r[REG_AX]
    if AND(Status,mTIME_OUT) = 0 then
        return remainder(Status,256)
    else
        return -1
    end if
    else
        return -1
  end if
end function -- ReadC()
----------------------------------------------------------------------------
function ReadStr(integer com)
sequence Str integer c  atom start integer TimeOut
    Str = {}
    c = ReadC(com)
    start = time()
    TimeOut = 0
    while c != 13 and not TimeOut do
        if c != -1 then
            Str = Str & c
        end if
        c = ReadC(com)
        TimeOut = time() - start > 1  -- 1 second time out
    end while
    if TimeOut then
        return Str
    end if
    c = ReadC(com)
    while c != 10 do
        c = ReadC(com) -- modem send cr&lf at end of each line
    end while
    return Str
end function -- ReadStr()
----------------------------------------------------------------------------

procedure WriteStr(integer com, sequence Str)
    for i = 1 to length(Str) do
        WriteC(com, Str[i])
    end for
end procedure -- WriteStr()

----------------------------------------------------------------------------

constant com = 3  -- set it to your modem com port

constant cmdReset = "ATZ\r"
constant cmd = "AT$\r"  -- command sent to the modem
constant cTIME_OUT = 1
integer c,key
atom start
sequence InStr
  clear_screen()
   puts(1,"****** querying modem demo **********\n")
  if not InitCom(com,9600,8,1,cNONE) then
    puts(1,"Fail to initialise com port.\n")
    abort(1)
  end if
  puts(1,"Reset modem with \"ATZ\" command.\n")
  WriteStr(com,cmdReset)
  c = ReadC(com)
  start = time()
  while c != 'A' do
    if time() - start > cTIME_OUT then
        exit
    end if
    c = ReadC(com)
    -- wait modem answer
  end while
  InStr = ReadStr(com) -- modem should return "OK"
  puts(1,InStr)
  puts(1,"Sending AT$ command to modem.\n")
  WriteStr(com,cmd)
  puts(1,"Waiting for modem answer.\n")
  start = time()
  while ReadC(com) != 'A' do
    if time() - start > cTIME_OUT then
        exit
    end if
    -- wait modem answer
  end while
  if not time() - start > cTIME_OUT then
    puts(1,"Modem answered.\n")
  else
    puts(1,"No modem answer.\n")
  end if
  InStr = {}
  c = ReadC(com)
  key = get_key()
  while get_key() != 27 do
    if  key > -1 and key != 27 then
        puts(1,key)
        WriteC(com,key)
    end if
    if c > -1 then
      InStr = InStr&c
    end if
    if c = 13 then
      c = ReadC(com)
      puts(1,InStr&c)
      if match("OK",InStr) then  -- "OK"  means end of modem answer.
         exit
      end if
      InStr={}
    end if
    c = ReadC(com)
    key = get_key()
  end while



--=====================_853300178==_

Jacques Deschenes
Baie-Comeau, Quebec
Canada
desja at quebectel.com

--=====================_853300178==_--

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu