QNX X86 82c54

/*
*  This program will set up a irq handler, and 
* set up a 82c54-10 on the parrallel port inorder 
* to generate interrupts at a controlled pace.
*  This program uses the eventattach call, it is not as fast as
* the interruptattach version
*
*  the commandline args are
*    portevent  [PORT address] [interrupt number] [divisor]
*
* the comand word is made from the following
*  d7 d6 d5 d4 d3 d2 d1 d0
*                        *  bcd =1 binary=0
*               *  *  * --- mode <<1  ie mode 1 is 02 mode 2 is 0x04 mode 3 is 0x06
*         *   * ----------- read write control: 00 latch cnt, 01 is r/w lsb only
*                            10 is r/w msb only and 11 is r/w lsb then msb
*   *  * ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is c/t3
*                            and the read back command is 11
*  Pat Ford april 18 2000
*/

 

 

#include <stdio.h>
#include <stdlib.h>
#include <hw/inout.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>

/*
mapping info for base + 2 (control)
where        d3     d2    d1       d0
                          __       __
what         A1     A0    RD       WR      Hex
------------------------------------------------------------
wr_cntr0      0     0      1       0       0x09
wr_cntr1      0     1      1       0       0x01
wr_cntr2      1     0      1       0       0x0D
wr_cntrl      1     1      1       0       0x05
rd_cntr0      0     0      0       1       0x0A
rd_cntr1      0     1      0       1       0x02
rd_cntr2      1     0      0       1       0x0E
 It looks funky but remember that d0, d1, d3, are inverted
*/

#define wr_ct1    0x09
#define wr_ct2    0x01
#define wr_ct3    0x0D
#define wr_cntrl  0x05
#define rd_ct1    0x0A
#define rd_ct2    0x02
#define rd_ct3    0x0E
#define rd_cntrl  0x06
#define cntrl_off 0x0B
#define idle      0x08

#define A0        0x04
#define A1        0x08
#define WR        0x02
#define RD        0x01

#define A0        0x04
#define A1        0x08
#define WR        0x02
#define RD        0x01

#define control_word_ct1   0x00
#define control_word_ct2   0x40
#define control_word_ct3   0x80
#define control_word_lsb   0x10
#define control_word_msb   0x20
#define control_word_word  0x30

#define control_mode_0     0x00
#define control_mode_1     0x02
#define control_mode_2     0x04
#define control_mode_3     0x06
#define control_mode_4     0x08
#define control_mode_5     0x0A

#define control_mode_bcd   0x01
#define control_mode_bin   0x00
#define base               PORT
#define inputs             PORT+1
#define control            PORT+2

struct sigevent         event;
volatile unsigned       counter;


int main(int argc, char *argv[])
{

int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0, IRQ=0;
uintptr_t lpt1;
size_t len=6;
uint64_t cps=0, t1=0, t2=0, sum=0, td;
float sec,hi, lo=1.0;

 

// Initialize event structure
event.sigev_notify = SIGEV_INTR;

mode=0x34;

PORT=strtol(argv[1], 0, 0);
IRQ=strtol(argv[2], 0, 0);
i=strtol(argv[3], 0, 0);
lsb=i & 0xff;
msb= i>>8;

if ( PORT==0 || IRQ==0 || i==0 )
{
 printf("\n You MUST include [PORT address] [interrupt number] and [divisor] as commandline args\n");
 exit(EXIT_FAILURE);
}

// Request I/O privity
ThreadCtl(_NTO_TCTL_IO, 0);


// map the io space we want
lpt1=mmap_device_io( len, PORT );
if( errno != EOK)
 printf("\nMmap_device errno %s\n", strerror( errno ) );


//set up the counter timer
out8( control, 0x04);    // set the address bus
out8(base,mode);         // have to setup data
out8(control,wr_cntrl);  // then drop the write enable
out8(control, idle);     // raise the write enable
out8(control, 0x08);
out8(base,lsb);
out8(control,wr_ct1);
printf ("\noutputing %x as lsb",lsb);
out8(control, idle);

out8(control, 0x08);
out8(base,msb);
out8(control,wr_ct1);
printf ("\noutputing %x as msb",msb);
out8(control, idle);

//  assert the irq enable
out8(control, ( idle | 0x10));
out8(base,0x00);

//out8(control,0xD8);

// Attach ISR vector
id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
if (id == -1)
  {
    perror("InterruptAttachEvent failed");
    exit(EXIT_FAILURE);
  }

cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;

printf("\nwaiting to be interrupted\n");
for (i = 0; i < cnt; ++i)
  {
    InterruptWait(0, NULL);
    tmp=InterruptUnmask(7, id);
    t1=ClockCycles();
    if (i!=0)
      {
        td=t1-t2;
        sec=(float)td/cps;
        if (sec<lo)
          lo=sec;
        if (sec>hi)
           hi=sec;
            sum+=sec;
        t2=t1;
      }
      else
      {
        sum=t1;
        t2=t1;
      }
   }

td=sum/(cnt-1);
printf(" the value for cps is %lld \n",cps);
printf ("the value of lo is %2.8f \n",lo);
printf ("the value of hi is %2.8f \n",hi);
printf("the average time was.. %2.8f\n ", sec);
  return 0;
}

 

posted @ 2014-05-22 10:32  集成块儿  阅读(293)  评论(0编辑  收藏  举报