/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... build a frequency counter using timer counter mode.
 *      The counter is gated through a timed capture input.
 */

#include <stdio.h>
#include <target.h>

/*
 * How it works:
 *
 * Timer1 is used to count falling edges at P0.10.
 * P0.11 serves as capture input. Falling edges at
 * this input latch the current counter value in a
 * capture register (CR1).
 *
 * Timer0 is used to produce a 1Hz signal to drive
 * the capture input (gate). The difference of the
 * last two CR1 values represents the frequency at
 * the P0.10 input.
 *
 * No interrupts, no CPU load - everything runs by
 * pure hardware, once the timers are initialized.
 * (Printing the result is all that is left to the
 * CPU... )
 *
 * Notabene: As the gate is triggered by the timer
 * hardware, the result is as exact as the crystal
 * driving the PLL which produces the timer clock.
 */
int
main(void)
{
	long last = 0;				// last CR1 value

	/*
	 * Set the gate output MAT0.2 (=P0.16) to
	 * 1Hz (i.e. toggle it every .5 seconds).
	 */
	Intern_t0mr2	= _PCLK/2-1;		// set MR2 to .5s
	Intern_t0mcr   |= 0x80;			// reset on MR2
	Intern_t0emr   |= 0x300;		// MAT0.2 toggle
	Intern_pinsel1 |= 2;			//        enable

	/*
	 * Comment the next line to count the internal clock
	 * instead of pulses at P0.10. This allows verifying
	 * that the exact value of _PCLK is measured.
	 */
	Intern_t1ctcr = 2;			// count CAP1.0 falling edges

	Intern_t1ccr  = 0x10;			// CR1 falling edge
	Intern_t1tcr  = 2;			// start t1
	Intern_t1tcr  = 1;			//  counter
	Intern_t0tcr  = 1;			// start timed gate

	Intern_pinsel0 |= 0xa00000;		// enable CAP1.0 (P0.10)
						//             1 (P0.11)
	/*
	 * Connect P0.16 (gate) to P0.11 (capture input) and then
	 * connect P0.10 to a pulse signal source. A simple test:
	 * Using a short cable as "antenna", "f = 50Hz" should be
	 * displayed.
	 *
	 * Note: Nothing is printed for f =0.
	 */
	while (1) if (Intern_t1cr1 != last) printf("f = %ldHz\n", Intern_t1cr1-last), last = Intern_t1cr1;
}

