Program listing
This contains the logging program, complete with
comments that describe its operation. These comments are easy to spot as they
are in bold text.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <dir.h>
#include <alloc.h>
#include <conio.h>
#include <time.h>
#define
TRUE 0x01
#define
FALSE 0x00
#define
DISPLAY 0x00
#define
DATALOG 0x01
#define
FILECOPY 0x02
/*
* VERSION numbers....
*/
#define
MAJOR 6 #define MINOR 1
/*
* I/O addresses
*/
#define PORT1 0x3F8 /* COM1 port address */
#define PORT2 0x2F8 /* COM2 port address */
#define PORT3 0x3E8 /* COM3 port address */
#define PORT4 0x2E8
/* COM4 port address */
#define LPT1 0x378 /* LPT1 port address */
#define LPT2 0x268 /* LPT2 port address */
/*
* Now
define the required BAUD rate
* 38400=0x03 115200=0x01 57600=0x02 19200=0x06
* 9600=0x0C 4800=0x18 2400=0x30
*/
#define BAUD 0x06 /* 19200 baud rate */
/*
* Data
logging utility
* Usage:
TCLOG
*
* Compile
with PACC -R or “_getargs() wildcard expansion”
* if you
want it to handle wildcards, e.g. CHK *.EXE
*/
/*
* This
version reprograms the system TICK (18th sec) and daisy chains
* onto the
0x1c interrupt where it changes the status of the variable
* Waitflag
instead of using the int 21 routine which seems to be a little
* BIOS
unfriendly!
* When
Waitflag changes, the sampling routine resets and runs again.
* In this way
the sampling is synchronised to the interrupt rate e.g. 33 Hz
*/
void set_rate(int Hz); /* Programs the tick timer
to support Hz sample rate */
void setup_int(); /*
Sets up out vector 1C interrupt routine
*/
void restore(); /*
Restores the orig vector 1C routine */
void create_header();
void interrupt timer_tick(); /* Changes the value
of waitflag from 0 to 128 */
void interrupt (far *old_1C_vect)(); /* Stores the old vector handler */
void tc_display(int tc); /* Displays the TC level */
/*
* Let’s
declare the global data...
*/
unsigned int h,i,j,k; /* loop counters */
unsigned int byte_count; /* Counts six bytes - goes 0 to 6 */
unsigned int time_out; /* flag to indicate time out problem */
unsigned int get_com; /* bioscom status */
unsigned char byte; /* bioscom parameter */
unsigned char lpt; /* LPT data */
unsigned char c[512]; /* character read from file */
unsigned char fn[20]; /* string for target filename */
unsigned int buf[7]; /* buffer for incoming data */
FILE * infile; /* input file handle */
FILE * outfile; /* output file handle */
unsigned char log[256]; /* Buffer for incoming serial data */
unsigned int waitflag; /* stores the flag for timer tick status */
main()
{
/*
* The main
loop may look a little cumbersome in that apart from setup and
* restore
and the interrupt routine, it does not use any subroutines.
* The
reason is that timing is quite tight on a slow machine and the
* potential
overhead of passing large amounts of data can make a difference
* at high
data rates.
*/
/*
* Let’s
initialise the data
*/
time_out = 0;
waitflag = 0; j =0; k =0;
/*
* Clear the
two spare data channels. These are stored but not used
* currently.
They can be filled in by reading external data such as
* throttle
and brake position.
*/
log[6] = 0; log[7] =0;
/*
* Set up
the COM port for 19.200 kbaud, 8B, No P, 1 STOP, FIFO on
*/
outportb(PORT1 + 1, 0x00); /* Turn off COM port interrupts */
outportb(PORT1 + 3, 0x80); outportb(PORT1 + 0,
BAUD); outportb(PORT1 + 1, 0x00); outportb(PORT1 + 3, 0x03); outportb(PORT1 +
2, 0xC7); outportb(PORT1 + 4, 0x0B);
/*
* Set up
the LPT control port to enable the switches...
bits 3,1 and 0 are used to generate active high
signals for the status port inputs.
Bit 7 6 5 4 3
2 1 0
Data 1 1 0 0 1
0 1 1 0xCB
*/
outportb(LPT1 + 2, 0xCB); /* Set up the control port */
/*
* Set up
the interval timer params.......
* This is
setup to generate a .033 second timing rate.
* This is
compatible with the data log software.
* ( c[07] =
0x3D; Set up internal timing for 30 Hz)
*/
set_rate(30); /* 30 Hz for data logging */
setup_int();
printf(“Setup complete. ch = %x\n”,check_port());
/*
* Print the
intro so we know the version and what it does...
*/
printf(“TCLOG version %d.%d FIFOs enabled 19.2
kbps\n”,MAJOR,MINOR); printf(“This collates data from the traction
control.\n”);
do /* Start
of main control loop */
{
/* Look at external controls */
/* If logging set then go into log loop */ /* If
not go into display loop */
/* Currently we go into log loop */
if (inportb(LPT1+1) < 0x80)
{ /* we are not data logging just displaying the tc
values */ printf(“Going into display mode...\n”);
FIFO Clear\n”);
FIFO Clear\n”);
/* Clear the serial port FIFO */ printf(“Clearing
serial port FIFO: “); while (inportb(PORT1 + 5) & 1)
{
log[10] = inportb(PORT1); printf(“=X”);
}
printf(“
printf(“ A MODE FL
FR RL RR RPM TC Samples\n”);
j = 0; /*
Check the
while (inportb(LPT1+1) < 0x80 & bioskey(1)
== 0)
switch value and the keyboard */
{
/* First send out the M to the data logger to get
it */
/* to send the next 6 bytes of data */
outportb(PORT1,0x4D);
/* Now lets get the data in */
byte_count = 0; /* clear the byte counter */
do
{get_com = inportb(PORT1 + 5); get_com =
inportb(PORT1 + 5);
if (get_com & 1)
{
log[byte_count++] = inportb(PORT1);
}
} while (waitflag != 128 & byte_count != 6);
/* Now we have six data samples, check if we timed
out... */ j++;
if (byte_count == 6)
{ /* Display the traction control status */
tc_display(log[5]);
/* All done */
}
else tc_display(0); /* RESET the TC status */
/* all done so wait for timer to expire... */
printf(“Display mode: %x %x %x %x %x %x %d\r”,
log[0],log[1],log[2],log[3],log[4],log[5],j); for(;waitflag != 128;);
waitflag = 0; /* Now clear the wait flag to repeat
*/ } /* end of data display WHILE loop */
fcloseall();
/* restore(); */ /* now performed on program exit
*/ printf(“\nEnd of data display routine\n”);
} /* end of IF data display = TRUE loop */ else
{/*
* WE ARE
DATA LOGGING!
*/
/* Set up the data log file */ create_header();
j =0; time_out = 0;
/* Clear the serial port FIFO */ printf(“Clearing
serial port FIFO: “); while (inportb(PORT1 + 5) & 1)
{
log[10] = inportb(PORT1); printf(“=X”);
}
printf(“F")
/* Now
synchronise with the clock */ printf(“Synchronising\n”);
printf(“A MODE Data logging starting \a\a\a\n”);
printf(“FL FR RL RR RPM TC OK FAIL\n”); for(;waitflag != 128;);
waitflag = 0;
while(inportb(LPT1+1) > 0x80 & bioskey(1) ==
0)
/* this would test the switch */
{
/* First send out the M to the data logger to get
it */
/* to send the next 6 bytes of data */
outportb(PORT1,0x4D);
/* Now lets get the data in */
byte_count = 0; /* clear the byte counter */
do
{ get_com = inportb(PORT1 + 5);
if (get_com & 1)
{ log[byte_count++] = inportb(PORT1);
}
} while (waitflag != 128 & byte_count != 6);
/* Now we have six data samples, check if we timed
out... */ if (byte_count == 6)
{ /* Success! */ j++;
/* Reorg the data correctly
This has been commented out as it was not needed
when the real problem was found out. */
/* Input order: 0 = FL, 1 = FR, 2=RPM,3=TC,4=RL,
5=RR */
/* Output order: FL, FR, RL, RR, RPM, TC */
/* log[9] = log[2];*/ /* Copy RMP to [9] */ /*
log[8] = log[3];*/ /* Copy TC to [8] */ /* log[2] = log[4];*/ /* Copy RL to [2]
*/ /* log[3] = log[5];*/ /* Copy RR to [3] */
/* log[4] = log[9];*/ /* Copy RPM to [4] */
/* log[5] = log[8];*/ /* Copy TC to [5] */
/* Store the data in the file */
fwrite(log,1,8,outfile);
/* Display the traction control status */
tc_display(log[5]);
/* Display the LPT port status */
/* printf(“LPT=%x\n”,inportb(LPT1+1)); */
}
else /* we timed out.. */
{
/* Mark the file so we know we timed out */
strcpy(log,”********”); fwrite(log,1,8,outfile);
time_out++; tc_display(0);
}
printf(“%x %x %x %x %x %x %d %d\r”, log[0], log[1],
log[2], log[3], log[4],log[5],j,time_out);
/* all done so wait for timer to expire... */
for(;waitflag != 128;);
waitflag = 0; /* Now clear the wait flag to repeat
*/
} /* end of data logging WHILE loop */ fcloseall();
printf(“\nTime out = %d”,time_out); printf(“
Transfers attempted: %d\n”,j);
} /* end of data log ELSE */
} while ( (inportb(LPT1+1) & 0x20) == 0x00);
/*
* We are
quitting the program so restore and close...
*/
restore();
printf(“ Quitting TCLOG now...\n”); } /* end of
MAIN() */
/*
* This is
where the sub-routines live that control the tick ...
*/
void set_rate(int Hz /* This is the sample rate we
need */)
{
int rate_hi,
rate_lo; /* low and high bytes to
program the timer */
int num; /* temp value
*/
printf(“Changing the BIOS 1/18th tick rate to
1/%d\n”,Hz);
/*
* First
calculate the values we need to program...
* If the
rate is 18... re program to normal BIOS value to restore normality
*/
/*
* The main
clock is 14.31818 MHz divided by 12 to give 1.1931816 MHz
* Divide by
65536 to give the 18.2 Hz tick.
* To
reprogram it, divide 1,193,181.6 by the Hz value.
* For 30 Hz
this is 39773 or 0x965C
*
*/
if (Hz == 18) { rate_hi = 0xFF; rate_lo = 0xFF; }
else if (Hz == 30) {rate_hi = 0x96; rate_lo = 0x5C;}
else {
num=65536/(Hz/18.2); rate_hi = num&0xFF00;
rate_hi = rate_hi/256;
rate_lo = num&0x00FF;
}
outportb(0x43,0x36); /* Set up 8253 timer for Sq
Wave */ outportb(0x40,rate_lo); /* program divisor low byte */ outportb(0x40,rate_hi);
/* program divisor high byte */
/*
* The tick
has now been set up for the required sampling frequency.
*/
} /* End of set_rate() */
void interrupt timer_tick()
{
/*
* The timer has expired so change the value of
waitflag and return.. */
waitflag = 128;
} /* end of timer tick interrupt routine */
void setup_int()
{
disable(); old_1C_vect=getvect(0x1C);
setvect(0x1c,timer_tick); enable();
} /* end of setup_int() */ void restore()
{
disable(); set_rate(18);
setvect(0x1C,old_1C_vect); enable();
}/* end of restore() */
void create_header()
{
char file_name[28]; /*
Stores the file name */
char temp_str[28]; /*
Holds the file name */
struct ffblk f; /*
File block structure */
int done; /*
Stores the result of the file find */
int count; /*
Stores the number of files to work out the
next file name for storage */
/*
* This
creates the enhanced Racelogic format file header from a
* header
file called BLANKHDR.BIN
*/
/*
* First
work out the next file name in the sequence
*/
count = 0;
done = findfirst(“data_*.dat”,&f,0);
while(!done) {
count++;
printf(“Count: %d %s\n”,count,f.ff_name); done =
findnext(&f);
}
strcpy(file_name,”data_”); itoa(count,temp_str,10);
strcat(file_name,temp_str); strcat(file_name,”.dat”);
strcpy(fn,file_name);
printf(“file name is %s\n”,fn); if (!(outfile =
fopen(fn,”wb”)))
{
printf(“Can’t open file %s. Exitting.\n”,fn);
exit(1);
exit(1);
}
/*
* Let’s do
the file copying now that we know that the
* input and
output files are open...
*/
if (!(infile = fopen(“BLANKHDR.BIN”, “r”)))
{
printf(“Can’t open BLANKHDR.BIN file for
logging\n”); exit(1);
}
/* fread(c,
260, 1, infile); /* Read the header */
* Now update
the information
*/
c[00]=8; /* Set up the extra channel 06 to 07 */
/* 3C = 125Hz, 3E = 7.5Hz, 3f = 202.89/256, 3D =
33Hz */
/* NOTE: <3a,3B,2D, and >3F DON’T WORK! */
c[07]
= 0x3D; /* Set up internal timing for 33
Hz */
/* Name the 1 s time stamp channel */
c[156]=’T’; c[157]=’C’; c[158]=’6'; c[159]=’1'; c[160]=’H’;
c[161]=’z’; c[162]=’3'; c[163]=’0';
/* Store the display factor for the channel */
c[164]= 0x00; c[165]= 0x00; c[166]= 0x4C; c[167]=
0x3E;
/* Name the 20 second time stamp channel */
c[180]=’T’; c[181]=’i’; c[182]=’m’; c[183]=’e’; c[184]=’ ‘; c[185]=’s’;
c[186]=’e’; c[187]=’c’;
/* Store the display factor for the channel */
c[188]= 0x00; c[189]= 0x00; c[190]= 0xA0; c[191]=
0x41;
/*
* Now let’s
write the channel names.....
*/
/* Name the first channel */
c[12]=’L’; c[13]=’e’; c[14]=’f’; c[15]=’t’; c[16]=’
‘; c[17]=’F’; c[18]=’r’; c[19]=’ ‘;
/* Store the display factor */
c[20]= 0x00; c[21]= 0x00; c[22]= 0x26; c[23]= 0x3F;
/* Name the second channel */
c[36]=’R’;c[37]=’i’;c[38]=’g’;c[39]=’h’; c[40]=’t’;c[41]=’
‘;c[42]=’F’;c[43]=’r’;
/* Store the display factor */
c[44]= 0x00;c[45]= 0x00;c[46]= 0x26;c[47]= 0x3F;
/* Name the third channel */
c[60]=’L’;c[61]=’e’;c[62]=’f’;c[63]=’t’; c[64]=’
‘;c[65]=’B’;c[66]=’a’;c[67]=’k’;
/* Store the display factor */
c[68]= 0x00;c[69]= 0x00;c[70]= 0x26;c[71]= 0x3F;
/* Name the fouth channel */
c[84]=’R’;c[85]=’i’;c[86]=’g’;c[87]=’h’; c[88]=’t’;c[89]=’
‘;c[90]=’B’;c[91]=’k’;
/* Store the display factor */
c[92]= 0x00;c[93]= 0x00;c[94]= 0x26;c[95]= 0x3F;
/* Was 259, now 260 for 8th channel */
fwrite(c, 260, 1, outfile); /* write the header */
/* HEADER completed! */
}/* end of create_header */
void tc_display(int tc)
{
/*
* This
displays the TC level either on the screen or
* on an
external LED array using the parallel port.
* Replace
with printf to write to the screen
*/
if (tc == 0) {outportb(LPT1,0x00);} else if (tc ==
1) {outportb(LPT1,0x01);} else if (tc == 2) {outportb(LPT1,0x03);} else if (tc
== 3) {outportb(LPT1,0x07);} else if (tc == 4) {outportb(LPT1,0x0f);}
} /* end of
tc_display() */
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.