/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... install interrupt mode for the COM receiver.
 */

#include <stdio.h>
#include <sys/arm7tdmi.h>
#include <target.h>
#include "delay.h"

extern char _bdata;				// data start
#define IRQ_VEC	(*((long *)&_bdata+14))		// IRQ vector

static unsigned char fifo[256];			// char buffer
static unsigned char wind;			// write index
static unsigned char rind;			// read  index

/*
 * IRQ service
 *
 * Only com is enabled for IRQ,
 * no need for polling IRQSTA.
 */
static void __attribute__((interrupt))		// handle as ISR!
irq_sr(void)
{
	fifo[wind++] = Intern_comrx;		// put received char to buf
}

/*
 * Read FIFO status.
 *
 * Return number of chars in FIFO.
 */
static int
fifo_stat(void)
{
	return (unsigned char)(wind-rind);
}

/*
 * Read max. count chars from FIFO to buf.
 *
 * Return number of chars read.
 */
static int
fifo_read(char *buf, unsigned count)
{
	int r = 0;

	while (count-- && rind != wind) buf[r++] = fifo[rind++];
	return r;
}

/*
 * The program enters a delay loop to simulate some activity. The
 * IRQ SR saves characters received during that time in a FIFO.
 *
 * After the delay the FIFO status is shown, the FIFO emptied and
 * its contents displayed. This process repeats "forever".
 */
int
main(void)
{
	IRQ_VEC = (long)irq_sr;			// set IRQ SR addr
	Intern_irqen = 0x4000;			// enable com for IRQ
	Intern_comien0 = 1;			//            rec int

	ENABLE_INTERRUPTS;			// enable core ints

	while (1) {
		char buf[sizeof(fifo)+1] = {0};	// read buffer

		puts("\nType some characters...");
		delay(10000);
		printf("%d chars in buffer\n", fifo_stat());
		printf("%d chars read\n", fifo_read(buf, sizeof(fifo)));
		puts(buf);
	}
}
