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

Need help on SPI interface with M25P20

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







Need help on SPI interface with M25P20
PostPosted: Mon Oct 09, 2006 12:10 pm     Reply with quote

Hi everyone,
I am trying to setup a communication link between the PIC and M25P20 using SPI. All data returned from read operation is 0.

What's wrong with my code?

Thank you and best regards,
James

Here is a testing code:


Code:

#include <18F442.h>
#device *=16
#include <string.h>
#fuses HS,NOWDT,NOPUT,NOPROTECT, NOBROWNOUT
#use delay(clock=12352000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define PORTD_CFG 0xE0
#define MEM_CLK   PIN_D0
#define MEM_CS    PIN_D2
#define MEM_WRI   PIN_D3
#define MEM_HOLD  PIN_D4
#define MAX_ADDRESS  262144

int1 ext_fmem_ready(void)
{
   int8 data;
   
   output_low(MEM_CS);
   //RDSR (Read Status Register) has address 5
   spi_write(0x05);
   //Read RDSR, bit0 is Write In Progress (WIP)
   data = spi_read(0);
   output_high(MEM_CS);
   //if WIP is 0, flash memory is ready to write
   return(!bit_test(data, 0));
}

int write_ext_fmem(int32 address, BYTE data)
{
   int wait_timeout = 3;
   
   while(!ext_fmem_ready())
   {
      if(--wait_timeout == 0)
         return 0;
   }
   if( address > (long)MAX_ADDRESS)
      return 0;
     
   output_low(MEM_CS);
   //WREN (Write Enable) address on 6
   spi_write(0x06);
   output_high(MEM_CS);
   
   output_low(MEM_CS);
   //select Page Program
   spi_write(0x02);
   spi_write(address >> 16);
   spi_write(address >> 8);
   spi_write(address);
   //write data
   spi_write(data);
   output_high(MEM_CS);
   return 1;
}
//--------------------------------

int read_ext_fmem(int32 address)
{
   int8 data;
   int wait_timeout = 3;
   
   while(!ext_fmem_ready())
   {
      if(--wait_timeout == 0)
         return 0;
   }
   if(address > MAX_ADDRESS)
      return 0;
     
   output_low(MEM_CS);
   spi_write(0x03);
   spi_write(address >> 16);
   spi_write(address >> 8);
   spi_write(address);
   
   data = spi_read(0);
   output_high(MEM_CS);
   
   return data;


void main ( )
{
   int data;

#use fast_io(D)
   Set_Tris_D(PORTD_CFG);
   
//setup spi
   output_low(MEM_CLK);
   output_high(MEM_CS);   
   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16 );
   delay_us(20);
   //write to address 10 and read it back
   write_ext_fmem(10, 128);
   data = read_ext_fmem(10); 
}   
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 09, 2006 12:22 pm     Reply with quote

Quote:
#define PORTD_CFG 0xE0
#define MEM_CLK PIN_D0
#define MEM_CS PIN_D2
#define MEM_WRI PIN_D3
#define MEM_HOLD PIN_D4

spi_write(address >> 16);
spi_write(address >> 8);
spi_write(address);

What's wrong with my code?


You're using the CCS spi functions, such as spi_write().
These functions only use the hardware SPI pins, which are on Port C.
You need to re-wire the flash memory chip to use those pins.

You have some other things that need be fixed:
1. You need to add the NOLVP fuse.
2. You need a while(1); statement at the end of main().
3. I would get rid of the #fast_io and let CCS handle the TRIS.
Just use output_low(), output_high(), output_float(), etc., and
the compiler will take care of the TRIS.

I didn't try to analyze your code for correctness as a driver.
I just did a quick scan of it.
MELOG
Guest







PostPosted: Mon Oct 09, 2006 12:38 pm     Reply with quote

PortC has reserved for A/D chip. With PortD only, any sample code or it is impossible?

PCM programmer wrote:
Quote:
#define PORTD_CFG 0xE0
#define MEM_CLK PIN_D0
#define MEM_CS PIN_D2
#define MEM_WRI PIN_D3
#define MEM_HOLD PIN_D4

spi_write(address >> 16);
spi_write(address >> 8);
spi_write(address);

What's wrong with my code?


You're using the CCS spi functions, such as spi_write().
These functions only use the hardware SPI pins, which are on Port C.
You need to re-wire the flash memory chip to use those pins.

You have some other things that need be fixed:
1. You need to add the NOLVP fuse.
2. You need a while(1); statement at the end of main().
3. I would get rid of the #fast_io and let CCS handle the TRIS.
Just use output_low(), output_high(), output_float(), etc., and
the compiler will take care of the TRIS.

I didn't try to analyze your code for correctness as a driver.
I just did a quick scan of it.
melog
Guest







PostPosted: Mon Oct 09, 2006 1:09 pm     Reply with quote

PCM programmer,

I found an example code 9346.c under c:\Program Files\PICC\Drivers. Any better ones (using M25P20)?

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 09, 2006 1:13 pm     Reply with quote

Look at CCS drivers for memory chips, that use software SPI:

c:\program files\picc\drivers\at45db021.c

c:\program files\picc\drivers\68hc68r2.c
Memlog
Guest







PostPosted: Mon Oct 09, 2006 1:20 pm     Reply with quote

PCM programmer,

Thanks. One of them is perfect maching with my case!
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