delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/03/19/10:02:28

From: David Allsopp <daa AT tqSPAMbase DOT demon DOT co DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: problems with bios.h function
Date: Fri, 19 Mar 1999 10:07:32 +0000
Organization: Tranquillity Software Ltd.
Message-ID: <onmGlFAkHi82EwG3@tqbase.demon.co.uk>
NNTP-Posting-Host: tqbase.demon.co.uk
X-NNTP-Posting-Host: tqbase.demon.co.uk:193.237.23.6
X-Trace: news.demon.co.uk 921838095 nnrp-08:11426 NO-IDENT tqbase.demon.co.uk:193.237.23.6
X-Complaints-To: abuse AT demon DOT net
MIME-Version: 1.0
X-Newsreader: Turnpike (32) Version 4.01 <g0Tf4xpDTD4exNTVgwOBdC6kr2>
Lines: 128
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

I am having problems with one of the functions in bios.h: the bioscom()
function that allows communication with the serial port.  The spec of
the main program is as follows:
        Arguments are name of output file and a single byte
        Write the byte out to COM1 (which is attached to a weighbridge)
        Read the reply on COM1; <30 bytes + CR/LF + 2 more characters
        Write the string (inc. the CR/LF) to the output file
        Time out after 5 seconds

This works, but only half the time.  That is, one time the program works
as stated, reading the response from the weighbridge.  The next time, it
times out, with a port status enquiry returning 0x6001.  The next time, it
works, and then not, and so on.  We've completely run out of ideas on this
one.

More useful information:
        The port initialisation always returns status 0x6011
        The program is compiled on W95 using "gcc -Wall", and deployed
        on an NT box. DJGPP version 2.81.
        Attaching a terminal emulation to the port works OK all the time.
        When the program times out, a break-out box on the line shows that
        the weighbridge has sent data.
        When the program works, it does so in under a second.

Queries:
        Does the bioscom() function really use interrupt 0x14, and should
        we check for clashes (there don't seem to be any)?
        Should the port be set up in any particular way under NT, e.g. "No
        flow control"?

Stripped-down version of the program follows.  I've removed all the
argument checking and logging.  I can, of course, mail the full version 
on request: it's only twice as long.

==================================================================
#include <stdio.h>
#include <bios.h>
#include <signal.h>
#include <unistd.h>

#define COM1 0

#define INIT_COMMAND  0 // initialize com port (DATA is the settings)
#define WRITE_COMMAND 1 // write byte to port
#define READ_COMMAND  2 // read byte from port (DATA is ignored)
#define STAT_COMMAND  3 // get port status

#define BIT15 16384

#define CR '\015'
#define LF '\012'

void
OnSignal()
{
        exit(1); // status enquiry here gives status 0x6001
}

int 
main(int argc, char * argv[])
{
        // DECLARATIONS
        FILE * OutputFile;
        int PortStatus;
        char PortData [50];
        char EnquiryByte;
        int i;

        if ((OutputFile = fopen(argv[1], "w")) == NULL) {
                fprintf(stderr, "%s: cannot open file %s\n", argv[0],
argv[1]);
                return 3;
        }
        EnquiryByte = argv[2][1];

        // INITIALISE PORT
        PortStatus = bioscom(INIT_COMMAND, 0xe3, COM1); //always 0x6011

        // WRITE ENQUIRY BYTE TO PORT
        PortStatus = bioscom(WRITE_COMMAND, EnquiryByte, COM1);

        // SET UP ALARM CALL: hard-wired 5 seconds
        signal(SIGALRM, &OnSignal);
        alarm(5);

        // READ FROM PORT
        i = 0;
        while (i < 49) {
                int DataRead = bioscom(READ_COMMAND, 0, COM1);
                if (DataRead & BIT15) { // bit 15: error...
                        usleep(10000);  // ...so sleep for 1/100 sec...
                        continue;       // ...then loop and try again
                } else if (DataRead & 0xff) {
                        PortData[i++] = (char)(DataRead & 0xff);
                        if (PortData[i-2] == CR &&  PortData[i-1] == LF) {
                                break;
                        }
                } else {
                        // null byte (??) do nothing
                }
        }
        PortData[i++] = (char)0; // ensure null-terminated

        // THROW AWAY TWO TRAILING CHARACTERS
        // programming elegance note: it would of course be better to
        // factor this loop out into a GetChar() function, used above and
        // here, but with just one repeat it isn't worth it
        i = 0;
        while (i < 2) {
                int DataRead = bioscom(READ_COMMAND, 0, COM1);
                if (DataRead & BIT15) { // bit 15: error...
                        usleep(10000);  // ...so sleep for 1/100 sec...
                        continue;       // ...then loop and try again
                } else if (DataRead & 0xff) {
                        // throw away trailing characters
                } else {
                        // null byte (??) do nothing
                }
        }

        // WRITE STRING OUT TO SPECIFIED FILE
        fputs(PortData, OutputFile);
        return 0;
}

-- 
David Allsopp                           Houston, this is Tranquillity Base.
Remove SPAM to email me                 The Eagle has landed.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019