Recovered post by Mandar Joshi

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

*This post was added to an ancient thread. In the process of splitting it off, it became orphaned, but was recovered from my browser cache. Ross*

 

                       I am using STK600, trying to interface ATmega2560 with AT45DB041B(data flash) in interrupt mode. I can write and read page by polling method. Th code for the same is below in which I am writing 256 bytes on page and reading all 256 bytes at a time and displaying them on hyper terminal.

                       I want to read the data from flash in interrupte. I have configured SPI interrupt  and its working properly. Only I am not getting how to read only 10 bytes at a time from page and do I have to wait in ISR till status register gives "READY" status, if yes then how?

                       Thanks in advance

 

 

 

 

        //main.c

#include <asf.h>

//Macros to make SS low and high respectively

#define cs_low() \
		delay_us(10);\
		PORTB=(0<<PB0);\
		delay_us(10);

#define cs_high() \
		delay_us(10);\
		PORTB=(1<<PB0);\
		delay_us(10);



unsigned char dat1[256],dat2[256];



unsigned char arr5[256]={0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,

0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,

0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,

0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7};



unsigned char arr6[256]={8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,
8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};	




void spimstr_init(void);
void spi_tx(unsigned char byte);
unsigned char spi_rx(void);
unsigned char get_status(void);
void init_uart(void);
void pg_program_thru_buff(int pg_addr,int buff_addr,unsigned char arr[256]);
void pg_read(int pg_addr,int buff_addr,unsigned char dat[256]);
void pg_erase(int pg_addr);





int main (void)
{
	// Insert system clock initialization code here (sysclk_init()).

	board_init();
	
	init_uart();
	
	spimstr_init();
	
	pg_program_thru_buff(1019,0x00,arr5);
	
	pg_read(1019,0x00,dat1);
	
	for(int i=0;i<256;i++)
	{
	 UDR1=(dat1[i]|0x30);
	 
	 while(UCSR1A!=0x20);	
	}
	
	pg_erase(1019);
	
	// Insert application code here, after the board has been initialized.
}




void spimstr_init()
{
	//Master Mode Selected
	//MSB out first
	//Clock Polarity and Clock Phase selected as 1
	//Clock Frequency 8MHz/128 selected

	SPCR|=(1<<SPE)|(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0);

}




void spi_tx(unsigned char byte)
{
	SPDR=byte;
	
	while(!(SPSR&(1<<SPIF)));        //wait until transmission is completed
}



unsigned char spi_rx()
{
	spi_tx(0x00);                    //sending dummy byte
	
	while(!(SPSR&(1<<SPIF)));        //wait until reception is completed
	
	return SPDR;
}



unsigned char get_status()
{
	unsigned char status;
	
	cs_low();
	
	spi_tx(0xd7);            //opcode to read status register of EEPROM
	
	status=spi_rx();         //Received the value of status register of EEPROM
	
	status=status & 0x80;
	
	cs_high();
	
	PORTA=status;               //LED PORT to indicate status register value
	
	return status;
}


void init_uart()
{
	UBRR1H=0x00;      

	UBRR1L=0x33;
	
	UCSR1B|=0x18;
	
	UCSR1C|=0x06;
}





//pg_addr is address of the page on which data to be written and buff_addr is the starting address of the page from which data to be written 
void pg_program_thru_buff(int pg_addr,int buff_addr,unsigned char arr[256])
{
	while(get_status()==0x00);

	cs_low();
	
	spi_tx(0x82);                              //opcode to write page
	
	spi_tx((0x00)|(pg_addr & 0x01d0));
	
	spi_tx((pg_addr & 0x007f)|(buff_addr & 0x0100));
	
	spi_tx(buff_addr & 0x00ff);
	
    for(int i=0;i<256;i++)
    
	spi_tx(arr[i]);
	
	cs_high();
}




void pg_read(int pg_addr,int buff_addr,unsigned char dat[256])
{
	while(get_status()==0x00);

	cs_low();
	
	spi_tx(0xd2);                           //opcode to read page
	
	spi_tx((0x00)|(pg_addr & 0x01d0));
	
	spi_tx((pg_addr & 0x007f)|(buff_addr & 0x0100));
	
	spi_tx(buff_addr & 0x00ff);
	
	spi_tx(0x00);
	
	spi_tx(0x00);
	
	spi_tx(0x00);
	
	spi_tx(0x00);

	for(int i=0;i<256;i++)
	{
	 dat[i]=spi_rx();
	}
	
	cs_high();
}




void pg_erase(int pg_addr)
{
 while(get_status()==0x00);	

 cs_low();
  
 spi_tx(0x81);                  //opcode to erase page
 
 spi_tx((0x00) | (pg_addr & 0x01d0));
 
 spi_tx((pg_addr & 0x007f)|0x00);
 
 spi_tx(0x00);

 cs_high();
}

        //init.c

 

       #include <board.h>
       #include <compiler.h>
       #include <conf_board.h>

       void board_init(void)
     {
         DDRA|=0xff;                            //Make PORTA as o/p port for LED
 
        DDRB|=(1<<DDB2)|(1<<DDB1)|(1<<DDB0);   //Clk,MOSI,MISO pin configuration
     }

 

Ross McKenzie ValuSoft Melbourne Australia

Last Edited: Thu. Feb 5, 2015 - 11:11 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
                       I am using STK600, trying to interface ATmega2560 with AT45DB041B(data flash) in interrupt mode. I can write and read page by polling method. Th code for the same is below in which I am writing 256 bytes on page and reading all 256 bytes at a time and displaying them on hyper terminal.

                       I want to read the data from flash in interrupte. I have configured SPI interrupt  and its working properly. Only I am not getting how to read only 10 bytes at a time from page and do I have to wait in ISR till status register gives "READY" status, if yes then how?

The waiting does not have to be in an ISR.

Iluvatar is the better part of Valar.

Last Edited: Sat. Feb 7, 2015 - 07:39 PM