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.
LPC1764 SPI assistance with 25LC512 EEPROM
Started by ●August 17, 2013
Reply by ●August 18, 20132013-08-18
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
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
Reply by ●August 18, 20132013-08-18
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, 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.
Reply by ●August 18, 20132013-08-18
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:
Here is the SSP_Init function that gets called in main and this functions calls the setSSPclock function:
and here is the setSSPclock function:
Reply by ●August 18, 20132013-08-18
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
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
Reply by ●August 22, 20132013-08-22
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.
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.
Reply by ●August 23, 20132013-08-23
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
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
Reply by ●August 23, 20132013-08-23
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
Jeff
Reply by ●August 23, 20132013-08-23
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
> 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
Reply by ●August 27, 20132013-08-27
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.
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.