/* spi_flash_01.c
* SPI-Kommunikation mit Flash-Speicher SST25VF016B und Auslesen des Statusregisters
* Controller: ATmega88 @ 8MHz
*/
#include <avr/io.h>
#define WP		(1<<PC5)		// Write Protect disable @ PC5
#define HOLD	(1<<PC4)		// Stop serial communication disable @ PC4
#define CE		(1<<PB2)		// Chip Enable @ PB2
#define MOSI	(1<<PB3)		// Master Out Slave In @ PB3
#define MISO	(1<<PB4)		// Master In Slave Out @ PB4
#define SCK		(1<<PB5)		// Clock @ PB5

uint8_t status_register=0;

void SPI_MasterInit(void)					// Init SPI Master
{
	DDRB = MOSI|SCK|CE;						// Set MOSI, SCK, CE output
	SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);	// Enable SPI, Master, set clock rate fck/64
}

void SPI_MasterTransmit(uint8_t data)		// Transmit SPI data
{
	SPDR = data;							// Start transmission
	while(!(SPSR & (1<<SPIF)));				// Wait for transmission complete
}

uint8_t SPI_SlaveReceive(void)				// Receive SPI data
{
	while(!(SPSR & (1<<SPIF)));				// Wait for reception complete
	return SPDR;							// Return SPI-Dataregister
}

int main(void)
{
	DDRC |= WP | HOLD;		// Set WP, HOLD output
	PORTC |= WP|HOLD;		// Set WP, HOLD high
	
	SPI_MasterInit();		// Init SPI Master
	
	PORTB &= ~CE;			// CE = low (start communication)
	
	SPI_MasterTransmit(0x05);	// Send command 0x05 (Read the status register)
	SPI_MasterTransmit(0x00);	// Send one dummy byte
	
	status_register = SPI_SlaveReceive();	// Read received SPI data and store in status_register
	
	PORTB |= CE;							// CE = high (end of communication)
	status_register=0;						// set the variable status_register to 0
	
	while(1)
	{
		asm("NOP");		// NOP = no operation (Inline Assembler Instruction)
	}
}