/* FILE: C:\MAX158\ADC1_0.C DATE: 06/28/00 22:25 1.0 - STARTED AUTH: P.OH DESC: Stitch interrupts and CTC (8253/4 Counter Timer Chip) reprogramming into an ADC application program. User prescribes a sampling time for data acquisition. LOGS: - May need to distinguish between greater or lesser than 55 msec ??? - 2-dim data array malloc? */ #include #include #include #include #include #include #define CTC_CLOCK_FREQUENCY 1193182 /* Hz */ #define DEFAULT_CTC_DIVISOR 65536 /* pulses */ #define CTC_CONTROL_ADDRESS 0x43 #define CTC_COUNTER0 0x40 #define NEW_MODE 52 /* Counter 0, Mode 2, LO/HI loading */ #define DEFAULT_MODE 52 /* Same as newMode */ #define IRQ3 0x0b #define TRUE 1 #define FALSE 0 /* globals */ int EOC; long count; /* Prototypes */ void reProgramCtc(float); void restoreCtc(void); void interrupt (*oldIrq3)(void); /* IRQ3 hardware interrupt */ void interrupt newIrq3(void); /* IRQ3 ISR */ void interrupt (*old0x1C)(void); /* 0x1C software interrupt */ void interrupt new0x1C(void); /* 0x1C ISR */ void calculateTickRate(float); void main(void) { int baseAddress, channel; /* MAX158 card parameters */ float deltaT, freq; /* Sampling time [sec], frequency [Hz] */ int k, kMax; /* Sample and max sample index */ float* data; /* Acquired data array */ FILE* fp; /* Acquired data file */ clrscr(); window(5,5,50,75); gotoxy(2,2); cprintf("Sampling time in seconds? e.g. 0.010"); scanf("%f", &deltaT); gotoxy(2,3); cprintf("How many samples? e.g. 1000"); scanf("%d", &kMax); data = (float*) malloc(kMax * sizeof(int)); if(deltaT < 0.055) { /* sampling time < 55 msec */ reProgramCtc(deltaT); } else { /* sampling time >= 55 msec */ calculateTickRate(deltaT); } restoreCtc(); /* Nice to return everything back */ } /* end of main */ /* -------------------------------------------------- new0x1C: ISR for software interrupt 0x1C (BIOS tick). Global variable count incremented at tick rate. -----------------------------------------------------*/ void interrupt new0x1C(void) { count++; old0x1C(); } /* end of new0x1C */ /* -------------------------------------------------- newIrq3: ISR for hardware interrupt IRQ 3. Code executed everytime IRQ 3 rises to +5V. This occurs when MAX158 /INT goes low. This signals an end-of-conversion (EOC). -----------------------------------------------------*/ void interrupt newIrq3(void) { #pragma asm pushf; /* preserve interrupt flag */ #pragma asm cli; EOC = TRUE; /* signal end-of-interrupt (EOI) */ outportb(0x20, 0x20); /* signal end-of-interrupt (EOI) */ #pragma asm popf; /* restore interrupt flag */ return; } /* end of newIrq3 */ /* -------------------------------------------------- reProgramCtc: If sampling time < 0.055 (55 msec), reprogram CTC to generate interrupt ticks at desired sampling time -----------------------------------------------------*/ void reProgramCtc(float samplingTime) { int loByte, hiByte; /* CTC divisor low and high byte */ int newCtcDivisor; /* CTC divisor [pulse] */ newCtcDivisor = (int)(samplingTime * CTC_CLOCK_FREQUENCY); /* [pulses] */ loByte = newCtcDivisor & 0xFF; hiByte = (newCtcDivisor >> 8) & 0xFF; #pragma asm pushf; /* preserve interrupt flag */ #pragma asm cli; outportb(CTC_CONTROL_ADDRESS, NEW_MODE); outportb(CTC_COUNTER0, loByte); outportb(CTC_COUNTER0, hiByte); gotoxy(2,4); cprintf("divisor = %d\n", newCtcDivisor); gotoxy(2,5); cprintf("loByte = %d, hiByte = %d\n", loByte, hiByte); #pragma asm popf; /* restore interrupt flag */ return; } /* end reProgramCtc */ /* -------------------------------------------------- calculateTickRate: If sampling time >= 0.055 (55 msec), calculate necessay tick rates. -----------------------------------------------------*/ void calculateTickRate(float samplingTime) { /* Fill up function with number of usec, msec, sec, min, hours ? Suppose want deltaT = 0.056 sec, how do we achieve this? A. Could program CTC with a "default" value of 0.000010 sec = 10 usec. Then 56 msec/10 usec = 5600 Then count 5600 tick triggers? B. What's a good "default" value though? The maxium is 65536/CTC_CLOCK_FREQUENCY = 0.0549 sec = 55 msec. Perhaps need to look at deltaT last decimal place. For example 0.056 has a third decimal value of 6, or 1 msec resolution. Thus reprogramming CTC with a default value of 1 msec will require counting 56 msec/1 msec = 56 times. Suppose deltaT = 0.05606 sec. Last decimal place requires 0.00001 sec resolution = 10 usec resolution. Reprogramming CTC with default value of 10 usec will require counting 0.05606 sec/10 usec = 5606 times. C. How about every 10 sec? We would have to count 10 sec/18.1 sec = 552.49 times. */ } /* end of calculateTickRate */ /* -------------------------------------------------- restoreCtc: Restore CTC back to original default -----------------------------------------------------*/ void restoreCtc(void) { int loByte, hiByte; loByte = DEFAULT_CTC_DIVISOR & 0xFF; hiByte = (DEFAULT_CTC_DIVISOR >> 8) & 0xFF; outportb(CTC_CONTROL_ADDRESS, DEFAULT_MODE); outportb(CTC_COUNTER0, loByte); outportb(CTC_COUNTER0, hiByte); return; } /* end of restoreCtc */