Hi all,
I had written a code to interface 25c160 (SPI EEPROM) with lpc2114. I used proteus for simulation. But when i was de-bugging my code in keil, S0SPDR register is not taking any values.I am not able to understand what went wrong.... I am attaching my code...... Please guide my way out....
pavan pavannaidu.v@gmail.com
#include <lpc21xx.h> #include "spi.h" unsigned char rd[5]; void spi_init(void) { PINSEL0 = 0X00005500; //SELECTING SPI MODE S0SPCCR = 0X78; //100KHZ S0SPCR = 0x20; //MASTER MODE WITH 8-BITS PER TRANSFER IODIR0 = 0x00000400; //SET SSEL0 AS OUTPUT; } unsigned char spi_tx_rx(unsigned char val) { IOCLR0 = 0X00000080; S0SPDR = val; while(!(S0SPSR & 0x80)); S0SPSR = 0X00; return S0SPDR; IOSET0 = 0X00000080; } void spi_write_en(void) { IOCLR0 = 0X00000080; spi_tx_rx(WREN); wait(); IOSET0 = 0X00000080; } void spi_write(unsigned char *val) { spi_write_en(); spi_tx_rx(WRITE); spi_tx_rx(0X00); //ADDRESS: HIGHER BYTE spi_tx_rx(0X00); //ADDRESS: LOWER BYTE while(*val) { spi_tx_rx(*val++); } wait(); } void spi_read() { int i; spi_tx_rx(READ); spi_tx_rx(0X00); //ADDRESS: HIGHER BYTE spi_tx_rx(0X00); //ADDRESS: LOWER BYTE for(i=0;i<5;i++) { rd[i] = spi_tx_rx(0x00); wait(); } } /* void write(unsigned char *dataa) { while(*dataa) spi_write(*dataa++); } void read(void) { int i; spi_read(); for(i=0;i<5;i++) { rd[i] = spi_read(); wait(); } } */ void wait() { int j; for(j=0;j<50000;j++); }
are you sure the peripheral clock is setup correctly...? if not, the S0SPCCR is invalid.
yeah, I have done that.,
Fosc = 12Mhz, configured both Cclk and Pclk to be 12Mhz The SPI clock(S0SPCCR = 0x78) was configured at 100Khz.
i tried to debug the code but the S0SPDR register is not seen taking any values!!!!1( eg., even if i forced S0SPDR = 0xAA, it was showing S0SPDR=0x00 in the SPI peripheral window)......
i dont know what to do know?????
pavan.
Don't expect that you can read back the value you write to the data register. Depending on design, some implementations uses a R/W register. Some designs has one read-only register at the same address as a write-only register.
The value you are expected to pick up after a transfer, is the data sent from the slave. Have you made sure that all signals are toggling as expected on the slave side? Does the slave get a slave-select? Does the slave send out any data back?
You have one line setting one I/O pin as output:
IODIR0 = 0x00000400; //SET SSEL0 AS OUTPUT;
You have one different pin value that seems to be used for slave select:
IOCLR0 = 0X00000080;
Hi, can any one provide me with a working code for the same. it would be very helpful.......
pavannaidu.v@gmail.com
Have you checked the function of the slave-select signal yet?
Does the memory see slave-select, clock and MOSI signals? Is the memory emitting any MISO signal? Does the signals look ok - correct levels? correct timing? correct clock phase and level?
Hi Per Westermark, I have grounded the CS input of the memory, i am able to see the clock, MOSI signal.But the MISO signal remains unchanged(in tri-state). I am protues to check my output. pavan
Are you sure that's allowed?
Hi andy, well grounding CS pin should not pose a problem, because all you want is to make CS pin low when ever you use that memory block (25c150 in my case). And i am making CS low all time.....
pavan
And you are sure that you may not get out-of-sync in your bit train if you have no way to reassert the slave select line between commands?
"because all you want is to make CS pin low when ever you use that memory block"
Are you sure?
What if the device relies upon seeing a falling edge on CS...?
Don't make assumptions - do what the Datasheet tells you!
(so my question to you could be re-phrased as, "have you confirmed in the datasheet that holding CS low is supported")
hi, yes....i had gone through the data sheet of the memory block and some app notes., they said that CS can be grounded if a single memory element was in operation.
One note in the datasheet is: "A low-to-high transition on CS after a valid write sequence initiates an internal write cycle."
Another is: "The read operation is terminated by raising the CS pin (Figure 3-1)."
A third note: "After all eight bits of the instruction are ransmitted, the CS must be brought high to set the write enable latch. If the write operation is initiated immediately after the WREN instruction without CS being brought high, the data will not be written to the array because the write enable latch will not have been properly set."
But back to my initial comment. If you get a spurious clock cycle, and don't toggle CS - how will you then get the chip to synchronize again, so that it knows which clock cycle that represents the transfer of the first bit of a command or address or data byte?
Hi Per Westermark, I got my answer....thanks a lot........
Can you give links to the document(s) that said that, and the specific point(s) at which it was said?
It appears to contradict Per's quotes - so perhaps Per could also give references?