#include <c8051f350.h>




// Anschlüsse EPROM AT45DB161B  (SPI-Device)
sbit MSCK = P0^0;
sbit MISO = P0^1;
sbit MOSI = P0^2;
sbit MCS  = P0^3;
sbit MRDY = P1^1;
sbit MRES = P1^2;

//Chip-Select
#define CS_0 NSSMD0 = 0		
#define CS_1 NSSMD0 = 1		


// buffer 1 write 
#define BUFFER_1_WRITE 0x84

// buffer 2 write 
#define BUFFER_2_WRITE 0x87

// buffer 1 read
#define BUFFER_1_READ 0x54

// buffer 2 read
#define BUFFER_2_READ 0x56

// DataFlash status register for reading density, compare status, 
// and ready/busy status
#define STATUS_REGISTER_READ 0x57




//--------------------- MAIN -------------------------------------------------------------------------
void main()
{
	
	unsigned char status, buffByte;
	unsigned int count=0;
	
									   
										    // disable watchdog timer
	PCA0MD &= ~0x40;                        // WDTE = 0 (clear watchdog timer enable)


	Init_Device();

	
	

	while(1)
	{
		status  = EE_Read_Status();		    // Statusinformationen aus EPROM
		
		EE_Write_Buffer(1,0x000,0x01);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x001,0x02);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x002,0x03);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x003,0x04);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x004,0x05);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x005,0x06);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x005,0x07);		// schreiben in Buffer 
		EE_Write_Buffer(1,0x007,0x08);		// schreiben in Buffer 
   
		buffByte = EE_Read_BUFFER(1,0x001); // lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x002);	// lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x003);	// lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x004);	// lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x005);	// lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x006);	// lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x007);	// lesen aus Buffer 
		buffByte = EE_Read_BUFFER(1,0x008);	// lesen aus Buffer 
		
	}


//-------------------- END MAIN ----------------------------------------------------------------------


// ------------------- INIT DEVICE -------------------------------------------------------------------
// Peripheral specific initialization functions,
// Called from the Init_Device() function
void Port_IO_Init()
{
    

    // P0.0  -  SCK  (SPI0), Push-Pull,  Digital
    // P0.1  -  MISO (SPI0), Open-Drain, Digital
    // P0.2  -  MOSI (SPI0), Push-Pull,  Digital
    // P0.3  -  NSS  (SPI0), Push-Pull,  Digital
    // P0.4  -  TX0 (UART0), Push-Pull,  Digital
    // P0.5  -  RX0 (UART0), Open-Drain, Digital
    // P0.6  -  Unassigned,  Open-Drain, Digital
    // P0.7  -  Unassigned,  Open-Drain, Digital

    // P1.0  -  Unassigned,  Open-Drain, Digital
    // P1.1  -  Unassigned,  Open-Drain, Digital
    // P1.2  -  Unassigned,  Open-Drain, Digital
    // P1.3  -  Unassigned,  Open-Drain, Digital
    // P1.4  -  Unassigned,  Open-Drain, Digital
    // P1.5  -  Unassigned,  Open-Drain, Digital
    // P1.6  -  Unassigned,  Open-Drain, Digital
    // P1.7  -  Unassigned,  Open-Drain, Digital

    P0MDOUT  |= 0x1D;
    XBR0      = 0x03;
    XBR1      = 0x40;
}

void SPI_Init()
{

	SPI0CFG   = 0x70;
    SPI0CN    = 0x09;
    SPI0CKR   = 0x04;

}








//-------------------- LESEN EPROM STATUS ------------------------------------------------------------
unsigned char EE_Read_Status(void)  // lesen von ADDR1 
{
	unsigned char retval;		// Rückgabewert;

	
	CS_0;						// select EEPROM, CS = 0;
	
	
	
	if(TXBMT)
	{
		write_SPI(STATUS_REGISTER_READ);
		write_SPI(0x00);
	}


	CS_1;					   // deselect EEPROM, CS = 1;


	Timer0_ms(10);

	retval = SPI0DAT;
	
	 return retval;

}

//--------------------- LESEN BUFFER 1 od. 2 -------------------------------------------------------
unsigned char EE_Read_BUFFER(bit buffer,int buffer_counter )  // lesen von ADDR1 
{
	unsigned char retval;		// Rückgabewert;

	

	while(!MRDY);

	//CS_0;						// select EEPROM, CS = 0;

	


	if(TXBMT)
	{
	//übertragen "Lesen" opcode
		if(!buffer)
			write_SPI(BUFFER_1_READ);  			// Befehl -> Lesen Buffer 1
   		else									// Befehl -> Lesen Buffer 2
			write_SPI(BUFFER_2_READ);

		write_SPI(0x00);
		write_SPI(0x00<<6);
		write_SPI((char)(buffer_counter>> 2));   	//  MSB adresse
		write_SPI((char)(buffer_counter));   		//  LSB adresse
		write_SPI(0x00);
    }
	
	
	
	CS_1;					   // deselect EEPROM, CS = 1;
							   
	Timer0_ms(10);			   // warte 10ms

	retval = SPI0DAT;		  // lese Datenregister von SPI

	while(!MRDY);

	return retval;

}

//--------------------- SCHREIBEN EPROM ------------------------------------------------------------

void EE_Write_Buffer(bit buffer, int buffer_counter, unsigned char flash_data) // schreiben in Buffer 
{
    
	int page_counter = 0;
	
	while(!MRDY);

	CS_0;						// select EEPROM, CS = 0;
	
	
								
	if(TXBMT)				  // ist TX -SPI leer
	{	
	//übertragen "Lesen" opcode
		if(!buffer)
			write_SPI(BUFFER_1_WRITE);  			//  Befehl schreiben in Buffer 1
		else
			write_SPI(BUFFER_2_WRITE);  			//  Befehl schreiben in Buffer 2
	
		write_SPI(0x00);
		write_SPI(0x00<<6);
		write_SPI((char)(buffer_counter>> 2));   	//  MSB adresse
		write_SPI((char)(buffer_counter));   		//  LSB adresse
		write_SPI(flash_data);						//  Wert, der geschrieben werden soll
	}


	
	
	CS_1;					   // deselect EEPROM, CS = 1;

	while(!MRDY);
}


void write_SPI(unsigned char spi_data)  //SPI_Mode 3
{

     unsigned int i=0;
	 

		for(i=0;i<100;i++);
		

		SPI0DAT = spi_data;				
		while(!SPIF);
		SPIF = 0;

			
	    for(i=0;i<100;i++);   // kurz warten, danach Dummy senden
		
		SPI0DAT = 0x00;				
		while(!SPIF);
		SPIF = 0;
		
		
	   
}