EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

LPC1764 SPI assistance with 25LC512 EEPROM

Started by Nick August 17, 2013
Hey guys, I'm in a bit of a bind. I am using an LPC1764 with LPCexpresso version 5.2.6 with an LPC-Link 2. The problem is that I'm not sure if my connections are right or if my software is configured correctly.

Here is a simple layout of the connections:
http://i188.photobucket.com/albums/z265/fac7orx/eepromARMpic_zpsdc524e83.png

Here is a link to the EEPROM datasheet:
http://ww1.microchip.com/downloads/en/devicedoc/22065a.pdf

I am following the ssp_spi example given. I am using the SSP_SendData(SSP_CHANNEL,READ); and SSP_ReceiveData(SSP_CHANNEL); functions.

I configure SSP1 as follows:

Before entering the main while loop I put in a value (0xF9) at address 0:

Then I try to read the value from address 0:

Lastly, I am trying to run this at 10MHz and under the function "SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct)" I changed SSP_InitStruct->ClockRate = 1000000; to SSP_InitStruct->ClockRate = 10000000; (1 million to 10million for 10MHz). I'm not sure what else is required. If anyone can help me out it would be much appreciated. Thank you.

An Engineer's Guide to the LPC2100 Series

Hello Nick,

here are some points, i have seeing in your listing:

- I am missing filling sspChannelConfig with the configuration.
But because you have mentioned "ClockRate",
i think this is just a Copy&Paste error.
Can you show what configuration parameter you are using?
Important are especially Number of Bits, CPOL, CPHA, FrameFormat,...

- How is PORT_CS defined?

- How is SSP_CHANNEL defined?

- FIOCLR/FIOSET: These registers are not RMW (Read-Modify-Write),
but you just clr/set it.

- Have you checked to power up the peripheral/GPIO/...
and give them the right clock? (Look in User Manual,
what is exactly available and needed)

- Sometimes there is SSP and SPI. Check if you have not a mixture.

Some general point to narrow your error:

- Have you checked that clk is toggled during transfer?

- Have you checked that data is coming out during transfer?

- If you have not connected the EEPROM, you can feed a fixed
low or high to get 0x00 or 0xFF via SPI. Is this correctly read?

- Do you have a logic analyzer? Very helpful with SPI!

- There is a chapter "Basic configuration", sometimes a chapter
"General description", please check both for additional hints.

- If the SPI interface itself is working,
the next could be that the exchanged data is not correct.
"READ" is such a general word, check if content is correct,
or even rename to EEPROM_READ_COMMAND or similar,
to check if there is no other place using READ.

Best regards,

Martin
Thank you for the reply Martin. Some things I have looked into thus far is the CHPA and COPL bits and setting PINSEL0 register to set MISO. Unfortunately, the example provided was using a somewhat convoluted ("SSP_ReadWrite") function and they were only writing and not reading. Also, here is where they defined PIN_MASK_CS:



Also, here are updated pin configurations (I've added MISO1):


Underneath that they have configured P2.2 for output:


ans here are the defined instructions for the EEPROM that I put in:


And, according to this site (scroll down to "Timing"):
http://www.engscope.com/pic24-tutorial/12-1-spi-basics/

The figure that reads "serial input timing" looks exactly like the SPI EEPROM from Microchip I am using (maybe just different memory size). So, this tells me that CPHA = 0, CPOL=0.

Here is the function that configures the clock,CPHA,CPOL,etc taken from the lpc17xx_ssp.h (also it looks like it uses lpc17xx_clkpwr.c and .h which I have also included in my project):



I have also checked clock with an oscilloscope (not logic analyzer on hand unfortunately). I see what appears to be pulse (more like sloped triangles). My scope is rated at 20MHz, but the highest time division setting is 200ns which is 5MHz. Also, it is an analog scope, so it is hard to tell the frequency by counting the ticks when the time division can go high enough.

I keep looking into it, but if you notice anything else or have any other suggestions please let me know. Thanks again.
Also, at the top of "lpc17xx_ssp.c" I see include statements for "lpc17xx_clkpwr.h" and "lpc17xx_ssp.h" and there are SSP_Init and that calls to setSSPclock. I have included lpc17xx_clkpwr.h and .c. It looks like they already have done the heavy lifting for me in regard to setting up the clock and power.

Here is the SSP_Init function that gets called in main and this functions calls the setSSPclock function:



and here is the setSSPclock function:

Hello Nick,

you can lower clk from 10 MHz to e.g. 100 kHz.
It is perhaps than easier so see with your scope,
and you see if speed makes a problem.

If you can remove the EEPROM (or just not select it via CS)
you can also do the access faster, e.g. not only
every 2 seconds (i think), but perhaps e.g. 2 times per second,
if this is helpful.

You can also send only 1 byte instead of multiple byte,
if this makes it easier for you to bring system up.

You have checked that you see a clock.
Have you checked if data is sent?
Can you see the bytes you have sent?
Have you checked the order of the bits?

Have you checked the data which is received?

Best regards,

Martin
I managed to figure it out. I needed a delay after and before the /CS pin was asserted low and high. Here is what the read statement look like within the main while loop now:



I have to find out how to use timers as delays, for milliseconds using system tick isn't going to cut it. From the datasheet, the delay has to be about 100ns. I think I can use the match register to do this I just have to configure the PCLK to be system clock divided by 2 instead of 4.

Thank you for your responses and assistance.
Hi Nick,

It seems to me that the 100ns from the datasheet is the minimum time delay
needed for it to work. Anything above that will make it work just fine. 1ms
is good enough, it is not worth the trouble to create a 100ns delay.

Your code seems wrong though, where one reads:

else
{

systick_delay(1); // wait 1ms
PORT_CS->FIOCLR |= PIN_MASK_CS; //CS low

should be:

else

{

PORT_CS->FIOCLR |= PIN_MASK_CS; //CS low

systick_delay(1); // wait 1ms

Cumprimentos,

Bernardo Marques
While the delays may allow your code to work, I don't think that's the proper solution. You didn't post your SSP send and receive functions, but that's probably where your problem is. There are status bits that can be used to pace the rate at which you feed new data to the SSP. Here is some code from my SSP driver module and it has been tested on serial flash, serial EEPROM, displays with SPI interfaces, and serial DAC's. You can issue the select immediately before and the de-select immediately after calling one of these functions with no delays.

Jeff
Hi,

> Hi Nick,
>
>
>
> It seems to me that the 100ns from the datasheet is the minimum time delay
> needed for it to work. Anything above that will make it work just fine.
> 1ms is good enough, it is not worth the trouble to create a 100ns delay.
>
> Your code seems wrong though, where one reads:
>
> else
>
> {
> systick_delay(1); // wait 1ms
> PORT_CS->FIOCLR |= PIN_MASK_CS; //CS low

...actually, I believe you would require

PORT_CS->FIOCLR = PIN_MASK_CS; //CS low

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore Development Platform http://www.soldercore.com

Thank you so much guys! You are exactly right the delays actually only worked for sending and receiving 1 byte, when I recently tried multiple bytes and it doesn't work. The reason may just be the status bit that ksdoubleshooter kindly pointed out. I'll give it ago and post back if it works, maybe I don't need any delays at all, but I'll try it with both.

Additionally, I did create a ns and microsecond delay functions I can also test as well, but I'll try the ms delay with the system tick first.

The 2024 Embedded Online Conference