|
|
View previous topic :: View next topic |
Author |
Message |
russk2txb
Joined: 30 Mar 2008 Posts: 109 Location: New Jersey
|
SPI Block reads and writes |
Posted: Sat Jan 08, 2011 7:48 am |
|
|
Hi all. I searched this forum quite a bit and cannot find any discussion or examples of SPI block reads and writes. I am talking to a 25LC160D eeprom sucessfully with single reads and writes (8 and 16 bits). But I cannot get block read to work (haven't tried the block writes yet). I am using the #USE SPI software SPI. Here is some code that works for single byte read:
Code: |
#use spi (DI=PIN_C1, DO=PIN_C5, CLK=PIN_C0, MODE=0, stream=SPI_PORT)
int ReadExByte (long addr)
{
int val;
output_low (EX_ROM); // select Rom
spi_xfer (SPI_PORT, EX_READ, 8);
spi_xfer (SPI_PORT, addr, 16);
val = spi_xfer (SPI_PORT, 0, 8);
output_high (EX_ROM);
return val;
}
|
and here is what I last tried for a block read:
Code: |
void ReadExData (long addr, long *p, int count)
{
int i;
output_low (EX_ROM); // select Rom
spi_xfer (SPI_PORT, EX_READ, 8);
spi_xfer (SPI_PORT, addr, 16);
for (i=0; i < count; ++i) {
p [i] = spi_xfer (SPI_PORT, 0, 8);
// p [i] = spi_xfer (SPI_PORT); // also tried this
}
output_high (EX_ROM); // Latch
}
|
The code compiles and does not cause a crash or hang, but no data is read, not even zeroes. The buffer contains exactly what it did upon entry to the function. Thanks for any insight, help, or examples.
Russ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Jan 08, 2011 7:52 am |
|
|
What value have you got in 'count'?.
Is a int, big enough?.
Best Wishes |
|
|
russk2txb
Joined: 30 Mar 2008 Posts: 109 Location: New Jersey
|
|
Posted: Sat Jan 08, 2011 8:54 am |
|
|
count is 16.
Russ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Jan 08, 2011 9:38 am |
|
|
A couple of comments:
You are aware presumably that this device is on the 'will be phased out soon' list, and not recommended for new designs. While fiddling around, might be better to select a newer part....
Is your target array, really holding 'long' values?. Seems a waste, when the code is returning bytes. Remember the 'size' given with a pointer, is the amount the pointer advances, not the size of the pointer itself.....
The address required by this chip, is _3 bytes_. You are sending 2.
Your address value needs to be an int32, not an int16, and you should send 3 bytes when writing the address. This may be the core 'problem'.
So:
Code: |
void ReadExData (int32 addr, int8 *p, int count)
{
int i;
output_low (EX_ROM); // select Rom
spi_xfer (SPI_PORT, EX_READ, 8);
spi_xfer (SPI_PORT, addr, 24);
for (i=0; i < count; ++i) {
p [i] = spi_xfer (SPI_PORT, 0, 8);
}
output_high (EX_ROM); // Latch
}
|
Best Wishes |
|
|
russk2txb
Joined: 30 Mar 2008 Posts: 109 Location: New Jersey
|
|
Posted: Sat Jan 08, 2011 4:31 pm |
|
|
Thanks for your reply but I think you are confusing this EEPROM with some other. The address is definitely 16 bits on the 25LC160D. At first I thought "How stupid I am", and changed the address parameters to 32 bits and 24 bit writes. That did not work, even with single byte reads and writes. Then looked it up on the data sheet, changed it back to 16 bit addressing and the single byte reads and writes worked again.
Also, at first I was not sure how you got the impression that I was reading long words, in this case I am actually reading string data, from a 16 byte string field. But as I wrote this I realized what the problem was. I had copied the function from an earlier attempt at a function to read multiple longs, and never changed the pointer. Changed the pointer to a char* and now have both reads and writes working in block mode.
I should note that I was getting data from the prom, but it was garbage due to the incorrect incrementing of my pointer.
Thanks again
Russ
[from the data sheet] Quote: | The device is selected by pulling CS low. The 8-bit READ instruction is transmitted to the 25XX160C/D followed
by the 16-bit address, with the five MSBs of the address being "don’t care" bits...
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jan 09, 2011 3:23 am |
|
|
Quite interesting. I was looking at the 'generic' 25LC160 data sheet. This specifies 3 bytes for the address (I'd guess to make it compatible to go on the same bus with larger devices...).
A 'caveat' for anyone switching between these devices.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|