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

spi flash_WRITE writes 3 bytes instead of one?

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



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

spi flash_WRITE writes 3 bytes instead of one?
PostPosted: Tue Jan 17, 2012 11:36 am     Reply with quote

Hello everybody,
Please help to solve my problem...
I'm trying to write one byte to 128 Mb flash memory M25P128
but when I write one byte it writes 3 bytes:
For instance: address 0xEC0000 (first address in sector 59)
and data is D170
When I read data:
0xEC0000 is D170 OK
0xEC000001 is D05 WHY?
0xEC0002 is D0 WHY
0xEX0003 is 0xFF ok
and data after this in all addresses is 0xFF as expected...

Thank you for good discussion forum Smile

Here is part of my code:
Code:

These are before main() sure:

#define flash_WREN     0x06        //flash muistin write enable
#define PAGE_prog      0x02        //flash muistin page program enable
#define flash_RSTATUS  0x05        //flash muistin READ status osoite
#define flash_READ     0x03        //flash muistin READ enable
#define SEC_erase      0xD8        //flash muistin SECTOR ERASE
#define FULL_erase     0xC7        //flash muistin BULK ERASE

//***********************************************************************************************

short int flash_WRITE(int8 flash_data)
{
     
      int8 read_data,timeout;
     
      output_high(flash_sel);delay_us(2);                 
      spi_write(flash_WREN);delay_us(2);                   
      output_low(flash_sel);                   
      delay_us(2);     
      output_high(flash_sel); delay_us(2);       
      spi_write(PAGE_prog); delay_us(2);                 
      send_FLASH_address(); delay_us(2);                   
      spi_write(flash_data);delay_us(2);                     
     
      output_low(flash_sel);                 
   
      timeout = 0;
   
      while(flash_busy()& (timeout < 255))   
      {
       delay_us(500);
       ++timeout;
     
      if(timeout == 255)
      {
     
      clear_row(14);clearTextBuffer();
      strcpy(teksti,"flash write (timeout) error"); text_xy(0,14);text(teksti);
      delay_ms(3000);
      return FALSE;
      }
      }
     
      delay_ms(20);
 
       read_data = READ_flash();
 
      if(read_data == flash_data)
      {
      return TRUE;
      }
     
      else
      {
      clear_row(14);clearTextBuffer();     
      strcpy(teksti,"flash compare error"); text_xy(0,14);text(teksti);
      delay_ms(3000);
      return FALSE;
      }
}


//***********************************************************************************************

short int flash_busy(void)
{
 
    int8 status;
    short int bitti_testi;

       
       output_high(flash_sel);delay_us(2);                 
       spi_write(flash_RSTATUS);delay_us(2);               
       status = spi_read(0);
       output_low(flash_sel);                 
       
       bitti_testi = bit_test(status,0);     
       return bitti_testi;
}

//***********************************************************************************************

void send_FLASH_address(void)         //läh. globaalin flash_addr osoitteen 24 bits  SPI-väylään
{
 
   int8 msb,mmsb,lsb; 
   
    msb =(flash_addr >> 16);
    mmsb = flash_addr >> 8;
    lsb= flash_addr;
 
 
 spi_write(msb); delay_us(2);     //MSB first
 spi_write(mmsb);delay_us(2);
 spi_write(lsb);delay_us(2);
 
 
}     

//***********************************************************************************************
 :)  :)
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Jan 17, 2012 1:39 pm     Reply with quote

a lot of code is missing here
- starting with the HOW you handle SPI setup / initialization.

also i am not seeing code on HOW you got the read back data you complain about. the code for the read_flash() function leaps to mind .......
more code needs to be known - before i could begin to comment on a possible fault with the "COMMENT FREE" driver code you have here.
artohautala



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

PostPosted: Tue Jan 17, 2012 2:13 pm     Reply with quote

asmboy wrote:
a lot of code is missing here
- starting with the HOW you handle SPI setup / initialization.

also i am not seeing code on HOW you got the read back data you complain about. the code for the read_flash() function leaps to mind .......
more code needs to be known - before i could begin to comment on a possible fault with the "COMMENT FREE" driver code you have here.


Ok thanks for your answer ...
here is my spi setup:
setup_spi(spi_master|spi_mode_0|spi_clk_div_64 );
and here is my code to read memory:
Code:

//***********************************************************************************************
int8 READ_flash(void)
{
      int8 read_data;
     
      output_high(flash_sel); delay_us(2);      //flash muisti ON
      spi_write(flash_READ);                    //flash READ ON
      send_FLASH_address();                     //lähetetään osoite
      read_data = spi_read(0);                  //luetaan data
      output_low(flash_sel);                    //flash muisti OFF
     
      return read_data;
}
//***********************************************************************************************
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Jan 17, 2012 5:18 pm     Reply with quote

what PIC ?
what #FUSES
what compiler version ?

a solution will come down to knowing what PIC pins are doing what for the pic control of the EEPROM CHIP enable and SPI control ( as hardware SPI is all that works with the spi_ functions you selected )

and then diagnosing what is wrong the way you try to communicate with it.

ie: whats wrong with this stab at a driver for the Serial EEPROM in question

each bit of extra info you post helps
don't be stingy ...

BTW have you read this ???

http://www.ccsinfo.com/forum/viewtopic.php?t=44460&highlight=m25p128

Very Happy Very Happy Shocked Arrow
artohautala



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

PostPosted: Tue Jan 17, 2012 11:00 pm     Reply with quote

asmboy wrote:
what PIC ?
what #FUSES
what compiler version ?

a solution will come down to knowing what PIC pins are doing what for the pic control of the EEPROM CHIP enable and SPI control ( as hardware SPI is all that works with the spi_ functions you selected )

and then diagnosing what is wrong the way you try to communicate with it.

ie: whats wrong with this stab at a driver for the Serial EEPROM in question

each bit of extra info you post helps
don't be stingy ...

BTW have you read this ???

http://www.ccsinfo.com/forum/viewtopic.php?t=44460&highlight=m25p128

Very Happy Very Happy Shocked Arrow


Yes my compiler version is 4.018 and I'm using pic18f452.
This is first line in main():
Code:

setup_spi(spi_master|spi_mode_0|spi_clk_div_64 ); //mode 0 tai 3

Here are fuses:
Code:

#include<18F452.h>
#include <string.h>

#use delay(clock = 20000000,restart_wdt)
#fuses HS,NOWDT,NOPROTECT         //oltava HS !

#zero_ram    //nollaa kaikki muuttujat alussa


Here are defines:
Code:

#include <graph_rutines.c>

#define RTC_SDA  PIN_C1            //reaalikellon datalinja
#define RTC_SCL  PIN_C0            //reaalikellon kellopulssi
#define MENU     PIN_A0            //ylempi näppäin, normally closed, tila on FALSE
#define SET      PIN_A1            //alempi näppäin, normally closed, tila on FALSE

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL, RESTART_WDT)

#define flash_SEL   PIN_C2         //flash-muistin chip select, testattu OK
#define flash_SCL   PIN_C3         //flash-muistin kellolinja, testattu OK
#define flash_MISO  PIN_C4         //flash-muistin serial out MISO (master in slave out)TEST OK
#define flash_MOSI  PIN_C5         //flash-muistin serial in MOSI (master out slave in)TEST OK

#define flash_WREN     0x06        //flash muistin write enable
#define PAGE_prog      0x02        //flash muistin page program enable
#define flash_RSTATUS  0x05        //flash muistin READ status osoite
#define flash_READ     0x03        //flash muistin READ enable
#define SEC_erase      0xD8        //flash muistin SECTOR ERASE
#define FULL_erase     0xC7        //flash muistin BULK ERASE

#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)
temtronic



Joined: 01 Jul 2010
Posts: 9218
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 18, 2012 6:45 am     Reply with quote

Let's see...

PIC18F452 is a 5 volt device

M25P128 is a 3 volt device

Do you have a proper logic level translation chip between these parts ?

Before you can debug the software, you have to be sure the hardware is correct.
artohautala



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

PostPosted: Wed Jan 18, 2012 7:12 am     Reply with quote

temtronic wrote:
Let's see...

PIC18F452 is a 5 volt device

M25P128 is a 3 volt device

Do you have a proper logic level translation chip between these parts ?

Before you can debug the software, you have to be sure the hardware is correct.

Thanks for your answer temtronic.
Yes I have logic converters.

I'm rather sure my hardware is ok because sector erase and bulk erase works. I can't program bits back to one's before I sector erase or bulk erase, and after erase I can write again. But problem is that first byte is in right address and it's ok but two following bytes are programmed also so I write 3 data bytes instead of one.
One thing I'm not sure if my logic converter rise and fall times are ok
datasheet of memory says min. 0.1 V /ns and it is rather fast.

Ok. This is link to my level converter schematic:
http://tinyurl.com/7ft6fvh

and this link is schematic:
http://tinyurl.com/76fo9rx
best regards
artohautala



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

PostPosted: Wed Jan 18, 2012 8:19 am     Reply with quote

artohautala wrote:
temtronic wrote:
Let's see...

PIC18F452 is a 5 volt device

M25P128 is a 3 volt device

Do you have a proper logic level translation chip between these parts ?

Before you can debug the software, you have to be sure the hardware is correct.

Thanks for your answer temtronic.
Yes I have logic converters.

I'm rather sure my hardware is ok because sector erase and bulk erase works. I can't program bits back to one's before I sector erase or bulk erase, and after erase I can write again. But problem is that first byte is in right address and it's ok but two following bytes are programmed also so I write 3 data bytes instead of one.
One thing I'm not sure if my logic converter rise and fall times are ok
datasheet of memory says min. 0.1 V /ns and it is rather fast.

Ok. This is link to my level converter schematic:
http://tinyurl.com/7ft6fvh

and this link is schematic:
http://tinyurl.com/76fo9rx
best regards


by the way ... same results also using x_fer function and this #use...:
#use spi(FORCE_HW,SAMPLE_RISE, BITS=8, stream=SPI_STREAM)
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Jan 18, 2012 8:34 am     Reply with quote

Think carefully about what is happening. You are trying to write one byte, it is actually writing more than one. What are the extra bytes? They are 05 00. What does that look like? It looks like a what you send in flash_busy()! So, it is interpreting the flash_busy status request as data to be written. The question is why?

Why indeed... well, if you look at your level convertor you have an open collector driver for the select. That produces a fast high to low transition at its output, but a slower low to high as the capacitance of the select pin (which we don't know: the data sheet doesn't tell us) has to be charged through your 1k5 pull-up resistor. So, we don't know what the low-high rise time is. What we do know is that you give just 2us after the write command before sending the flash_busy request. I'll bet what's happening is that its not rising in time and so the memory IC is thinking the flash_busy request is more data, which is writes. So, either use an active drive or wait longer after the write before asking for data. There's no point in asking for the first write status for a few ms anyway, as its going to take a long time to actually write. You want to ask first in the "maybe it has, maybe it hasn't" region, not as you are at the moment in the "No way, I've barely start to write yet!" region.

Most of your delay_us(2) are pointless any way. You only really need to do anything immediately after activating the select and immediately after deactivating it, to give time for it to rise. Get your oscilloscope out to check how long that really needs to be. You certainly don't need to wait between bytes.
artohautala



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

PostPosted: Wed Jan 18, 2012 9:17 am     Reply with quote

RF_Developer wrote:
Think carefully about what is happening. You are trying to write one byte, it is actually writing more than one. What are the extra bytes? They are 05 00. What does that look like? It looks like a what you send in flash_busy()! So, it is interpreting the flash_busy status request as data to be written. The question is why?

Why indeed... well, if you look at your level convertor you have an open collector driver for the select. That produces a fast high to low transition at its output, but a slower low to high as the capacitance of the select pin (which we don't know: the data sheet doesn't tell us) has to be charged through your 1k5 pull-up resistor. So, we don't know what the low-high rise time is. What we do know is that you give just 2us after the write command before sending the flash_busy request. I'll bet what's happening is that its not rising in time and so the memory IC is thinking the flash_busy request is more data, which is writes. So, either use an active drive or wait longer after the write before asking for data. There's no point in asking for the first write status for a few ms anyway, as its going to take a long time to actually write. You want to ask first in the "maybe it has, maybe it hasn't" region, not as you are at the moment in the "No way, I've barely start to write yet!" region.

Most of your delay_us(2) are pointless any way. You only really need to do anything immediately after activating the select and immediately after deactivating it, to give time for it to rise. Get your oscilloscope out to check how long that really needs to be. You certainly don't need to wait between bytes.


YES, that makes sense!
Now I think it works I tested it rapidly...

Thank you so much for your help Smile

I added 200us delay to the beginning of flash_busy function like this:
Code:

short int flash_busy(void) //testaa onko flash-muisti valmis TRUE jos ei valmis!
{
    int8 status;
    short int bitti_testi;
       
       delay_us(200);      //RECENTLY ADDED DELAY!
       output_high(flash_sel);                   //flash muisti ON
       spi_xfer(SPI_STREAM, flash_RSTATUS,8);
       status = spi_xfer(SPI_STREAM, 0,8);       
       output_low(flash_sel);                   //flash muisti OFF
       bitti_testi = bit_test(status,0);        //write in progress WIP bit jos valmis se on LOW
       return bitti_testi;
}
 :)
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