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 Read problem on 25LC256

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



Joined: 19 Dec 2009
Posts: 4
Location: Wisconsin

View user's profile Send private message Visit poster's website

SPI Read problem on 25LC256
PostPosted: Tue May 18, 2010 6:50 am     Reply with quote

I am seeing a problem with reading data from a 25LC256. Specifically what is happening is there is a right-shift by one bit to the data (eg receiving 3F instead of the actual 7E). The code below writes the data correctly (I verified by pulling chip after a write and reading it with a EEPROM programmer that the data sent was correct). However the read is bit shifted and I don't see why it would be. Any help would be appreciated.
Code:

#define EEPROM_SELECT PIN_H4
#define EEPROM_DI     PIN_C4
#define EEPROM_DO     PIN_C5
 
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE    32768  //32Kb x 8
#define READ           0b00000011
#define WRITE          0b00000010
#define WRDI           0b00000100
#define WREN           0b00000110
#define RDSR           0b00000101
#define WRSR           0b00000001

void init_ext_eeprom()
{
output_high(EEPROM_WP);
output_high(EEPROM_HOLD);
output_high(EEPROM_SELECT);
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 );
return;
}

//--------------------------------
int1 ext_eeprom_ready(void)
{
BYTE data;

output_low(EEPROM_SELECT);
spi_write(RDSR);
data = spi_read(0);
output_high(EEPROM_SELECT);
return(!bit_test(data, 0));
}

//--------------------------------
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data)
{
while(!ext_eeprom_ready());

output_low(EEPROM_SELECT);
spi_write(WREN);
output_high(EEPROM_SELECT);

output_low(EEPROM_SELECT);
spi_write(WRITE);
spi_write(address >> 8);
spi_write(address);
spi_write(data);
output_high(EEPROM_SELECT);
return;
}
//--------------------------------

BYTE read_ext_eeprom(EEPROM_ADDRESS address)
{
BYTE data;

while(!ext_eeprom_ready());

output_low(EEPROM_SELECT);
spi_write(READ);
spi_write(address >> 8);
spi_write(address);

data = spi_read(0);
output_high(EEPROM_SELECT);

return(data);
}

I am using CCS version 4.103. The project is using a PIC18F97J60 at 25MHZ with #define INTERNAL_CLOCK 0.16 statement in the main program prior to doing any SPI actions.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 18, 2010 12:25 pm     Reply with quote

If you have a problem where your SPI data is "off by one bit", it's
usually caused by selecting the wrong SPI mode. The mode is critical
for correct operation in SPI.

The first thing is to determine the SPI mode used by your slave device.
In Microchip data sheets, they very nicely give the mode in the timing
diagrams for the chip. Look at the timing diagrams on page 5 of
the 25LC256 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/21822F.pdf
You'll see that they use Mode 0,0 or 1,1. (That's in binary).
You can also call these Mode 0 and Mode 3.

Now you need some way to specify the mode in CCS. This information
is available in the forum archives. You just sort of have to know it's there:
Code:

// SPI mode definitions.
#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)


Here's your SPI statement:
Quote:

setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 );

We can see that you're using Mode 2, which is not correct. That's likely
the cause of your "shifted by 1" problem.

The solution is to add those 4 #define statements above main(), and
then edit your setup_spi() statement to use the proper mode:
Code:

setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16 );

Notice how that line is now self-documenting. You can see the SPI mode
just by looking at it.
sdkilde



Joined: 19 Dec 2009
Posts: 4
Location: Wisconsin

View user's profile Send private message Visit poster's website

PostPosted: Tue May 18, 2010 12:47 pm     Reply with quote

Thanks that was the problem Very Happy
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