Re: COM I/O
- Posted by Jacques Deschenes <desja at QUEBECTEL.COM> Jan 14, 1997
- 1579 views
--=====================_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==_--