SPIM reading external memory incorrectly

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Basically, the SPIM will rotate bits as they are read into the PSoC3.... WARNING - not all chips present this problem! Some PSoC chips are NOT PRONE to this rotation! Other chips CONSISTANTLY show the problem!

   

Yes, a demo project is available on request! brian@genesysinst.com

   

Project: Create an SPIM with the normal IO (not bidirectional), mode 0. Disconnect the CS (SS) and connect to non-hardware pin. Chip used is a CY8C3866PVI-021ES2. I tried the DVK and it too gives this problem!

   

I'm using Ramtron FM25V05 as external memory, so grab a data sheet and notice that the word is similar (not identical!!!) to the Apps Note EP60810 - I.E. a multiple data word must be sent while the CS is low. I have pins 3 and 7 tied high, by the way. Well, the write needs two dips in the CS, but...

   

Speed - 3MHz, internal clock. Leave the buffers set at 4. I use the RESET pin to hold the SPIM non-functional and tri-state the IO as the Ramtron needs to be read by another processor. No interrupts.

   

Read/write various bit patterns as a BLOCK (one start address, many data). I need to block move data on occasion for my project.

   

I get bit rotations! Writing 16 (0x10) locations of "0x80" results in a READ of "0xC0" for the 0x10 locations! All the same!

   

Heres a list of some stuff I tried: 0x00 -> 0x00, 0xff -> 0xff, 0x55 -> 0x2a, 0xaa -> 0xd5, 0x80 -> 0xc0, 0x01 -> 0x00; 0x88 -> 0xc4, 0x11 -> 0x08.... Curiously, reading in, say, 0x15 locations does not reveal that the 0x11'th location contains incorrect data. You might expect this if the bit pattern is rotating to the next byte in the stream. So the stream is not polluted? Or can I say that?

   

Thoughts?

0 Likes
43 Replies
Anonymous
Not applicable

Just to make sure I'm completely clear, you are using the SPI communication interface to talk to an external memory, correct?

   

 

   

Also, what version of PSoC Creator are you using?

   

 

   

-Bobby

0 Likes
Anonymous
Not applicable

 I also see a similar problem.

   

In my case I have the following conditions CPU clock 48MHz. SPI clock 400KHz and SPI Master in Mode 00. Reads return data with a 1 bit shift so 5 is actually returned as 2. I can see on the scope that the data is correct. If I slow the CPU clock to 24MHz but keep the SPI clock at 400KHz everythings is fine.

   

I'm use Psoc3 ES3 silicon with Beta5 creator

   

My read function is as follows :

   

   

unsigned char IF_ReadRxData(void)

   

{

   

   

   while ((SPI_GetTxBufferSize()!=0));   // Wait for Tx FIFO empty ( incase any transfers are left)

   

   while(!(SPI_ReadTxStatus() & 0x10 )); // SPI idle,  becuase FIFO can be empty but not idle

   

   SPI_ClearRxBuffer();  // Clear old data 

   

   

   SPI_WriteTxData(0xFF);  // Send Data to trigger the transfer  

   

   while(SPI_GetRxBufferSize() ==0 );  // Wait for data to come in.

   

   return SPI_ReadRxData();  // Return Data

   

}

   

 

   

Also waiting for SPI idle is very slow. What is the best way to do the above. If you can't be sure the previous transfer has finshed before trying to read the next byte.

   

Thanks

0 Likes
Anonymous
Not applicable

Hi dp,

   

 

   

Instead of using "while(SPI_GetRxBufferSize() ==0 ); " to ensure that the dummy byte has been transmitted, can you try using "while(!(SPIM_1_ReadTxStatus() & SPIM_1_STS_SPI_DONE));" ?

   

Let us know if you can observe any improvement.

   

 

   

Regards,

   

dasg

0 Likes
Anonymous
Not applicable

brian,

   

From the description you have provided, it is clear that the received value is right-shifted by 1 bit.

   

You need to open the configuration tab of MISO input and unsynchronize it by unchecking the "Input Synchronized" from the "Input" tab. This should be able to solve the issue.

   

Let us know if this works.

   

 

   

Regards,

   

dasg

0 Likes
Anonymous
Not applicable

Hi,

   

I have a problem using too the FRAM FM25V05. I send a quantity of 0b0001000 in the memory ( or 0x10) and when we want to read it we have several errors. In my case, instead of receiving 0x01 we receive 0x00 ...

   

I use 16MHz CPU with 4MHz SPI clock.

   

Here a screenshot of my scope showing my problem: (1 = SPI clock, 2 = a trigger that shows where we have a 'read error')

   

   

 

   

The trigger (channel 2) on this attached picture should fall on a falling edge of the clock, in this case it falls before one half period (average) of the falling edge of the SPI clock.

   

Have someone any idea about our problem ? What can be the origin of this reading error ?

   

Regards,

   

Albin.

   

 

   

PS: The writing process succesfull, we have only problem on reading ..

0 Likes
Anonymous
Not applicable

Just something that i have to add, channel 2 is the data that we get from the FRAM. We should get the rising edge of the data from the falling edge of the clock till the next falling edge of the clock, here the "1" falls before the next falling edge ... that is our problem.

   

if someone have an idea, let me know 🙂

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Deducting from your last description: the data-pulse from the fram is not long enough. Are there any parameters for your memory that can be set differently?

   

And Are you using the right Mode for the SPI Master?

   

Bob

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

According to the data sheet, you are using SPI mode 0 (CPOL=0, CPHA=0). This means the data should be set at the falling flank of the clock (which it does) and be read with the rising flank. This is where it fails. The frequency is OK, the FRAM can go up to 40MHz. But did you try with a lower frequency? Do other read operations fail too (e.g. the device ID)?

   

What looks suspicious to me is the high swing on the data line. Could it be that you don't have a proper blocking capacitor for the FRAM? Or maybe the signal lines are too long

0 Likes
Anonymous
Not applicable

@Bob Marlowe: Hi Bob, thanks for your reply. We are using Mode 0 SPI Clock and about the memory's parameters all is ok.

   

@hli: You are right about our problem, that data falls before the falling edge of our clock. At higher frequencies we have same/similar errors (@8MHz SPI Clock, @16MHz ...).

   

What do you mean by writing "Could it be that you don't have a proper blocking capacitor for the FRAM" ?

   

About signal wires they are shorter as possible.

   

Thanks for your help.

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

You should have a 100nF capacitor between Vcc and GND on your chip. Make it as close to the cip as possible. It avoids drops in the power supply when the power consumtion of the chip changes (which happens everytime it starts to work).

0 Likes
Anonymous
Not applicable

This capacitor is solder very close to the FRAM for sure 🙂

   

I tought you were speaking about an another capacitor somewhere to put ...

   

Any other idea ?

   

 

   

Thanks.

0 Likes
Anonymous
Not applicable

But this capacitor is necessary to prevent possible low dropout from Vcc, what is the link between this capacitor linked to vcc and problem with datas readen ?

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Not having this capacitor usually leads to erratic behavior - that's why it might have been the reason (e.g. an untimely voltage drop due to some internal triggers firing when the clock signal changes and boom there goes your data line back to zero...). But since this is OK, you might ask Ramtron for more help - this doesn't seem to be an issue with the PSoC.

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi All,

   

Am trying to read M25P16  flash interfaced with PSoC3 via spi.

   

I sent a command byte(0x9F) to read status register,but couldnt get any data back from slave device(M25P16).

   

PSoC3 is SPI master,i observed in scope that after sending read command,clock was not generated.

   

SPI clock is 1Mhz,Mode 0 we are operating,CS line drived through firmware. In Screen shot yellow line is CS,

   

small portion of clock generated was during command write byte,after that during read cycles no data and no clock.

   

Please let me know your thoughts on this.

   

 

   

Thanks,

   

Manju

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Please open a new thread when you have a new problem. People won't always look at old threads, and you will get overlooked.

   

To your problem: the master only creates a clock when it is sending data. If you want to read something after you have written the command, you need to send a dummy byte to the slave. It will get ignored by the slave, but the master reads the answer when doing this.

0 Likes
Anonymous
Not applicable

 We used PSOC3 with 25pe16 and no problem so far.

   

I think it is better to upload your project for us to have a look. And also open a new thread as suggested.

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Thanks for your replies .Next time onowrds will open  thread for new problems.

   

I uploaded the project here,please suggest what went wrong.

   

Am sending dummy bytes to generate clock while reading, but getting 0x00  in MISO line.

   

 

   

Thanks,

   

Manju

0 Likes
Anonymous
Not applicable

I'll have a look.

   

Have you tried to read the ID of the chip. This would be the first thing I do as the ID is a fix data stream.

0 Likes
Anonymous
Not applicable

Yes,I tried to read Chip ID ,by sending command byte(0x9F) but getting zero's on miso line .

   

 

   

Thanks,

   

Manju

0 Likes
Anonymous
Not applicable

 If you cannot read ID, I would not try programming. 

   

Can you show me how your read ID?

   

Do you use the same routines as you posted?

   

you can upload the readiD part for us to check.

0 Likes
Anonymous
Not applicable

"WE NEED A EDITING FEATURE"!!!!!

   

I mean if you cannot read ID, I would not try to test the progrtamming(writing) the flash. Because there is not way of knowing whether the content is correct.

0 Likes
Anonymous
Not applicable

 Hi ,In that project file, i commented the Read ID function.

   

Below function to read the Chip ID of flash.Please let me know your thoughts on this.

   

   

void ReadFlashRegisters()

   

{

   

uint32  i,counter,status ,timeout ;

   

uint32 data_read = 0;

   

uint8 rx_data = 0;

   

i = counter = status = 0;

   

timeout = 50000;

   

DEBUG_UART_PutString("\r\nSend CMD");

   

while ( 1 )  // For Testing Purpose Keep Sending CMD

   

{

   

DEBUG_UART_PutString("\r\nSend CMD");

   

ChipSelect_Write(0x00);

   

SPIMaster_WriteByte(0x9F);

   

while ((SPIMaster_ReadTxStatus() & SPIMaster_STS_TX_FIFO_EMPTY) != SPIMaster_STS_TX_FIFO_EMPTY )

   

{

   

if ( counter++ > SPI_TIMEOUT_COUNTER )

   

break ;

   

}

   

while ( timeout -- > 0 )

   

{

   

SPIMaster_WriteByte(0x33); //Dummy byte write 

   

#if 1

   

if((SPIMaster_GetRxBufferSize() > (uint8)0 ) && (SPIMaster_GetTxBufferSize() == (uint8)0))

   

{

   

while (SPIMaster_GetRxBufferSize() > 0)

   

{

   

rx_data = SPIMaster_ReadRxData(); ; 

   

print_val(rx_data);

   

DEBUG_UART_PutChar(',');

   

   

}

   

}

   

#endif

   

}

   

timeout = 50000;

   

ChipSelect_Write(0x01);

   

i = 0;

   

counter = 0;

   

CyDelay(1000);

   

}

   

}

   

Thanks,

   

Manju

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

First - how did you configure the SPIM component? Is it 8bit, MSB first and the proper SPI mode (either 0/0 or 1/1)?

   

Second - can you try to upgrade the SPI component? I see from the code that you use an older version (2.00 at most), and the curent one is 2.30.

   

Third - when you send the first command (0x9f), you need to read one byte from the read buffer. For every byte written out by the master, another one is read, and this is true for the commands also.

   

How large did you configure the RX buffer? If it is larger than 4 bytes (which is the recommended size) you get a software buffer, and GetRxBufferSize() returns 0 as long as only the hardware buffer is used.

   

You while() loop is somewhat bogus: you put a byte in the write buffer - but this doesn't mean that it is written out when the function returns. Then you check that the transmit buffer is empty - which won't be the case. And then you proceed to write the next byte. This means that you never read anything. You need to add either a small delay after the write, or even better add a loop waiting for the transmit buffer to become empty.

0 Likes
Anonymous
Not applicable

SPI Configuration - Mode 0(CPHA 0 ,CPOL 0 ), 8Bit , MSB first . 

   

RX buffer size is 8. I will try updating the components and inserting delay after writing the byte.

   

Thanks for the suggestions .

   

 

   

Thanks,

   

Manju

0 Likes
Anonymous
Not applicable

The following is similar to what we use, Hope it helps.

   

**********

   

 ulong ReadID(void)

   

{

   

ulong ulDataRead = 0;

   

ChipDeselect();

   

ChipSelect();

   

/* read ID command */

   

Write1Byte(RDID);

   

SPI_ClearRxBuffer();

   

ulDataRead = flashRead1Byte();

   

ulDataRead <<= 8;

   

ulDataRead |= flashRead1Byte();

   

ulDataRead <<= 8;

   

ulDataRead |= flashRead1Byte();

   

ChipDeselect();

   

return ulDataRead;

   

}

   

 

   

uchar Read1Byte(void)

   

{

   

SPI_ClearRxBuffer();

   

Write1Byte(DUMMY);

   

return SPI_ReadByte();

   

}

   

void Write1Byte(uchar ucData)

   

{

   

uchar ucStatus = 0;

   

while (!(SPI_ReadStatus() & SPI_STS_TX_FIFO_EMPTY))

   

{

   

};

   

SPI_WriteByte(ucData);

   

while (!(SPI_ReadStatus() & SPI_STS_SPI_DONE))

   

{

   

};

   

}

   
    ********   
0 Likes
Anonymous
Not applicable

A bit of error, 

   

here is the corrected one ...

   

****

   

 ulong ReadID(void)

   

{

   

ulong ulDataRead = 0;

   

ChipDeselect();

   

ChipSelect();

   

/* read ID command */

   

Write1Byte(RDID);

   

SPI_ClearRxBuffer();

   

ulDataRead = Read1Byte();

   

ulDataRead <<= 8;

   

ulDataRead |= Read1Byte();

   

ulDataRead <<= 8;

   

ulDataRead |= Read1Byte();

   

ChipDeselect();

   

return ulDataRead;

   

}

   

 

   

uchar Read1Byte(void)

   

{

   

SPI_ClearRxBuffer();

   

Write1Byte(DUMMY);

   

return SPI_ReadByte();

   

}

   

 

   

void Write1Byte(uchar ucData)

   

{

   

uchar ucStatus = 0;

   

while (!(SPI_ReadStatus() & SPI_STS_TX_FIFO_EMPTY))

   

{

   

};

   

SPI_WriteByte(ucData);

   

while (!(SPI_ReadStatus() & SPI_STS_SPI_DONE))

   

{

   

};

   

}

   
        
0 Likes
Anonymous
Not applicable

 The SPI mode is same as ours. 

   

we just set the rx and tx to 4 byte, but we read/write  one byte at a time and not really using the buffer.

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Additional to the wait problema outlined above, a read buffer of 8 bytes implies the following:

   
        
  • an additional interrupt routine  is used to transfer bytes from FIFO to the software buffer
  •     
  • getRxBufferSize() returns 0 as long as received bytes are still in the FIFO, and are not read by the ISR
  •    
   

Especially the latter one might get you. Since you try to read all bytes directly, use a buffer size of 4 (which uses the hardware FIFO only).

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I tried using above functions ,things didnt work for my badluck.

   

I see the delay in between clock pulses because of function invokation and execution. That means clock is not continous.

   

Is that causing the problem ?

   

In data sheet features summary its saying 40Mhz to 50Mhz clock rate(maximum) .But if we set more then 24Mhz(based on Kbps rate setting) clock rate will get warning of clock accuracy.

   

 

   

Thanks,

   

Manju

0 Likes
Anonymous
Not applicable

 Did you see any signal from the MISO? Can you post the waveforem. Use MOSI as the syne 

0 Likes
Anonymous
Not applicable

 We are using 2M bit rate without any problem. Yes, there are delays between the clock pulse, you can change the functions to reduce the delay after you have it working.

0 Likes
Anonymous
Not applicable

I just noticed that we use high impedance digital input for MISO on PSOC. Check if that is the problem.

0 Likes
Anonymous
Not applicable

Thanks for your inputs,we successfully interfaced the SPI flash with PSoC3.

   

Thanks,

   

Manju

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

What was the final thing to make it work?

0 Likes
Anonymous
Not applicable

 It would help all others if you can tell us what's the solution, how it was fixed.

0 Likes
Anonymous
Not applicable

Main Issue was Clock generation during read cycles.

   

In our board SPI chip was dead,Bcoz of this the code posted above was not working.

   

we mounted new SPI flash chip,interface is Up now ..

   

Thanks,

   

Manju

0 Likes
Anonymous
Not applicable

 Thanks 🙂

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

One thing I do when interfacing a new / unkown IC via I2C or SPI is using a bus pirate: http://dangerousprototypes.com/docs/Bus_Pirate . This makes it simple to find out to speak with the chip. I start writing the software only after I understand the protocol, so when something wents wrong it's easier to know where the problem lies.

0 Likes
Anonymous
Not applicable

 That is a good product. Should order one to try

0 Likes