View previous topic :: View next topic |
Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 195
|
beginner SPI problem |
Posted: Wed Jan 09, 2008 4:13 pm |
|
|
I'm just getting started with the SPI stuff and am starting with the ex_spi.c code cloned into a program I have that also does a software I2C interface on pins C0 and C1. Before I forget, the compiler version is 3.249. I've tried this on both a PIC18LF252 and a PIC18LF2525 with the same results. The program calls the init_ext_eeprom() routine and inputs commands from a serial port to read (using read_ext_eeprom()) or write (using write_ext_eeprom()) to the external eeprom (the 93LC56 device that came with the software developers kit). I've wired the device as specified in the 9356spi.c file.
The problem is this... I put the 93LC56 clock (pin 2) and 93LC56 input (pin 3) lines on a scope. When I write a value to the eeprom, it looks exactly like what I expected from the description of the write_ext_eeprom() function. It writes a 0x0a, then it writes the address, and then it writes the data. I looked at the CS signal with respect to this burst and it is normally low, goes high during the burst, and then returns low again. Write appears to work fine. Read, however...
When I monitored the 93LC56 output (pin 4) and the 93LC56 clock (pin 2) and try the read_ext_eeprom() function, all I get is 0xff outputs. I've tried using a pullup (10K and 47K to Vcc) and pulldown (ditto to ground) with no help. I have tried pins 6 and 7 to ground as well as pin 5. Both ways result in the same output. I tried another device but the results are largely the same. A couple of addresses actually could be written and read back corectly (address 000).
This responds the same way at 3.3VDC, 4.0VDC, and 5.0VDC. My clock rate is 20MHz. The setup_spi() function called in the 93LC56 support file says its using "SPI_CLK_DIV_16" but the SPI clock looks like its about 800ns on the scope (a little less than 1us for a clock cycle).
I did a check of the postings and did not see this one mentioned.
Does anyone have an idea of what's happening? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 09, 2008 4:48 pm |
|
|
What is the exact part number of your eeprom ?
There will be an A, B, or C letter after the "93LC56". |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jan 09, 2008 5:16 pm |
|
|
Quote: | My clock rate is 20MHz. The setup_spi() function called in the 93LC56 support file says its using "SPI_CLK_DIV_16" but the SPI clock looks like its about 800ns on the scope (a little less than 1us for a clock cycle). | 20MHz / 16 = 1.25MHz = 800ns. Your clock is working as configured. |
|
|
kamputty Guest
|
|
Posted: Wed Jan 09, 2008 5:42 pm |
|
|
Does it work if you do not have the probe on it? If it does, are you grounding the probe correctly?
Also, if you still cannot get it working, can you manually bit blast it?
~Kam (^8* |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
a little more info |
Posted: Wed Jan 09, 2008 6:16 pm |
|
|
The exact part number of the eeprom is the 93LC56A. It was the part supplied in the software developers kit.
I also tried a divide by 64 instead of the divide by 16 in the setup_spi(). The clock period was longer, as expected, but the interface still behaves the same way.
I will try the system tomorrow (the system is at work and I'm home now) without the scope probe but the problem showed up initially before I put the scope on it... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 09, 2008 6:46 pm |
|
|
Post the list of physical connections between the PIC and the eeprom.
Post the pin numbers on the PIC and the pin numbers on the eeprom
that are connected together. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jan 10, 2008 7:30 am |
|
|
... and post the compiler version number as well. |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Thu Jan 10, 2008 8:16 am |
|
|
pinout connections:
pic18lf252 or 2525 93lc56a
B0 (21) CS (1)
SCLK (14) Clk (2)
SDO (16) DI (3)
SDI (15) DO (4)
Gnd (5), *8/16 (6), and NU (7) are at Gnd
Vcc (8) is at 3.3VDC
again (as I posted in the original message), the compiler version is 3.249. |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Thu Jan 10, 2008 8:36 am |
|
|
sorry for the last posting... apparently all white space is deleted
PIC pin 21 (CS) -----> EEPROM pin 1 (CS)
PIC pin 14 (SClk) -----> EEPROM pin 2 (Clk)
PIC pin 16 (SDO) -----> EEPROM pin 3 (DI)
PIC pin 15 (DI) <----- EEPROM pin 4 (DO)
again, the EEPROM pins 5, 6, and 7 are all at ground and the EEPROM pin 8 is at 3.3VDC. |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
additional information |
Posted: Thu Jan 10, 2008 11:51 am |
|
|
I got a chance to test some more with the interface... I tried it without the scope probes and got the same result. This morning, though, its showing a little different symptoms... (with and without the scope probes).
According to the scope trace during the write, the correct first byte (0x0a), second byte (address byte), and third byte (data byte) are going out correctly. When I put a 111 into address 000 and then check it with a read, the read shows 111. Address 001 is also showing a 111. When I put a 222 into address 001 and then try a read, it still shows the 111. As a matter of fact, all odd addresses are being ignored and all even addresses are writing the data to both odd and even addresses. When I put a 123 into address 100, I can read back a 123 from addresses 200 and 201. At least that's what gets read back now. Is this something that could be related to the *8/16 input on the eeprom?
Weird, huh? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 10, 2008 2:47 pm |
|
|
I think there is a problem with the SPI mode.
The 93LC56A data sheet says this:
(in section 3.2 on page 12):
http://ww1.microchip.com/downloads/en/DeviceDoc/21794E.pdf
Quote: |
Opcodes, address and data bits are clocked in
on the positive edge of CLK. Data bits are also
clocked out on the positive edge of CLK.
|
This means it samples on the rising edge. The timing diagram in
Figure 1-1 (on page 5) also shows this. It also shows that clock
idles at a low level. This is SPI mode 0. See the diagrams at
the bottom of this page:
http://elm-chan.org/docs/spi_e.html
ckielstra has previously come up with some define statements
to easily select the correct SPI mode, when using the setup_spi()
statement:
Code: |
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
|
Now we get to the important part. In the CCS 9356spi.c driver file,
they are doing this in the init_ext_eeprom() routine:
Quote: |
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16); |
Well, that selects Mode 2. But Mode 2 idles high and samples on
the falling edge. The setup in the above statement is wrong. It's
using the wrong edge. This explains the funky results. SPI timing:
http://elm-chan.org/docs/spi_e.html
To fix this, edit the 9356spi.c program and add the four #define
statements shown above to the start of the 9356spi.c file (above all
the routines). Then edit the setup_spi() statement and change the
middle constant so it looks like this:
Code: |
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
|
|
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Thu Jan 10, 2008 4:34 pm |
|
|
I did what you suggested. I set up MODE 0 and a divide by 16. In looking at the data/clock phase relationship with a scope during the write cycle, I could confirm the clock was normally low, went high for each bit, and write data changed on the falling clock edge, exactly as specified in the reference http://elm-chan.org/docs/spi_e.html (which was a very good reference, by the way). In looking at the data being read in, though, the data/clock relationship looked like MODE 1, with data changing on the rising clock edge.
I even tried divide by 64 instead of divide by 16, thinking the 20MHz clock rate might be a little too high. No difference. I tried all four modes (0, 1, 2, and 3) and they all come back with the same results. I loaded each of the first eight memory locations with 0x10 through 0x80, respectively. When I dumped the first 8 memory locations I get the following:
external eeprom address 01 contains 10
external eeprom address 02 contains 20
external eeprom address 03 contains 20
external eeprom address 04 contains 30
external eeprom address 05 contains 30
external eeprom address 06 contains 40
external eeprom address 07 contains 40
As an experiment, I tied the *8/16 (eeprom pin 6) to high. I got the same results.
Where is the #define value SPI_XMIT_L_TO_H defined? I could not find it listed in the manual for my version 3.249 compiler. I also could not find a complementary SPI_XMIT_H_TO_L value...
I loaded |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 10, 2008 4:40 pm |
|
|
Look in the .H file for your PIC. The constants that are used with
the CCS functions are all in the .H file. See this directory.
Quote: | c:\Program Files\Picc\Devices |
You said the eeprom voltage is +3.3v.
What's the PIC's Vdd voltage ? |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Thu Jan 10, 2008 6:24 pm |
|
|
Thanks for pointing out what should have been obvious to me for the #defines ;)
The PIC and the EEPROM are both running from the same 3.3VDC power supply.
I breadboarded another circuit using a pair of 74HC165 shift registers and looked at the clock and data lines again. I used setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16); and the data was clocked into the PIC correctly. I believe this is MODE 2. I'm doing this preliminary "get-my-feet-wet" stuff so I can eventually implement a system with a set of 5 ADCS7476 ADC devices. The 74HC165s simulate the 16-bit output from the ADCs. |
|
|
|