Forums

Problems with SPI at LPC2294

Started by maxk...@web.de January 15, 2008
Hello together,
i want to save some parameters on the EEPROM (AT25080). This EEPROM is on the Basic Board of LPC2294. It controlled by SPI. The problem is that i don't receive any data from this memory. LPC2294 is working as a master. I can measure the clk, MOSI (Master out, Slave in), an chip select but there is nothing on MISO (Master in, Slave out). In the data register S0SPDR is always the value 0xFF.
I´ve read all the data sheets and manuals of the LPC2294 and the eeprom. Furthermore i have found many examples for similar projects with spi but they all didn`t work. Maybe someone can help me.

This is my code:

#include

#define SPIF (1<<7)
#define Add 0x00000000

int Mem_Read(unsigned long address)
{
char Wert;

IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)

S0SPDR = 0x00000003; //Send read operation code 0000 x011
while(!(S0SPSR&SPIF)); //Wait until done
//Wert = S0SPDR; //Receive data
S0SPDR = address; //Send address
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x00000000; //Dummy Byte
while(!(S0SPSR&SPIF)); //Wait until done

Wert = S0SPDR; //Receive data

IOSET0 = 0x00000400; //Chipselect High (High_disabled)

return Wert;
}

void Mem_Write(char Wert, unsigned long address)
{

IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)

S0SPDR = 0x00000006; //Send write enable 0000 x110
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x00000002; //Send write operation code 0000 x010
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = address; //Send address
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = Wert; //Send data
while(!(S0SPSR&SPIF)); //Wait until done

IOSET0 = 0x00000400; //Chipselect High (High_disabled)
}

void init_SPI()
{
PINSEL0 |= 0x00005500; //Configure SPI0 Pins
IODIR0 = 0x00000400; //Set P0.10 as output
IOSET0 = 0x00000400; //Chipselect High (High_disabled)

S0SPCR = 0x20; //CPHA=0, Mastermode, MSB first
S0SPCCR = 0x0C; //PCLK/S0SPCCR=SCK (12 for SCK = 1.25 MHz) > 8 and even

}

int main()
{
int stop=0;

init_SPI();
Mem_Write(88,Add); //Write 88 to address Add
stop=Mem_Read(Add); //Read from address Add

stop+=1;

}

Thanks in advance,
Max

An Engineer's Guide to the LPC2100 Series

Hi Max,
First, this device needs to toggle chip select for WREN command and
then for WRITE
command - so you must set CS low, send WREN, set CS high, again CS low
and then all process of writing. This is why I prefer SSP since this
process is done in a
hardware queue ....
After a write, you should wait for at least 5 ms as data sheet specify.
Only after
this time interval you can write another byte.
Note you can write many bytes in bursts - I am using this feature to
record words.
Now, about the waveform on oscilloscope: depends on processor's pin - if
you
need to be HI instead LOW, use a pull-up resistor - MISO is in 3-state and
the slave, after receiving a valid address outputs data specific to that
address -
it is the operating mode of SPI - while one byte is transferred from
master to the slave,
another one is transferred from slave to master.
Regards,
Ioan

maxkusnezow wrote:
>
> Hi Ioan,
>
> thank you a lot for your help. Now I can read from eeprom. I did it
> how you sugessted it. Now i receive the content of the addressed
> memory. Using an oscilloscope i am able to see the data on MISO.
> But now i have a problem with writing on the eeprom.
> It writes only if i do the following steps.
>
> 1. Step
> void Mem_Write(char value, unsigned long address)
> {
>
> IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
> <-------------------------- before write op code
>
> S0SPDR = 0x00000006; //Send write enable 0000 x110
> while(!(S0SPSR&SPIF)); //Wait until done
>
> S0SPDR = 0x00000002; //Send write operation code 0000 x010
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01; //Send address Byte 1
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01; //Send address Byte 2
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = value; //Send data
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> }
>
> 2. Step
> void Mem_Write(char value, unsigned long address)
> {
>
> S0SPDR = 0x00000006; //Send write enable 0000 x110
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
> <-------------------------- after write op code
>
> S0SPDR = 0x00000002; //Send write operation code 0000 x010
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01; //Send address Byte 1
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01; //Send address Byte 2
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = value; //Send data
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> }
>
> After second step it writes the value to the memory. On oscilloscope i
> see MOSI is logical low. only during transmitting data the individual
> bits are high.
> _ __
> for example: __________| |___| |_____________
>
> Have you any idea or an advice why it is so?
>
> Thanks in advance!
>
> Regards,
> Max
>
> --- In l... ,
> Petrescu wrote:
> >
> > Hi,
> > Be careful with memory organization of this device: it is 1K X 8 bits -
> > the address must be
> > always 16 bits(not a unsigned long !), so a reading sequence must be: 1
> > byte(opcode)+2bytes(address)+1byte(dummy)
> > to read a single byte. Using an oscilloscope, you must be able to see
> > only 32 SCK clock pulses for a reading (make a loop...)
> > I do not know LPC2294 in detail, but if it has a SPI1 like LPC2148,
> use
> > this, I found it more efficient.
> > Regards,
> > Ioan
> >
> > maxkusnezow@... wrote:
> > > Hello together,
> > > i want to save some parameters on the EEPROM (AT25080). This
> EEPROM is on the Basic Board of LPC2294. It controlled by SPI. The
> problem is that i don't receive any data from this memory. LPC2294 is
> working as a master. I can measure the clk, MOSI (Master out, Slave
> in), an chip select but there is nothing on MISO (Master in, Slave
> out). In the data register S0SPDR is always the value 0xFF.
> > > I´ve read all the data sheets and manuals of the LPC2294 and the
> eeprom. Furthermore i have found many examples for similar projects
> with spi but they all didn`t work. Maybe someone can help me.
> > >
> > > This is my code:
> > >
> > > #include
> > >
> > > #define SPIF (1<<7)
> > > #define Add 0x00000000
> > >
> > > int Mem_Read(unsigned long address)
> > > {
> > > char Wert;
> > >
> > > IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
> > >
> > > S0SPDR = 0x00000003; //Send read operation code 0000 x011
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > //Wert = S0SPDR; //Receive data
> > > S0SPDR = address; //Send address
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = 0x00000000; //Dummy Byte
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > >
> > > Wert = S0SPDR; //Receive data
> > >
> > > IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> > >
> > > return Wert;
> > > }
> > >
> > > void Mem_Write(char Wert, unsigned long address)
> > > {
> > >
> > > IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
> > >
> > > S0SPDR = 0x00000006; //Send write enable 0000 x110
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = 0x00000002; //Send write operation code 0000 x010
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = address; //Send address
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = Wert; //Send data
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > >
> > > IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> > > }
> > >
> > > void init_SPI()
> > > {
> > > PINSEL0 |= 0x00005500; //Configure SPI0 Pins
> > > IODIR0 = 0x00000400; //Set P0.10 as output
> > > IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> > >
> > > S0SPCR = 0x20; //CPHA=0, Mastermode, MSB first
> > > S0SPCCR = 0x0C; //PCLK/S0SPCCR=SCK (12 for SCK = 1.25 MHz) > 8 and
> even
> > >
> > > }
> > >
> > > int main()
> > > {
> > > int stop=0;
> > >
> > > init_SPI();
> > > Mem_Write(88,Add); //Write 88 to address Add
> > > stop=Mem_Read(Add); //Read from address Add
> > >
> > > stop+=1;
> > >
> > > }
> > >
> > > Thanks in advance,
> > > Max
> > >
> > >
> > >
> > >
Hi

Looking to your Step 1 routine, it should be enough
to write one single byte to the desired position.
Do you have a scope to check if the CS line goes high
on the SCL low-time of the last trnsmition bit? The
manual is pretty clear about this condition, or the
write cycle wont start.

" Programming will start
after the CS pin is brought high. (The LOW-to-High
transition of the CS pin must occur during
the SCK low-time immediately after clocking in the D0
(LSB) data bit. "

Also, its recommended to check the memorys status
register to ensure the write cicle has started (bit 0
== 1)and wait til it finished (bit0 == 0). Are you
doing this right after the Mem_Write function returns,
or are you trying to read right after trying to write?
The second step shouldnt work because you are
issuing the write enable command with the CS line
high, so it will be ignored by the eeprom.
Probably you are doing a read operation right after
the step2, so you are having the false ilusion it is
responsible for the writing to be succesfull. I think
when executing the step2, you give to the eeprom
enough time to finishes the write cycle, so you can
read the data you just wrote, but the step one is the
real responsible for the write to be performed. Try to
remove the step2 and put the read status register
routine instead, with a loop waiting for the bit0 to
be clear, and right after it try to read the data.

Regards

--- maxkusnezow escreveu:

> Hi Ioan,
>
> thank you a lot for your help. Now I can read from
> eeprom. I did it
> how you sugessted it. Now i receive the content of
> the addressed
> memory. Using an oscilloscope i am able to see the
> data on MISO.
> But now i have a problem with writing on the eeprom.
> It writes only if i do the following steps.
>
> 1. Step
> void Mem_Write(char value, unsigned long address)
> {
>
> IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
>
> <-------------------------- before write op code
>
> S0SPDR = 0x00000006; //Send write enable 0000 x110
> while(!(S0SPSR&SPIF)); //Wait until done
>
> S0SPDR = 0x00000002; //Send write operation code
> 0000 x010
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01;
> //Send address Byte 1
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01;
> //Send address Byte 2
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = value; //Send data
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOSET0 = 0x00000400; //Chipselect High
> (High_disabled)
> }
>
> 2. Step
> void Mem_Write(char value, unsigned long address)
> {
>
> S0SPDR = 0x00000006; //Send write enable 0000 x110
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
>
> <-------------------------- after write op code
>
> S0SPDR = 0x00000002; //Send write operation code
> 0000 x010
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01;
> //Send address Byte 1
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x01;
> //Send address Byte 2
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = value; //Send data
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOSET0 = 0x00000400; //Chipselect High
> (High_disabled)
> }
>
> After second step it writes the value to the memory.
> On oscilloscope i
> see MOSI is logical low. only during transmitting
> data the individual
> bits are high.
> _ __
> for example: __________| |___| |_____________
>
> Have you any idea or an advice why it is so?
>
> Thanks in advance!
>
> Regards,
> Max
>
> --- In l..., Petrescu
> wrote:
> >
> > Hi,
> > Be careful with memory organization of this
> device: it is 1K X 8 bits -
> > the address must be
> > always 16 bits(not a unsigned long !), so a
> reading sequence must be: 1
> > byte(opcode)+2bytes(address)+1byte(dummy)
> > to read a single byte. Using an oscilloscope, you
> must be able to see
> > only 32 SCK clock pulses for a reading (make a
> loop...)
> > I do not know LPC2294 in detail, but if it has a
> SPI1 like LPC2148,
> use
> > this, I found it more efficient.
> > Regards,
> > Ioan
> >
> > maxkusnezow@... wrote:
> > > Hello together,
> > > i want to save some parameters on the EEPROM
> (AT25080). This
> EEPROM is on the Basic Board of LPC2294. It
> controlled by SPI. The
> problem is that i don't receive any data from this
> memory. LPC2294 is
> working as a master. I can measure the clk, MOSI
> (Master out, Slave
> in), an chip select but there is nothing on MISO
> (Master in, Slave
> out). In the data register S0SPDR is always the
> value 0xFF.
> > > I´ve read all the data sheets and manuals of
> the LPC2294 and the
> eeprom. Furthermore i have found many examples for
> similar projects
> with spi but they all didn`t work. Maybe someone can
> help me.
> > >
> > > This is my code:
> > >
> > > #include
> > >
> > > #define SPIF (1<<7)
> > > #define Add 0x00000000
> > >
> > > int Mem_Read(unsigned long address)
> > > {
> > > char Wert;
> > >
> > > IOCLR0 = 0x00000400; //Chipselect low
> (Low_enabled)
> > >
> > > S0SPDR = 0x00000003; //Send read operation code
> 0000 x011
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > //Wert = S0SPDR; //Receive data
> > > S0SPDR = address; //Send address
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = 0x00000000; //Dummy Byte
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > >
> > > Wert = S0SPDR; //Receive data
> > >
> > > IOSET0 = 0x00000400; //Chipselect High
> (High_disabled)
> > >
> > > return Wert;
> > > }
> > >
> > > void Mem_Write(char Wert, unsigned long address)
> > > {
> > >
> > > IOCLR0 = 0x00000400; //Chipselect low
> (Low_enabled)
> > >
> > > S0SPDR = 0x00000006; //Send write enable 0000
> x110
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = 0x00000002; //Send write operation code
> 0000 x010
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = address; //Send address
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > > S0SPDR = Wert; //Send data
> > > while(!(S0SPSR&SPIF)); //Wait until done
> > >
> > > IOSET0 = 0x00000400; //Chipselect High
> (High_disabled)
> > > }
> > >
> > > void init_SPI()
> > > {
> > > PINSEL0 |= 0x00005500; //Configure SPI0 Pins
> > > IODIR0 = 0x00000400; //Set P0.10 as output
> > > IOSET0 = 0x00000400; //Chipselect High
> (High_disabled)
> > >
> > > S0SPCR = 0x20; //CPHA=0, Mastermode, MSB first
> > > S0SPCCR = 0x0C; //PCLK/S0SPCCR=SCK (12 for SCK > 1.25 MHz) > 8 and
> even
> > >
> > > }
> > >
> > > int main()
> > > {
> > > int stop=0;
> > >
> > > init_SPI();
> > > Mem_Write(88,Add); //Write 88 to address Add
> > > stop=Mem_Read(Add); //Read from address Add
> > >
> > > stop+=1;
> > >
> > > }
> > >
> > > Thanks in advance,
>
=== message truncated ==
Abra sua conta no Yahoo! Mail, o ico sem limite de espa para armazenamento!
http://br.mail.yahoo.com/
--- Petrescu escreveu:

> First, this device needs to toggle chip select for
> WREN command and
> then for WRITE
> command - so you must set CS low, send WREN, set
> CS high, again CS low
> and then all process of writing.

The memory datasheet is very obscure about this.

Abra sua conta no Yahoo! Mail, o ico sem limite de espa para armazenamento!
http://br.mail.yahoo.com/
Hi,
From Atmel's data sheet, page 10:
WRITE SEQUENCE (WRITE): In order to program the AT25080A/160A/320A/640A,
two separate
instructions must be executed. First, the device must be write enabled
via the WREN
instruction. Then a write (WRITE) instruction may be executed. Also, the
address of the memory
location(s) to be programmed must be outside the protected address field
location
selected by the block write protection level. During an internal write
cycle, all commands will
be ignored except the RDSR instruction.
A write instruction requires the following sequence. After the CS line
is pulled low to select the
device, the WRITE op-code is transmitted via the SI line followed by the
byte address (A15
A0) and the data (D7D0) to be programmed (see Table 10). Programming
will start after the
CS pin is brought high. The low-to-high transition of the CS pin must
occur during the SCK
low-time immediately after clocking in the D0 (LSB) data bit.
The READY/BUSY status of the device can be determined by initiating a
read status register
Ioan

Alexandre Kremer wrote:
> --- Petrescu > escreveu:
>
> > First, this device needs to toggle chip select for
> > WREN command and
> > then for WRITE
> > command - so you must set CS low, send WREN, set
> > CS high, again CS low
> > and then all process of writing.
>
> The memory datasheet is very obscure about this.
>
> Abra sua conta no Yahoo! Mail, o ico sem limite de espa para
> armazenamento!
> http://br.mail.yahoo.com/
Hi Ioan,

thank you a lot for your help. Now I can read from eeprom. I did it
how you sugessted it. Now i receive the content of the addressed
memory. Using an oscilloscope i am able to see the data on MISO.
But now i have a problem with writing on the eeprom.
It writes only if i do the following steps.

1. Step
void Mem_Write(char value, unsigned long address)
{

IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
<-------------------------- before write op code

S0SPDR = 0x00000006; //Send write enable 0000 x110
while(!(S0SPSR&SPIF)); //Wait until done

S0SPDR = 0x00000002; //Send write operation code 0000 x010
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x01; //Send address Byte 1
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x01; //Send address Byte 2
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = value; //Send data
while(!(S0SPSR&SPIF)); //Wait until done

IOSET0 = 0x00000400; //Chipselect High (High_disabled)
}

2. Step
void Mem_Write(char value, unsigned long address)
{

S0SPDR = 0x00000006; //Send write enable 0000 x110
while(!(S0SPSR&SPIF)); //Wait until done

IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
<-------------------------- after write op code

S0SPDR = 0x00000002; //Send write operation code 0000 x010
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x01; //Send address Byte 1
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x01; //Send address Byte 2
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = value; //Send data
while(!(S0SPSR&SPIF)); //Wait until done

IOSET0 = 0x00000400; //Chipselect High (High_disabled)
}

After second step it writes the value to the memory. On oscilloscope i
see MOSI is logical low. only during transmitting data the individual
bits are high.
_ __
for example: __________| |___| |_____________

Have you any idea or an advice why it is so?

Thanks in advance!

Regards,
Max

--- In l..., Petrescu wrote:
>
> Hi,
> Be careful with memory organization of this device: it is 1K X 8 bits -
> the address must be
> always 16 bits(not a unsigned long !), so a reading sequence must be: 1
> byte(opcode)+2bytes(address)+1byte(dummy)
> to read a single byte. Using an oscilloscope, you must be able to see
> only 32 SCK clock pulses for a reading (make a loop...)
> I do not know LPC2294 in detail, but if it has a SPI1 like LPC2148,
use
> this, I found it more efficient.
> Regards,
> Ioan
>
> maxkusnezow@... wrote:
> > Hello together,
> > i want to save some parameters on the EEPROM (AT25080). This
EEPROM is on the Basic Board of LPC2294. It controlled by SPI. The
problem is that i don't receive any data from this memory. LPC2294 is
working as a master. I can measure the clk, MOSI (Master out, Slave
in), an chip select but there is nothing on MISO (Master in, Slave
out). In the data register S0SPDR is always the value 0xFF.
> > I´ve read all the data sheets and manuals of the LPC2294 and the
eeprom. Furthermore i have found many examples for similar projects
with spi but they all didn`t work. Maybe someone can help me.
> >
> > This is my code:
> >
> > #include
> >
> > #define SPIF (1<<7)
> > #define Add 0x00000000
> >
> > int Mem_Read(unsigned long address)
> > {
> > char Wert;
> >
> > IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
> >
> > S0SPDR = 0x00000003; //Send read operation code 0000 x011
> > while(!(S0SPSR&SPIF)); //Wait until done
> > //Wert = S0SPDR; //Receive data
> > S0SPDR = address; //Send address
> > while(!(S0SPSR&SPIF)); //Wait until done
> > S0SPDR = 0x00000000; //Dummy Byte
> > while(!(S0SPSR&SPIF)); //Wait until done
> >
> > Wert = S0SPDR; //Receive data
> >
> > IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> >
> > return Wert;
> > }
> >
> > void Mem_Write(char Wert, unsigned long address)
> > {
> >
> > IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
> >
> > S0SPDR = 0x00000006; //Send write enable 0000 x110
> > while(!(S0SPSR&SPIF)); //Wait until done
> > S0SPDR = 0x00000002; //Send write operation code 0000 x010
> > while(!(S0SPSR&SPIF)); //Wait until done
> > S0SPDR = address; //Send address
> > while(!(S0SPSR&SPIF)); //Wait until done
> > S0SPDR = Wert; //Send data
> > while(!(S0SPSR&SPIF)); //Wait until done
> >
> > IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> > }
> >
> > void init_SPI()
> > {
> > PINSEL0 |= 0x00005500; //Configure SPI0 Pins
> > IODIR0 = 0x00000400; //Set P0.10 as output
> > IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> >
> > S0SPCR = 0x20; //CPHA=0, Mastermode, MSB first
> > S0SPCCR = 0x0C; //PCLK/S0SPCCR=SCK (12 for SCK = 1.25 MHz) > 8 and
even
> >
> > }
> >
> > int main()
> > {
> > int stop=0;
> >
> > init_SPI();
> > Mem_Write(88,Add); //Write 88 to address Add
> > stop=Mem_Read(Add); //Read from address Add
> >
> > stop+=1;
> >
> > }
> >
> > Thanks in advance,
> > Max
> >
> >
> >
> >
I think if you review the datasheet, you will see that you need two
separate sequences for first enabling the write operation and then
writing the data.

Each sequence is framed by CS' first going low and then going high.
You are trying to short circuit the framing by only selecting the
device once. That's also why it takes two sequences to get it to work.

See the 2d paragaph on page 8 of this datasheet which, in the final
sentence, states that all instructions start with a high-to-low CS
transition : http://www.ortodoxism.ro/datasheets/atmel/doc0675.pdf

Richard
Hi

Yes, ive read that before and understood it. What i
meant is that it could have a note or something on
that write operation description informing about
toggling the CS is needed between WREN and the write
sequence, or the programmer will try to optimize his
code by removing this need and trying to write bytes
just by queueing instructions. I know the waveforms on
further pages give an absolute idea of each operation,
but every user is a different case and the more clear
is the document, the less errors will be done. I think
it would help to avoid cases like that, from the
original poster.

Regards

--- Petrescu escreveu:

> Hi,
> From Atmel's data sheet, page 10:
> WRITE SEQUENCE (WRITE): In order to program the
> AT25080A/160A/320A/640A,
> two separate
> instructions must be executed. First, the device
> must be write enabled
> via the WREN
> instruction. Then a write (WRITE) instruction may be
> executed. Also, the
> address of the memory
> location(s) to be programmed must be outside the
> protected address field
> location
> selected by the block write protection level. During
> an internal write
> cycle, all commands will
> be ignored except the RDSR instruction.
> A write instruction requires the following sequence.
> After the CS line
> is pulled low to select the
> device, the WRITE op-code is transmitted via the SI
> line followed by the
> byte address (A15
> A0) and the data (D7D0) to be programmed (see Table
> 10). Programming
> will start after the
> CS pin is brought high. The low-to-high transition
> of the CS pin must
> occur during the SCK
> low-time immediately after clocking in the D0 (LSB)
> data bit.
> The READY/BUSY status of the device can be
> determined by initiating a
> read status register
> Ioan
>
> Alexandre Kremer wrote:
> >
> >
> > --- Petrescu > > escreveu:
> >
> > > First, this device needs to toggle chip select
> for
> > > WREN command and
> > > then for WRITE
> > > command - so you must set CS low, send WREN, set
> > > CS high, again CS low
> > > and then all process of writing.
> >
> > The memory datasheet is very obscure about this.
> >
> > Abra sua conta no Yahoo! Mail, o ico sem limite
> de espa para
> > armazenamento!
> > http://br.mail.yahoo.com/
>
> >
> >
>
>
Hi at all,
i want to thank you very much for your help. Now i can write/read data
to/from certain address on the eeprom. My mistakes were:
1. I have to put CS low, send operation code for write enable and then
put CS high. After that i have to put CS low again, send op. code for
write operation, send 2 bytes address, send data (1 byte) and then put
CS high to end the whole write operation.
2. Furthermore it is necessary to wait for eeprom advice while it is
busy. For that i have to read status register of the advice,
especially bit0. bit0==1 -> advice busy, bit0==0 -> advice ready. You
cant read until bit0 is cleared (ready).
I will post the whole code. Perhaps this will help others with a
similar problem.

Thanks again!

Regards,
Max

#include

#define SPIF (1<<7)

int Mem_Read(short int address)
{
char data=0;
char add_byte1, add_byte2;
add_byte1=(address>>8)&0xFF;
add_byte2=address&0xFF;

IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
S0SPDR = 0x00000003; //Send read operation code 0000 x011
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = add_byte1; //Send address
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = add_byte2; //Send address
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x00000000; //Dummy Byte
while(!(S0SPSR&SPIF)); //Wait until done
data = S0SPDR; //Receive data
IOSET0 = 0x00000400; //Chipselect High (High_disabled)
return data;
}

void Mem_Write(char value, short int address)
{
char add_byte1, add_byte2;
add_byte1=(address>>8)&0xFF;
add_byte2=address&0xFF;

IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
S0SPDR = 0x00000006; //Send write enable 0000 x110
while(!(S0SPSR&SPIF)); //Wait until done
IOSET0 = 0x00000400; //Chipselect High (High_disabled)
IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
S0SPDR = 0x00000002; //Send write operation code 0000 x010
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = add_byte1; //Send address
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = add_byte2; //Send address
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = value; //Send data
while(!(S0SPSR&SPIF)); //Wait until done
IOSET0 = 0x00000400; //Chipselect High (High_disabled)
}

void Status_Read()
{
char value=0;
do{
IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
S0SPDR = 0x00000005; //Send operation code 0000 x101 (Read
Status Register)
while(!(S0SPSR&SPIF)); //Wait until done
S0SPDR = 0x00000000; //Dummy Byte
while(!(S0SPSR&SPIF)); //Wait until done
value = S0SPDR; //Receive data
IOSET0 = 0x00000400; //Chipselect High (High_disabled)
}while(value&0x01); //wait while bit0==1
}

void init_SPI()
{
PINSEL0 |= 0x00005500; //Configure SPI0 Pins
IODIR0 = 0x00000400; //Set P0.10 as output
IOSET0 = 0x00000400; //Chipselect High (High_disabled)
S0SPCR = 0x20; //CPHA=0, Mastermode, MSB first
S0SPCCR = 0x0C; //PCLK/S0SPCCR=SCK (12 for SCK = 1,25 MHz) have to
be > 8 and even
}

int main()
{
int value=0;
init_SPI(); //Init SPI
Mem_Write(123,0x0000); //Write 123 to address 0x0000
Status_Read(); //Wait while eeprom busy
value=Mem_Read(0x0000); //Read from address 0x0000
return 0;
}



Hi,
Be careful with memory organization of this device: it is 1K X 8 bits -
the address must be
always 16 bits(not a unsigned long !), so a reading sequence must be: 1
byte(opcode)+2bytes(address)+1byte(dummy)
to read a single byte. Using an oscilloscope, you must be able to see
only 32 SCK clock pulses for a reading (make a loop...)
I do not know LPC2294 in detail, but if it has a SPI1 like LPC2148, use
this, I found it more efficient.
Regards,
Ioan

m...@web.de wrote:
> Hello together,
> i want to save some parameters on the EEPROM (AT25080). This EEPROM is on the Basic Board of LPC2294. It controlled by SPI. The problem is that i don't receive any data from this memory. LPC2294 is working as a master. I can measure the clk, MOSI (Master out, Slave in), an chip select but there is nothing on MISO (Master in, Slave out). In the data register S0SPDR is always the value 0xFF.
> I´ve read all the data sheets and manuals of the LPC2294 and the eeprom. Furthermore i have found many examples for similar projects with spi but they all didn`t work. Maybe someone can help me.
>
> This is my code:
>
> #include #define SPIF (1<<7)
> #define Add 0x00000000
>
> int Mem_Read(unsigned long address)
> {
> char Wert;
>
> IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
>
> S0SPDR = 0x00000003; //Send read operation code 0000 x011
> while(!(S0SPSR&SPIF)); //Wait until done
> //Wert = S0SPDR; //Receive data
> S0SPDR = address; //Send address
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x00000000; //Dummy Byte
> while(!(S0SPSR&SPIF)); //Wait until done
>
> Wert = S0SPDR; //Receive data
>
> IOSET0 = 0x00000400; //Chipselect High (High_disabled)
>
> return Wert;
> }
>
> void Mem_Write(char Wert, unsigned long address)
> {
>
> IOCLR0 = 0x00000400; //Chipselect low (Low_enabled)
>
> S0SPDR = 0x00000006; //Send write enable 0000 x110
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = 0x00000002; //Send write operation code 0000 x010
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = address; //Send address
> while(!(S0SPSR&SPIF)); //Wait until done
> S0SPDR = Wert; //Send data
> while(!(S0SPSR&SPIF)); //Wait until done
>
> IOSET0 = 0x00000400; //Chipselect High (High_disabled)
> }
>
> void init_SPI()
> {
> PINSEL0 |= 0x00005500; //Configure SPI0 Pins
> IODIR0 = 0x00000400; //Set P0.10 as output
> IOSET0 = 0x00000400; //Chipselect High (High_disabled)
>
> S0SPCR = 0x20; //CPHA=0, Mastermode, MSB first
> S0SPCCR = 0x0C; //PCLK/S0SPCCR=SCK (12 for SCK = 1.25 MHz) > 8 and even
>
> }
>
> int main()
> {
> int stop=0;
>
> init_SPI();
> Mem_Write(88,Add); //Write 88 to address Add
> stop=Mem_Read(Add); //Read from address Add
>
> stop+=1;
>
> }
>
> Thanks in advance,
> Max
>
>