/*

Filename:               AN-0056.c

Function name:          main

Edit date:              12/09/91

Function:
                Demonstration program shows how to convert analog data
                in the fastest time possible.  Uses PC control and 5710
                cards.

                Compiled using Borlands Turbo-C, version 2.0.

                Timing periods using various cards are shown below:

                Card    Time for 1000     Time/conversion      Conversions/
                 No.     conversions                            second
                5010    .05 sec           50 micro-seconds      20000
                5016    .023 sec          23 micro-seconds      43400
 (with 5710-1)  5016    .012 sec          12 micro-seconds      83000

5016 was operating at 16 Mhz (fast speed) for above measurements.  The 
5010 was at 10 Mhz.

These tests were performed on prototype cards and will not necessarily
reflect your actual results.

Polling is the fastest method of bringing in data.  Interrupts can take
up to 40 microseconds before processing can even begin.  

You can change channels and still read data quickly.  However, through put
will decrease significantly.  Don't forget to allow about 4 micro seconds
for the MUX to settle when changing channels.

Revisions:

*/

/* Includes */

#include        "stdio.h"
#include        "dos.h"

/* Definitions */
/* set up addresses and offsets of 5710                                 */

#define BASE_5710       0x100
#define BASE_CTC        4+BASE_5710     /* 8254 base address            */
#define BASE_8255       8+BASE_5710     /* 8255 base address            */
#define CH_ADDR         9+BASE_5710     /* analog channel select        */
#define VIDEO           0x10            /* video interrupt              */
#define KEYBOARD        0x16            /* keyboard interrupt           */
#define ARRAY           1000            /* data array size              */

/* Declarations */

        int     data[ARRAY];            /* data array                   */
        int     hibyte,lowbyte;         /* data declarations            */
        long    accum;                  /* averaged data                */

/* Program                                                              */

void main()
{
        int ch,d;
        char sdata[10];

        outportb(BASE_8255+3,128);

/* print out intro messages                                              */

        prints("\n\n\r5710 burst mode analog input demonstration.\n\r");
        prints("Program is intended to show how fast an A-D converson\n\r");
        prints("and logging cycle can be.\n\n\r");
        prints("1000 samples are logged into an array.  When the array is full\n\r");
        prints("all values are added then divided by 1000.  The result is then\n\r");
        prints("printed to the screen.  The process then repeats.\n\n\r");
        prints("Assumes the 5710 card is set to the following conditions:\n\r");
        prints("         Base address 100H\n\r");
        prints("         No interrupts set (Jumper block W1)\n\n\r");
        prints("Average converted value from channel 0 (J2) will be printed.\n\r");
        prints("Port C, bit 0 (pin 13 of J1) will go to a 1 during conversion\n\r");
        prints("You can look at this bit to determine the time it takes to\n\r");
        prints("do 1000 conversions.\n\n\r");
        prints("To end program, press any key.\n\n\r");

/* set up 82C55 port on 5710 for outputs and set channel to convert     */

        outportb(BASE_8255+3,128);
        outportb(BASE_8255+1,1);

/* Loop until key is pressed then exit program                          */

        while (inkey2() == 0)
        {

/* do dummy read of converter to clear last conversion                  */

                hibyte = inportb(BASE_5710+2);
                lowbyte = inportb(BASE_5710+3);

/* Initiate conversion                                                  */

                outportb(BASE_5710,0);

/* signal start of conversion.  Output to port C, bit 0 of 8255         */

                outportb(BASE_8255+2,1);

/* bring in 1000 conversions, average them, then print out average      */

                for(ch = 0; ch != ARRAY; ch++)
                {

/* wait until conversion is done (up to 25 micro seconds).  If not done
in time, exit with message to screen.                                   */

                        d=0;
                        while((inportb(BASE_5710) & 1) == 0)
                        {
                                d++;
                                if(d > 40)   /* change # for processor */
                                {
                                        prints("\n\n\rTime out error!\n\r");
                                        prints("Program terminated.\n\n\r");
                                        exit();
                                }
                        }

/* read in data                                                        */

                        hibyte = inportb(BASE_5710+2);
                        lowbyte = inportb(BASE_5710+3);

/* Initiate conversion again.  Do not initiate a conversion until the
data has been read.                                                   */

                        outportb(BASE_5710,0);

/* convert data to a 16 bit number and store it                        */

                        data[ch] = hibyte*16 + lowbyte/16;

                }

/* signal done with loop                                               */

                outportb(BASE_8255+2,0);

/* loop to add data then average it                                    */

                accum = 0;
                for(ch = 0; ch != ARRAY; ch++)
                        accum = accum + data[ch];

                accum = accum / ARRAY;
                ltoa(accum,sdata,10);

/* print out data to the screen                                        */

                prints("Averaged data = ");
                prints(sdata);
                prints("\r");
        }

/* clean up the screen a bit                                            */

        prints("\n\n\rEnd of 5710 demonstration program.\n\r\n");
}

/* print routine to screen
 Prints a string using the BIOS write TTY.  Input to routine is a string.*/

prints(char *st)
{
        union REGS regs;

        int x,y;
        char *p;
        p = st;
        x = strlen(st);

/* loop to print out each character in the string                       */

        for(y = 0;y <x;y++)
        {
                regs.h.ah = 0xe;
                regs.h.al = *(p+y);
                regs.x.bx = 1;
                int86(VIDEO,&regs,&regs);
        }
}

/* Get a key from the BIOS keybaord buffer using its interrupt.  Returns
ASCII character if present.

This routine should be used in place of kbhit().  kbhit does work most of
the time but may not work if certian libraries are called.              */

int inkey2()
{
        union REGS regs;

/* check if a key is present                                            */

        if(keyhit() == 0)
                return(0);

/* get the key                                                          */

        regs.x.ax = 0;
        int86(KEYBOARD,&regs,&regs);
        return(regs.h.al);
}

/* check of keyboard has been pressed using BIOS interrupt.  Returns 0
if no key has been pressed or the ascii key pressed.

NOTE: This does not remove thekey from the buffer.  Use INKEY2 to
do that.                                                                */

int keyhit()
{
        union REGS regs;

        regs.x.ax = 0x100;
        int86(KEYBOARD,&regs,&regs);
        if((regs.x.flags & 0x40) != 0)
                return(0);
        else
                return(regs.x.ax & 0xff);
}
