Re: COM I/O
--=====================_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==_--
|
Not Categorized, Please Help
|
|