/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... read the serial Flash ID.
 */

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

/*
 * Pins
 */
#define PIN_CSADC	0x00010000		// P0.16
#define PIN_MS3		0x00400000		// P0.22
#define PIN_CSFLASH	0x00800000		// P0.23
#define PIN_PORT	0xff000000		// P0.24.. 31

/*
 * Initialize hardware.
 */
static void
init(void)
{
	/*
	 * Define I/Os, set all outputs hi.
	 */
	Intern_ioset  = PIN_CSADC|PIN_MS3|PIN_CSFLASH|PIN_PORT;
	Intern_iodir |= PIN_CSADC|PIN_MS3|PIN_CSFLASH|PIN_PORT;

	/*
	 * De-select SPImS
	 */
	Intern_ioclr = PIN_MS3;
	Intern_ioset = PIN_MS3;

	Intern_spcr	= 0x20;			// MSTR
	Intern_spccr	= 8;			// SPI SCK =pclk/8
	Intern_pinsel0 |= 0x5500;		// enable SPI pins
}

/*
 * SPI transfer (no error check!)
 *
 * Return received data.
 */
static int
spi_xfer(int c)
{
	Intern_spdr = c;			// start transfer

	/*
	 * Wait for transfer complete or error
	 * (mask the reserved bits 0, 1 and 2).
	 */
	while (!(Intern_spsr&0xf8)) ;

	return Intern_spdr;
}

/*
 * Read and print the manufacturer/device codes.
 */
int
main(void)
{
	init();

	while (1) {
		puts("\nHit RETURN to read device ID..."), getchar();

		Intern_ioclr = PIN_CSFLASH;	// CS lo
		spi_xfer(0x9f);			// RDID cmd

		printf("Manufacturer code   : %02x\n", spi_xfer(0));
		printf("      Device code 1 : %02x\n", spi_xfer(0));
		printf("      Device code 2 : %02x\n", spi_xfer(0));

		Intern_ioset = PIN_CSFLASH;	// CS hi
	}
}
