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 CCS Technical Support

PIC24 to Atmel flash SPI issue

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








PIC24 to Atmel flash SPI issue
PostPosted: Mon Sep 14, 2009 12:13 pm     Reply with quote

Hi,

I've been trying to read/write data from my PIC24 to an Atmel AT25F2048 SPI Serial Flash through SPI, but I have been having a communication issue. I have written the following simple piece of code which should read the product ID. On the oscilloscope I can see that the correct opcode is being sent, the clock is cycling/CS is low while writing the 1 byte opcode and CS is sent high to complete the write, but the product ID is never being received back:
Code:

#include <24fj128ga006.h>
#device ICD=TRUE

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPROTECT                //Code not protected from reading
#use delay(internal=8M)

#define EEPROM_SELECT PIN_G9
#define EEPROM_DI        PIN_G7
#define EEPROM_DO       PIN_G8
#define EEPROM_CLK      PIN_G6

// Use Charlie U's SPI mode definitions.
#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010

unsigned int16 ID;

void main()
{
 
   setup_spi2( FALSE );
   setup_spi2(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16);
   output_high(EEPROM_SELECT);

   while(true)
   {
      output_low(EEPROM_SELECT);
      ID = spi_read2(0x15);
      output_high(EEPROM_SELECT);
      delay_ms(5);
   }
}

I've tried some other SPI examples with no success. I've been going in circles for a few weeks now trying to get SPI to work with this Atmel EEPROM. Any help and/or examples that you may be able to provide to me on this issue will be greatly appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 14, 2009 12:17 pm     Reply with quote

Those SPI #defines are from a fairly old post. They are tied to the
particular register bit layout of the 16F (and 18F) series PICs.

I would not try to use them with the 24F-series PICs, at least without
checking it first.

In fact, look at FvM's post on using hardware SPI with the 24F-series:
http://www.ccsinfo.com/forum/viewtopic.php?t=38491&start=12
Guest








PostPosted: Mon Sep 14, 2009 1:10 pm     Reply with quote

Thanks so much for the quick response.

I've looked at the data sheet to determine the appropriate pins to use for the SPI setup. I've read the other post that you've referred to, but I get a bit lost in some of the details that they are pointing out with the incorrect SDI pin select register and how to diagnose this. I'm fairly new to embedded programming, so any detailed guidance that you may have on checking to see if this is an issue or another alternative solution is greatly appreciated.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 14, 2009 1:54 pm     Reply with quote

Yes, the above SPI_MODE codes are not applicable to PIC24.

With PCD, the setup_spi mask is directly copied to SPIxCON1, in my opinion you find the correct coding below, but you can check in PIC24F Family Reference Manual
Code:
#define SPI_MODE_0_0 0x0100
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0140
#define SPI_MODE_1_1 0x0040

The next point are #pin_select statements, but they aren't required for
PIC24FGA006, that has fixed pins.

Finally, your ID read operation is incorrect in my understanding of the AT25F2048 datasheet. But I'm using a different SPI flash device.
Code:
ID = spi_read2(0x15);

I think, that you need three byte transfers to get all data.
Code:
spi_read2(0x15);
ID1 = spi_read2(0);
ID2 = spi_read2(0);
Guest








PostPosted: Mon Sep 14, 2009 2:30 pm     Reply with quote

Thanks for the details FvM.

It's my understanding from looking at the Atmel datasheet that the RDID opcode can be either 0x15 or 0x1D. I'm still unsure if I have connectivity to the Atmel memory at this point and was hoping that this would be a simple test. I've emailed Atmel tech support twice over the past week with no answer as of today. I haven't been able to detect any hardware issues. I'm running out of options at this point and am desperate to get this working. Any other advice you or anyone else can give is greatly appreciated.
Guest








PostPosted: Mon Sep 14, 2009 2:34 pm     Reply with quote

Sorry, I didn't see you last solution. I will try that now.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Sep 15, 2009 6:18 am     Reply with quote

Quote:
I didn't see you last solution.

I added a supplement later on. If I understand the Atmel datasheet correctly, the ID isn't on a byte boundary in this case. But you can try to match it, if you get data different from 0x00 or 0xFF, otherwise, you most likely didn't manage to access the chip.
Guest








PostPosted: Tue Sep 15, 2009 8:36 am     Reply with quote

Excellent!! It appears to be reading in the proper product ID at this point. I'm getting 1F 63. Thank you FvM and PCM programmer for all your advice. I've been spinning my wheels for quite some time now.

At this point I'm going to write up and test some fairly simple read/write routines. I've tried in the past with no success. Hopefully, I can get this to work now. If you have any suggestions on some simple routines just let me know.

Thanks again!

New code:
Code:

#include <24fj128ga006.h>
#device ICD=TRUE

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPROTECT                //Code not protected from reading
#use delay(internal=8M)

#define EEPROM_SELECT PIN_G9

#define SPI_MODE_0_0 0x0100
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0140
#define SPI_MODE_1_1 0x0040

unsigned int16 ID1, ID2;

void main()
{
 
   setup_spi2( FALSE );
   setup_spi2(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16);
   output_high(EEPROM_SELECT);

   while(true)
   {
      output_low(EEPROM_SELECT);
      spi_read2(0x15);
      ID1 = spi_read2(0);
      ID2 = spi_read2(0);
      output_high(EEPROM_SELECT);
      delay_ms(5);
   }
}
Guest








PostPosted: Fri Sep 18, 2009 8:06 am     Reply with quote

I've written some simple routines to read/write a byte of data successfully by using the CCS spi_read function. Now I need to write an entire page of data (256 bytes) to the same address and I know that the spi_read function is designed to send 1 byte of data for each call. I'm trying to decide which is the best way to accomplish this and was curious if the spi_read function can be used within a loop to accomplish this task. As a test I've attempted to send two byes of data to the same address by use of the spi_read function without success.

Any suggestions?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Sep 18, 2009 9:06 am     Reply with quote

I don't know, what sending two bytes to same address means, the flash device it'self is performing an auto-increment of addresses.

A page write can work like below, assuming the memory has been erased before.
Code:
      SPI_nCS_LAT = 0;
      spi_read(0x06); // WREN
      SPI_nCS_LAT = 1;
      SPI_nCS_LAT = 0;
      spi_read(0x02); // Page Program
      spi_read(eeaddr.b[2]);
      spi_read(eeaddr.b[1]);
      spi_read(eeaddr.b[0]);
      for (i=0; i<256; i++)
      {
         b = *data++;
         spi_read(b);
      }
      SPI_nCS_LAT = 1;

The reason for performing write action through the spi_read() function has been discussed in a previous thread, it has been necessary at least with previous PCD versions, but is still with most recent V4.099, if I remember right. It doesn't harm anyway.
Guest








PostPosted: Fri Sep 18, 2009 1:55 pm     Reply with quote

Thank you for the example. I've used similar code to accomplish the task.

Within the last post I meant to say that I was assigning one address then writing two bytes of data. Sorry about that.

I can confirm that the spi_write function still seems not to work as intended within PCD version 4.097. I've only been using the spi_read function for read/write and it's been working perfectly.

Thanks again!
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