/* Listing 6 */

/*****************************************************
	TIMER.C 

	Basic Routines for programming the 9513 timer
	counter on the Lab Master AD.

	Copyright Don Bradley, 1991.

	Permission is granted for used of these routines
	in any manner as long as this copyright notice is
	included.

	Tested using Quick C 2.5 and MSC 6.0 on a 
	Toshiba T5200.

 *****************************************************/

#include <math.h>
#include <conio.h>

#include "labmastr.h"

void timer_reset()
	{
	/* reset 9513 timer\counter */
	outp(TIMER_CONTROL, 0xFF);

	/* Enable 16-bit Data Access */
	outp(TIMER_CONTROL, 0xEF);

	/* initalize master mode reg */
	outp(TIMER_CONTROL, 0x17);

	/* BCD Division, 16 Bit Data */
	outpw(TIMER_DATA, 0xA000);
	}

void timer5_on()
/*& Turns timer 5 on. Used to start ADC output from the
	 fifo thru manual or DMA control. */
	{
	/* turn timer 5 on */
	outp(TIMER_CONTROL, 0x30);
	}

void timer5_off()
/*& Turns timer 5 off. Used to stop or disable ADC
	 output from the fifo thru manual or DMA control. */
	{
	/* turn timer 5 off */
	outp(TIMER_CONTROL, 0xD0);
	}

#define COUNTSTART  0xb
#define COUNTHIGH  0xf

double timerad(double freq)
/*& Sets timer 5 of the labmaster board to the desired
	 frequency for data collection. */
	{
	double time;
	unsigned count = COUNTSTART;

	time = TIMER_F1 / freq;
	while (1) {
		if (time < 65536.0)
			break;
		time /= TIMER_DIVISOR;
		++count;
		}
	if (count <= COUNTHIGH) {
		timer5_off();

		freq = TIMER_F1 / ((unsigned) (time) *
			pow(10.0, (double) (count - COUNTSTART)));

		// initalize master mode register
		outp(TIMER_CONTROL, 0x17);
		// BCD Division, 16 Bit Data Bus counter 5 setup
		outpw(TIMER_DATA, 0xA000);
		outp(TIMER_CONTROL, 0x5);

		// No Gating, Count on Rising Edge,
		// F(count-COUNTSTART), Count Repetitively,
		// Count Down, Active High Terminal Count Pulse
		// frequency range 400Hz to 4MHz
		outpw(TIMER_DATA, (count << 8) | 0x21);

		outpw(TIMER_DATA, (int) time);

		timer5_on();
		}
	else 
		freq = 0.0;
	return (freq);
	}

void step_timerad()
	{

	timer5_off();

	// Point to Counter 5
	outp(TIMER_CONTROL, 0x5);

	// Active High output, Count Down, Binary Counting,
	// Count Repeatedly, Reload from Load Register
	// only, No Gateing, No Special Gate, Count Falling
	// Edges and Use Source 5.
	outpw(TIMER_DATA, 0x1521);
	outpw(TIMER_DATA, 2);

	// Load Counter 5
	outp(TIMER_CONTROL, 0x50);
	timer5_on()
	// Step Counter 5
	outp(TIMER_CONTROL, 0xF5);
	}
