CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SPI Block reads and writes

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
russk2txb



Joined: 30 Mar 2008
Posts: 109
Location: New Jersey

View user's profile Send private message

SPI Block reads and writes
PostPosted: Sat Jan 08, 2011 7:48 am     Reply with quote

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: 19378

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 7:52 am     Reply with quote

What value have you got in 'count'?.
Is a int, big enough?.

Best Wishes
russk2txb



Joined: 30 Mar 2008
Posts: 109
Location: New Jersey

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 8:54 am     Reply with quote

count is 16.

Russ
Ttelmah



Joined: 11 Mar 2010
Posts: 19378

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 9:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 4:31 pm     Reply with quote

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: 19378

View user's profile Send private message

PostPosted: Sun Jan 09, 2011 3:23 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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