/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... use the SPI.
 */

#include <stdio.h>
#include <target.h>
#include "../tty.h"

/*
 * The SPI is setup as master for single byte transfers.
 *
 * The SPI rate is sysclk/2/SPBR (in spcr0). The value for SPBR
 * must be >1. For your application modify settings like phase,
 * polarity etc. accordingly!
 */
static void
spi_init(void)
{
	 INTERN.qsm.qpar  = 0x7b;		/* enable SPI pins */
	 INTERN.qsm.qpdr  = 0x78;		/* chip selects off */
	 INTERN.qsm.qddr  = 0x7e;		/* set data direction */
	 INTERN.qsm.spcr0 = 0x8002;		/* master, SCK =sysclk/4 */
	*INTERN.qsm.comd_ram = 0xf;		/* 8 bits, no chip selects */
}

/*
 * SPI transfer
 *
 * Return received data.
 */
static int
spi_xfer(int c)
{
	*INTERN.qsm.tran_ram = c;		/* load transmit data */
	 INTERN.qsm.spcr1 |= 0x8000;		/* start transfer */

	/*
	 * Wait for transfer complete.
	 */
	while (!(INTERN.qsm.spsr&0x80)) ;

	INTERN.qsm.spsr = 0;			/* clear flags */
	return *INTERN.qsm.rec_ram;
}

/*
 * Test the SPI in loopback mode, i.e.
 *
 *  MISO connected to
 *  MOSI.
 *
 * Note: Applications with "real" SPI devices
 * need to select exactly ONE device prior to
 * starting transfers.
 */
int
main(void)
{
	/*
	 * Here:
	 * De-select all SPI devices!
	 */

	spi_init();				/* initialize SPI */
	while (1) {
		int sc, rc;			/* send/receive char */

		puts("Hit any key...");
		putch(sc = getch());

		/*
		 * Here:
		 * De-select all SPI devices!
		 * Select desired SPI device!
		 */

		printf("\nTransferring 0x%02x... ", sc);
		printf("received 0x%02x\n", rc = spi_xfer(sc));
		if (rc != sc) puts("Loopback FAILED!\7");
	}
}

