Annoying Problem With SPI interface to Atmel Dataflash

Started by gogotimmo May 18, 2006
Hi-

I am having probles with the LP32138 SSP (SPI) interface to an Atmel
dataflash (AT45DB161). I believe it has to do with the chip select
implementation. To read the status register of the Atmel dataflash,
for example, the device requires an opcode 'write' followed by
a 'read'. The write works fine, but the 'read' fails. I believe it is
failing because the chip select gets deasserted between the read and
write, thereby resetting the internal state machine of the data flash.
The datasheet of the atmel memory has timing diagrams that show the CS
asserted throughout the entire transfer with no transitions between
frames. Actually, it looks like the LPC2138 spi chip select gets
deasserted between each frame in a continuous transfer. If true, this
bites. The only workaround I can think of is to use a GPIO pin to
drive the CS manually. Since I'm already out of pins, this isn't a
great option for me. I thought of tricking the SPI peripheral by
sending an 8-bit opcode justified in a 16-bit frame, which would
probably work, but will fail when reading an array of memory
addresses. These Atmel dataflash devices are extremely popular, so
someone must have had similar issues.

Also, I don't mean to sound rude, but I have already looked at the SPI
code examples.

Any help is appreciated-
Thanks-
Tim

An Engineer's Guide to the LPC2100 Series

I think the basic problem is that the LPC213x SPI can only handle 8-
to 16-bit transfers, and the Atmel device requires longer ones.

A simple way around this is to "bit-bang" the interface (i.e. use
all pins as GPIO and drive them all in software). This is easy
enough to do for SPI interfaces. Performance might take a bit of a
hit, and you have to watch how interrupts may interfere with timing.

Brendan

--- In l..., "gogotimmo" wrote:
>
> Hi-
>
> I am having probles with the LP32138 SSP (SPI) interface to an
Atmel
> dataflash (AT45DB161). I believe it has to do with the chip select
> implementation. To read the status register of the Atmel
dataflash,
> for example, the device requires an opcode 'write' followed by
> a 'read'. The write works fine, but the 'read' fails. I believe it
is
> failing because the chip select gets deasserted between the read
and
> write, thereby resetting the internal state machine of the data
flash.
> The datasheet of the atmel memory has timing diagrams that show
the CS
> asserted throughout the entire transfer with no transitions
between
> frames. Actually, it looks like the LPC2138 spi chip select gets
> deasserted between each frame in a continuous transfer. If true,
this
> bites. The only workaround I can think of is to use a GPIO pin to
> drive the CS manually. Since I'm already out of pins, this isn't a
> great option for me. I thought of tricking the SPI peripheral by
> sending an 8-bit opcode justified in a 16-bit frame, which would
> probably work, but will fail when reading an array of memory
> addresses. These Atmel dataflash devices are extremely popular, so
> someone must have had similar issues.
>
> Also, I don't mean to sound rude, but I have already looked at the
SPI
> code examples.
>
> Any help is appreciated-
> Thanks-
> Tim
>

hi

I have working code for the AT45DB021, so i think its similar as for the one you use.

You have to do the chip select yourself, and to read , you need to perform a dummy write

this is the code i use to read the status of the 45DB021 connected to LPC2103,
/************************************************
* Read chip status *
*************************************************/
byte readstatus(void)
{
byte status;

//begin CS=0
FIO0MASK0=0x7f;
FIO0PIN0=0;

//send command
S0SPDR=READSTATUS;
//wait until sent
while((S0SPSR & 0x80)==0);

// send dummy byte
S0SPDR=0;

//wait until sent
while((S0SPSR & 0x80)==0);

//read data
status=S0SPDR;

//end CS=1
FIO0MASK0=0x7f;
FIO0PIN0=0x80;
return status ;
}
Be sure to init the SPI correctly (clock rate & polarity )

// init SPI mem interface
S0SPCR=0x0824;
S0SPCCR=0x1e; // clock 15mhz/30
Regards, Johan

----- Original Message -----
From: gogotimmo
To: l...
Sent: Thursday, May 18, 2006 6:24 AM
Subject: [lpc2000] Annoying Problem With SPI interface to Atmel Dataflash
Hi-

I am having probles with the LP32138 SSP (SPI) interface to an Atmel
dataflash (AT45DB161). I believe it has to do with the chip select
implementation. To read the status register of the Atmel dataflash,
for example, the device requires an opcode 'write' followed by
a 'read'. The write works fine, but the 'read' fails. I believe it is
failing because the chip select gets deasserted between the read and
write, thereby resetting the internal state machine of the data flash.
The datasheet of the atmel memory has timing diagrams that show the CS
asserted throughout the entire transfer with no transitions between
frames. Actually, it looks like the LPC2138 spi chip select gets
deasserted between each frame in a continuous transfer. If true, this
bites. The only workaround I can think of is to use a GPIO pin to
drive the CS manually. Since I'm already out of pins, this isn't a
great option for me. I thought of tricking the SPI peripheral by
sending an 8-bit opcode justified in a 16-bit frame, which would
probably work, but will fail when reading an array of memory
addresses. These Atmel dataflash devices are extremely popular, so
someone must have had similar issues.

Also, I don't mean to sound rude, but I have already looked at the SPI
code examples.

Any help is appreciated-
Thanks-
Tim

------
brendan
>I think the basic problem is that the LPC213x SPI can only handle 8-
>to 16-bit transfers, and the Atmel device requires longer ones.

I don't know of any SPI which makes longer frames than 16bit.
If you need more you have to send more frames.

Only if the CS is really deasserted between frames you need to tweak
the CS.
(BTW: The SAMs have the problem the otherway round, for DMA transfers
they do not deassert CS which some chips need.)

> A simple way around this is to "bit-bang" the interface (i.e. use
> all pins as GPIO and drive them all in software). This is easy
> enough to do for SPI interfaces. Performance might take a bit of a
> hit, and you have to watch how interrupts may interfere with timing.

A bit overkill. Using IO for CS would be enough.
Esp. if it you go for highvolume like with a dataflash.

--
42Bastian




--- In l..., 42Bastian Schick wrote:
>
> brendan
> >I think the basic problem is that the LPC213x SPI can only handle
8-
> >to 16-bit transfers, and the Atmel device requires longer ones.
>
> I don't know of any SPI which makes longer frames than 16bit.
> If you need more you have to send more frames.
>
> Only if the CS is really deasserted between frames you need to tweak
> the CS.

I guess it depends on what you call a "frame" or "transfer": I'd use
the term to describe the transfer of a set of bits framed by some
signal (in this case CS). I don't know the Atmel device specifically,
but it sounds like it's transferring more than 16-bits at a time.

I'd agree it's best to try and use the SPI peripheral if you can: you
clearly need to be careful though with polarity and timing of a GPIO
CS. By the way, does anyone know if you can use SSEL as GPIO whilst
using the other SPI pins as peripheral pins? if you can't you'd need
an extra pin, which aparently is not an option in this case.

Brendan

you should check the CPHA of the atmel chip in read and write mode.
Sometimes you have to change the CPHA of your LPC chip btw read and writes
dynamically.
----- Original Message -----
From: "gogotimmo"
To:
Sent: Thursday, May 18, 2006 7:24 AM
Subject: [lpc2000] Annoying Problem With SPI interface to Atmel Dataflash
> Hi-
>
> I am having probles with the LP32138 SSP (SPI) interface to an Atmel
> dataflash (AT45DB161). I believe it has to do with the chip select
> implementation. To read the status register of the Atmel dataflash,
> for example, the device requires an opcode 'write' followed by
> a 'read'. The write works fine, but the 'read' fails. I believe it is
> failing because the chip select gets deasserted between the read and
> write, thereby resetting the internal state machine of the data flash.
> The datasheet of the atmel memory has timing diagrams that show the CS
> asserted throughout the entire transfer with no transitions between
> frames. Actually, it looks like the LPC2138 spi chip select gets
> deasserted between each frame in a continuous transfer. If true, this
> bites. The only workaround I can think of is to use a GPIO pin to
> drive the CS manually. Since I'm already out of pins, this isn't a
> great option for me. I thought of tricking the SPI peripheral by
> sending an 8-bit opcode justified in a 16-bit frame, which would
> probably work, but will fail when reading an array of memory
> addresses. These Atmel dataflash devices are extremely popular, so
> someone must have had similar issues.
>
> Also, I don't mean to sound rude, but I have already looked at the SPI
> code examples.
>
> Any help is appreciated-
> Thanks-
> Tim
At 08:40 18.05.2006 +0000, you wrote:
>--- In l..., 42Bastian Schick wrote:
> >
> > brendan
> > >I think the basic problem is that the LPC213x SPI can only handle
>8-
> > >to 16-bit transfers, and the Atmel device requires longer ones.
> >
> > I don't know of any SPI which makes longer frames than 16bit.
> > If you need more you have to send more frames.
> >
> > Only if the CS is really deasserted between frames you need to tweak
> > the CS.
>
>I guess it depends on what you call a "frame" or "transfer": I'd use
>the term to describe the transfer of a set of bits framed by some
>signal (in this case CS). I don't know the Atmel device specifically,
>but it sounds like it's transferring more than 16-bits at a time.
>
>I'd agree it's best to try and use the SPI peripheral if you can: you
>clearly need to be careful though with polarity and timing of a GPIO
>CS. By the way, does anyone know if you can use SSEL as GPIO whilst
>using the other SPI pins as peripheral pins? if you can't you'd need
>an extra pin, which aparently is not an option in this case.

As far as I know (but I'm not the expert) the newer LPCs can use SSEL as
GPIO when using the SPI as an master only, older chips like the LPC2106
need this pin tied to high via a resistor.

Regards
Herbert
>Brendan
>
>SPONSORED LINKS
>Microcontrollers
>Microprocessor
>Intel
>microprocessors
>----------
>>Yahoo! Terms of Service.
>----------


brendan

>> Only if the CS is really deasserted between frames you need to tweak
>> the CS.
>
> I guess it depends on what you call a "frame" or "transfer": I'd use
> the term to describe the transfer of a set of bits framed by some
> signal (in this case CS).

Correct. I think this should be the definition.

>I don't know the Atmel device specifically,
> but it sounds like it's transferring more than 16-bits at a time.

You can up to the full size of the chip without deasserting CS.
But a single transfer is 8bits.

--
42Bastian
Hello,
I have interfaced Atmel at45db081 thro SPI interface with
LPC2148 and my code is as follows.

As per your postings for reading the status i have used a dummy
write and i could read some value like 0xd2 0x52 from the status
register of ATMEL flash.
But while trying to write some data and reading the same i am not
getting the correct value insted i am getting FF's.
Is the dummy write required only for status read or is it for data
read also.
PCONP |= 0x00000100;
PINSEL0 |= 0x00001500;
//SPI0 setup
S0SPCCR = 0x3C; //prescaler` => SPI clock = 1MHz
S0SPCR = 0x0020; //no SPI int,MSB
first,Master,CPOL=0,CPHA=0,8-bit data
dummy = S0SPSR; //read status register
dummy = S0SPDR;

void tx(unsigned char data)
{

S0SPSR=0;
S0SPDR = data;
while((S0SPSR&0x80)==0x00);

}

unsigned char rx(void)
{

char status;
status = S0SPSR;
return(S0SPDR);
}

void spi_bufwr()
{
// unsigned char src_str[7]={0x41,0x42,0x43,0x44,0x45,0x46,0};

ssel_l(); // Slave select->low
delay(1000);
tx(bufwr); // insert WRITE instruction

tx(0x00); //Afet cmd Zero is sent

tx(0x00);// write the high_byte of the adr

tx(0x50);// write the low_byte of the adr

ch_cnt=0 ;

tx(0x35);

ssel_h();
}
void spi_bufrd()
{
unsigned char temp=0;
//unsigned char dst_str[6];
ssel_l(); // SLAVE select->LOW
delay(100);

tx(bufrd); // insert Readinstruction
tx(0x00);
tx(0x00);// write the high_byte of the adr
tx(0x50); // write the low_byte of the adr

tx(0x00);

ch_cnt=0 ;
//rx();

temp=rx();
ch_cnt++ ;
delay(100);
ssel_h();

printf("\n%x\n",temp);
}

//////////////////////////////////////////////////////////////////

--- In l..., "Sagaert Johan"
wrote:
>
> hi
>
> I have working code for the AT45DB021, so i think its similar as
for the one you use.
>
> You have to do the chip select yourself, and to read , you need to
perform a dummy write
>
> this is the code i use to read the status of the 45DB021 connected
to LPC2103,
> /************************************************
> * Read chip status *
> *************************************************/
> byte readstatus(void)
> {
> byte status;
>
> //begin CS=0
> FIO0MASK0=0x7f;
> FIO0PIN0=0;
>
> //send command
> S0SPDR=READSTATUS;
> //wait until sent
> while((S0SPSR & 0x80)==0);
>
> // send dummy byte
> S0SPDR=0;
>
> //wait until sent
> while((S0SPSR & 0x80)==0);
>
> //read data
> status=S0SPDR;
>
> //end CS=1
> FIO0MASK0=0x7f;
> FIO0PIN0=0x80;
> return status ;
> }
> Be sure to init the SPI correctly (clock rate & polarity )
>
> // init SPI mem interface
> S0SPCR=0x0824;
> S0SPCCR=0x1e; // clock 15mhz/30
> Regards, Johan
>
> ----- Original Message -----
> From: gogotimmo
> To: l...
> Sent: Thursday, May 18, 2006 6:24 AM
> Subject: [lpc2000] Annoying Problem With SPI interface to Atmel
Dataflash
> Hi-
>
> I am having probles with the LP32138 SSP (SPI) interface to an
Atmel
> dataflash (AT45DB161). I believe it has to do with the chip
select
> implementation. To read the status register of the Atmel
dataflash,
> for example, the device requires an opcode 'write' followed by
> a 'read'. The write works fine, but the 'read' fails. I believe
it is
> failing because the chip select gets deasserted between the read
and
> write, thereby resetting the internal state machine of the data
flash.
> The datasheet of the atmel memory has timing diagrams that show
the CS
> asserted throughout the entire transfer with no transitions
between
> frames. Actually, it looks like the LPC2138 spi chip select
gets
> deasserted between each frame in a continuous transfer. If true,
this
> bites. The only workaround I can think of is to use a GPIO pin
to
> drive the CS manually. Since I'm already out of pins, this isn't
a
> great option for me. I thought of tricking the SPI peripheral by
> sending an 8-bit opcode justified in a 16-bit frame, which would
> probably work, but will fail when reading an array of memory
> addresses. These Atmel dataflash devices are extremely popular,
so
> someone must have had similar issues.
>
> Also, I don't mean to sound rude, but I have already looked at
the SPI
> code examples.
>
> Any help is appreciated-
> Thanks-
> Tim
>
> -------------------------------
-----------
>
study such codes associated with LPC 2xxx

Tryout something with Swamiji.... Add to your CV make it stronger...

NATARAJAN
--- On Thu, 11/6/08, venkat_oct10 wrote:

From: venkat_oct10
Subject: [lpc2000] Re: Annoying Problem With SPI interface to Atmel Dataflash
To: l...
Date: Thursday, November 6, 2008, 6:49 PM

Hello,
I have interfaced Atmel at45db081 thro SPI interface with
LPC2148 and my code is as follows.

As per your postings for reading the status i have used a dummy
write and i could read some value like 0xd2 0x52 from the status
register of ATMEL flash.
But while trying to write some data and reading the same i am not
getting the correct value insted i am getting FF's.
Is the dummy write required only for status read or is it for data
read also.

PCONP |= 0x00000100;
PINSEL0 |= 0x00001500;
//SPI0 setup
S0SPCCR = 0x3C; //prescaler= 60 => SPI clock = 1MHz
S0SPCR = 0x0020; //no SPI int,MSB
first,Master, CPOL=0,CPHA= 0,8-bit data
dummy = S0SPSR; //read status register
dummy = S0SPDR;

void tx(unsigned char data)
{

S0SPSR=0;
S0SPDR = data;
while((S0SPSR& 0x80)==0x00) ;

}

unsigned char rx(void)
{

char status;
status = S0SPSR;
return(S0SPDR) ;
}

void spi_bufwr()
{
// unsigned char src_str[7]={ 0x41,0x42, 0x43,0x44, 0x45,0x46, 0};

ssel_l(); // Slave select->low
delay(1000);
tx(bufwr); // insert WRITE instruction

tx(0x00); //Afet cmd Zero is sent

tx(0x00);// write the high_byte of the adr

tx(0x50);// write the low_byte of the adr

ch_cnt=0 ;

tx(0x35);

ssel_h();
}

void spi_bufrd()
{
unsigned char temp=0;
//unsigned char dst_str[6];
ssel_l(); // SLAVE select->LOW
delay(100);

tx(bufrd); // insert Readinstruction
tx(0x00);
tx(0x00);// write the high_byte of the adr
tx(0x50); // write the low_byte of the adr

tx(0x00);

ch_cnt=0 ;
//rx();

temp=rx();
ch_cnt++ ;
delay(100);
ssel_h();

printf("\n%x\ n",temp);
}

//////////// ///////// ///////// ///////// ///////// ///////// /////////

--- In lpc2000@yahoogroups .com, "Sagaert Johan"
wrote:
>
> hi
>
> I have working code for the AT45DB021, so i think its similar as
for the one you use.
>
> You have to do the chip select yourself, and to read , you need to
perform a dummy write
>
> this is the code i use to read the status of the 45DB021 connected
to LPC2103,
>
>
> /*********** ********* ********* ********* ********* *
> * Read chip status *
> ************ ********* ********* ********* ********* */
> byte readstatus(void)
> {
> byte status;
>
> //begin CS=0
> FIO0MASK0=0x7f;
> FIO0PIN0=0;
>
> //send command
> S0SPDR=READSTATUS;
> //wait until sent
> while((S0SPSR & 0x80)==0);
>
> // send dummy byte
> S0SPDR=0;
>
> //wait until sent
> while((S0SPSR & 0x80)==0);
>
> //read data
> status=S0SPDR;
>
> //end CS=1
> FIO0MASK0=0x7f;
> FIO0PIN0=0x80;
> return status ;
> }
>
>
> Be sure to init the SPI correctly (clock rate & polarity )
>
> // init SPI mem interface
> S0SPCR=0x0824;
> S0SPCCR=0x1e; // clock 15mhz/30
>
>
> Regards, Johan
>
> ----- Original Message -----
> From: gogotimmo
> To: lpc2000@yahoogroups .com
> Sent: Thursday, May 18, 2006 6:24 AM
> Subject: [lpc2000] Annoying Problem With SPI interface to Atmel
Dataflash
>
>
> Hi-
>
> I am having probles with the LP32138 SSP (SPI) interface to an
Atmel
> dataflash (AT45DB161). I believe it has to do with the chip
select
> implementation. To read the status register of the Atmel
dataflash,
> for example, the device requires an opcode 'write' followed by
> a 'read'. The write works fine, but the 'read' fails. I believe
it is
> failing because the chip select gets deasserted between the read
and
> write, thereby resetting the internal state machine of the data
flash.
> The datasheet of the atmel memory has timing diagrams that show
the CS
> asserted throughout the entire transfer with no transitions
between
> frames. Actually, it looks like the LPC2138 spi chip select
gets
> deasserted between each frame in a continuous transfer. If true,
this
> bites. The only workaround I can think of is to use a GPIO pin
to
> drive the CS manually. Since I'm already out of pins, this isn't
a
> great option for me. I thought of tricking the SPI peripheral by
> sending an 8-bit opcode justified in a 16-bit frame, which would
> probably work, but will fail when reading an array of memory
> addresses. These Atmel dataflash devices are extremely popular,
so
> someone must have had similar issues.
>
> Also, I don't mean to sound rude, but I have already looked at
the SPI
> code examples.
>
> Any help is appreciated-
> Thanks-
> Tim
>
>
>
>
>
> ------------ --------- --------- --------- --------- --------- -
-----------
>