|
|
View previous topic :: View next topic |
Author |
Message |
overmindx
Joined: 06 Oct 2008 Posts: 43
|
using 16mb spi flash memory |
Posted: Tue Mar 02, 2010 4:17 am |
|
|
Hi everybody, I've been trying this to work but to no avail. I am using an AT45db161d 16 mb spi flash memory.
Could somebody with a good heart take a look at my code and see if I am missing something. in the sample code below, even in the part where I want to get the status of the flash memory, located in this function -->int1 RdyBusy(void), it already doesn't work. Using the oscilloscope, I can see that the mcu is sending its command. The problem is that the flash memory is not sending anything.
Here is my code:
Code: |
#include <18f26k20.h>
#device adc=10
#FUSES WDT32768, INTRC_IO, NOPROTECT, NOIESO, BROWNOUT, PUT, NOCPD, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOEBTR, NOCPB, NOEBTRB, NOWRTC, NOWRTB, FCMEN, NOXINST, PBADEN, LPT1OSC, MCLR
#use delay(clock=16000000)
#use rs232(baud=19200, xmit=PIN_B4, rcv=PIN_B3, stream=PC)
#include <stdlib.h>
#include <string.h>
#define CS PIN_C2
unsigned char buffer[512];
unsigned char data[512];
void Init(void);
void MemRead(unsigned char *addr,char *buff, unsigned int len);
void MemWrite(unsigned char *addr,char *buff, unsigned int len);
unsigned char WriteSPI(unsigned char data);
char RdyBusy(void);
void SetSizeFT(void);
void main(void){
unsigned long address = 0x00;
unsigned long address2 = 0x00;
char data2[] = {"the quick brown fox jumps over the lazy dog"};
delay_ms(3000);
strcpy(data,data2);
Init();
while(RdyBusy());
delay_ms(200);
address=address<<9;
MemWrite(address,data,512);
while(RdyBusy());
delay_ms(200);
address2=address2<<23;
MemRead(address,buffer,512);
delay_ms(200);
output_high(CS);
while(1){
fprintf(PC,"data buffer = %s\n",buffer);
delay_ms(400);
}
}
void Init(void){
output_high(CS);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
while(RdyBusy());
SetSizeFT();
}
void MemRead( unsigned char *addr,char *buff, unsigned int len){
unsigned int x;
///CS = 0; //Select the chip
output_low(CS);
spi_write(0x0B); //Continuous Array Read
for( x=0; x<3; x++) //Send the Address (Page & Byte Start Address)
spi_write(*addr++);
spi_write(0xFF);
for( x=0; x<len; x++) //Read the Data In (Clock it)
*buff++ = spi_read();
///CS = 1; //DeSelect the Chip
output_high(CS);
}
void MemWrite( unsigned char *addr,char *buff, unsigned int len){
int x;
///CS = 0; //Select the chip
output_low(CS);
spi_write(0x84); //Buffer Write
for( x=0; x<3; x++) //Send the Address (Page & Byte Start Address)
spi_write(0x00);
for( x=0; x<len; x++) //Send the 4 Dont Care Bytes
spi_write(*buff++);
///CS = 1; //DeSelect the Chip
output_high(CS);
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
///CS = 0; //Select the chip
output_low(CS);
spi_write(0x83); //Buffer Write
for( x=0; x<3; x++) //Send the Address (Page & Byte Start Address)
spi_write(*addr++);
for( x=0; x<len; x++) //Send the 4 Dont Care Bytes
spi_write(*buff++);
////CS = 1; //DeSelect the Chip
output_high(CS);
}
int1 RdyBusy(void){
int wait=0;
output_low(CS);
spi_write(0xD7);
spi_write(0xD7);
wait = spi_read(0);
///CS = 1; //DeSelect the Chip
output_high(CS);
fprintf(PC,"wait=%i\n",wait); // PROBLEM HERE!! THE WAIT INTEGER ALWAYS RETURNS 0....
if(wait != 0)
return 0;
else
return 1;
}
void SetSizeFT(void){ //Five Twelve (512)
unsigned char stat;
///CS = 0; //Select the chip
output_low(CS);
spi_write(0x3D);
spi_write(0x2A);
spi_write(0x80);
spi_write(0xA6);
///CS = 1; //DeSelect the Chip
output_high(CS);
}
|
My circuit is similar to this
http://atomsoft.files.wordpress.com/2010/02/16mbitschem.jpg
However, I use 18f26k20 instead of the one shown in the picture.
Please help me figure out whats wrong with my program. Thanks. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Mar 02, 2010 5:35 pm |
|
|
This chip works in either SPI mode 0 or 3 (see chapter 3 of the datasheet). You are using mode 1.
For easier setup use the following defines: Code: | #define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) |
And then change the setup to: Code: | setup_spi(SPI_MASTER| SPI_MODE_0 |SPI_CLK_DIV_4); |
Another problem is that the spi_read() function only generates a clock when you add a parameter value. Change Code: | *buff++ = spi_read(); | to: Code: | *buff++ = spi_read(0); |
What is your compiler version number? |
|
|
x!nDy Guest
|
|
Posted: Tue Mar 02, 2010 9:17 pm |
|
|
Hello, thanks for the reply. I have done what you recommend but it still won't work...even in the part where I just want to get the status of the flash memory, it wont send back its status. My compiler version is PCH v.4.096. Please help. |
|
|
overmindx
Joined: 06 Oct 2008 Posts: 43
|
|
Posted: Tue Mar 02, 2010 10:17 pm |
|
|
Hello, using an oscilloscope, I checked the SO pin (PIN_C5). It seems the voltage spikes it generates are just a few mV. But when I changed
Code: |
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4)
|
to
Code: |
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64)
|
the voltage spikes became 2 volts. Is this a good enough voltage already for the flash memory to properly receive the command? Or am I missing something here? Please help. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|