delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/02/18/12:55:33

From: David Allsopp <daa AT tqSPAMbase DOT demon DOT co DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Comms on COM1
Date: Thu, 18 Feb 1999 16:13:58 +0000
Organization: Tranquillity Software Ltd.
Message-ID: <fmRbVAAGxDz2Ewpj@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 919354774 nnrp-04:12499 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: 172
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

I have a comms problem, if anyone is able to help...

The program attached below is meant to open COM1, send a wakeup character
to a weighbridge, read the weighbridge's response, and write it out to a
file.  The file name is passed as an argument, and the file is created if
necessary.  If there is any second argument, a log file is also created.
There is a timeout after 5 seconds.

The script is compiled with "gcc -o wbridge -Wall -s wbridge.c"

If COM1 is attached to a laptop running a terminal emulator, you can see
the character come out, and (subject to the timeout) successfully type
stuff back to the program.  This does, however, require that the RTS/CTS
pins (7 and 8) are jumpered together.

However, when the weighbridge is attached, it only gives back a response
one time in three or four; the rest of the time the program times out.
When it occurs, the response is immediate and of the correct format

So...

        Is there anything wrong with the program?  I admit it isn't the
        prettiest thing in the world, but KISS...

        Should the COM1 port settings in NT setup be made to specify anything
        in particular? We are currently using the default port settings.

        Should we force a particular flow-control strategy?  The possible
        settings are "none", "xon/xoff" and "hardware".

        Do we need to force COM1 to use IRQ14?  This is the IRQ mentioned
        in the documentation for "bios.h".

Er, that's it...  Thanks in advance for any help.

========================== PROGRAM FOLLOWS ==========================
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#define COM1 0
#define COM2 1
#define COM3 2
#define COM4 3

#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'

// GLOBAL DECLARATIONS: so that they can be used inside the signal handler
FILE * LogHandle = NULL;
struct time TimeNow;
struct date DateNow;
char LogMessage[100];

void
WriteLog(char * message)
{
        if (LogHandle != NULL) {
                fprintf(LogHandle, message);
        }
}

void
OnSignal()
{
        gettime(&TimeNow);
        sprintf(LogMessage, "Run timed out at %d:%02d.%02d\n",
                TimeNow.ti_hour, TimeNow.ti_min, TimeNow.ti_sec
        );
        WriteLog(LogMessage);
        exit(1);
}

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

        // ARGUMENT CHECKING AND INITIALISATIONS
        if (argc == 1) {
                fprintf(stderr, "%s: no filename specified!\n", argv[0]);
                return 2;
        }
        if ((OutputFile = fopen(argv[1], "w")) == NULL) {
                fprintf(stderr, "%s: cannot open file %s\n", argv[0], argv[1]);
                return 3;
        }
        if (argc > 2) {
                char LogFileName[200];
                strcat(strcpy(LogFileName, argv[1]), ".LOG");
                if ((LogHandle = fopen(LogFileName,"w")) == NULL)
                        fprintf(stderr,
                                "%s: warning: cannot open log file %s\n",
                                argv[0], argv[1]
                        );
        }
        getdate(&DateNow);
        gettime(&TimeNow);
        mprintf(LogMessage, "Run started at %d:%02d.%02d on %02d/%02d/%d\n",
                TimeNow.ti_hour, TimeNow.ti_min, TimeNow.ti_sec,
                DateNow.da_day, DateNow.da_mon, DateNow.da_year
        );
        WriteLog(LogMessage);

        // INITIALISE PORT
        PortStatus = bioscom(INIT_COMMAND, 0xe3, COM1);
        sprintf(LogMessage, "Port initialised: return value %#0x\n",PortStatus);
        WriteLog(LogMessage);

        // WRITE ENQUIRY BYTE TO PORT
        PortStatus = bioscom(WRITE_COMMAND, 0x05, COM1);
        sprintf(LogMessage,"Port byte written: return value %#0x\n",PortStatus);
        WriteLog(LogMessage);

        // 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
                        continue;       // ignore error and busy loop
                } else if (DataRead & 0xff) {
                        PortData[i++] = (char)(DataRead & 0xff);
                        sprintf(LogMessage,"\tVALID READ %c\n",PortData[(i-1)]);
                        WriteLog(LogMessage);
                        if (PortData[i-2] == CR
                        &&  PortData[i-1] == LF) {
                                WriteLog("\tCR/LF detected: stop\n");
                                break;
                        }
                } else {
                        WriteLog("\tNULL BYTE\n");
                }
        }
        PortData[i++] = (char)0; // ensure null-terminated

        // WRITE STRING OUT TO SPECIFIED FILE
        fputs(PortData, OutputFile);
        fflush(OutputFile);
        fsync(fileno(OutputFile));

        // FINISH
        gettime(&TimeNow);
        sprintf(LogMessage, "Run ended at %d:%02d.%02d\n",
                TimeNow.ti_hour, TimeNow.ti_min, TimeNow.ti_sec
        );
        WriteLog(LogMessage);
        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