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

Using * and read write blocks M25P80

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



Joined: 23 Aug 2005
Posts: 93

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

Using * and read write blocks M25P80
PostPosted: Mon Jan 12, 2009 7:38 am     Reply with quote

Hi, got a problem reading and writing to a M25P80 serial flash memory.
I think Im thinking wrong Confused
Using a PIC18F4550. And M25P80 driver mentioned on this forum..
Code:

/** @} */
#include "save_mem.h"
/**
 *  @defgroup flash Flash Manager
 *  Functions to control the ST MP25P80 serial flash device.
 */

/**
 *   Determine if a flash write or erase operation is currently in progress.
 *
 *   @return true if write/erase in progress
 */
bool_t flashIsWriteInProgress()
{
    uint8_t status;

    output_low (FLASH_CS);

    // Read Status Register (RDSR) flash command.
    flashSendByte (0x05);

    status = flashGetByte();

    output_high (FLASH_CS);

    return (((status & 0x01) == 0x01) ? true : false);
}

/**
 *   Read a block of memory from the flash device.
 *
 *   @param address of desired location in the range 0x00000 to 0xFFFFF (1MB)
 *   @param block pointer to locate of data block
 *   @param length number of bytes to read
 */
void flashReadBlock(uint32_t address, uint8_t *block, uint16_t length)
{
    uint16_t i;
   
    output_low (FLASH_CS);

    // Read Data Byte(s) (READ) flash command.
    flashSendByte (0x03);
    flashSendAddress (address);
   
    for (i = 0; i < length; ++i)
        *block++ = flashGetByte();
   
    output_high (FLASH_CS);
}

/**
 *   Write a block of memory to the flash device.
 *
 *   @param address of desired location in the range 0x00000 to 0xFFFFF (1MB)
 *   @param block pointer data block to write
 *   @param length number of bytes to write
 */
void flashWriteBlock(uint32_t address, uint8_t *block, uint8_t length)
{
    uint8_t i;

    output_low (FLASH_CS);
    // Write Enable (WREN) flash command.
    flashSendByte (0x06);
    output_high (FLASH_CS);
   
    output_low (FLASH_CS);
    // Page Program (PP) flash command.
    flashSendByte (0x02);
    flashSendAddress (address);
   
    for (i = 0; i < length; ++i)
    {
        // Send each byte in the data block.
        flashSendByte (*block++);

        // Track the address in the flash device.
        ++address;

        // If we cross a page boundary (a page is 256 bytes) we need to stop and send the address again.
        if ((address & 0xff) == 0x00)
        {
            output_high (FLASH_CS);

            // Write this block of data.
            while (flashIsWriteInProgress());

            output_low (FLASH_CS);
            // Write Enable (WREN) flash command.
            flashSendByte (0x06);
            output_high (FLASH_CS);

            output_low (FLASH_CS);
            // Page Program (PP) flash command.
            flashSendByte (0x02);
            flashSendAddress (address);
        } // END if
    } // END for   

    output_high (FLASH_CS);

    // Wait for the final write operation to complete.
    while (flashIsWriteInProgress());
}

/**
 *   Erase the entire flash device (all locations set to 0xff).
 */
void flashErase()
{
    output_low (FLASH_CS);
    // Write Enable (WREN) flash command.
    flashSendByte (0x06);
    output_high (FLASH_CS);
   
    output_low (FLASH_CS);
    // Bulk Erase (BE) flash command.
    flashSendByte (0xc7);
    output_high (FLASH_CS);

    while (flashIsWriteInProgress());
}

/**
 *   Read a single byte from the flash device through the serial interface.  This function
 *   only controls the clock line.  The chip select must be configured before calling
 *   this function.
 *
 *   @return byte read from device
 */
uint8_t flashGetByte()
{
    uint8_t i, value;
   
    value = 0;     
   
    // Bit bang the 8-bits.
    for (i = 0; i < 8; ++i)
    {
        // Data is ready on the rising edge of the clock.
        output_high (FLASH_CLK);

        // MSB is first, so shift left.
        value = value << 1;
   
        if (input (FLASH_Q))
            value = value | 0x01;
   
        output_low (FLASH_CLK);
    } // END for

    return value;
}

/**
 *   Initialize the flash memory subsystem.
 */
void flashInit()
{
    // I/O lines to control flash.
    output_high (FLASH_CS);
    output_low (FLASH_CLK);
    output_low (FLASH_D);
}

/**
 *   Write a single byte to the flash device through the serial interface.  This function
 *   only controls the clock line.  The chip select must be configured before calling
 *   this function.
 *
 *   @param value byte to write to device
 */
void flashSendByte(uint8_t value)
{
    uint8_t i;
   
    // Bit bang the 8-bits.
    for (i = 0; i < 8; ++i)
    {
        // Drive the data input pin.
        if ((value & 0x80) == 0x80)
            output_high (FLASH_D);
        else
            output_low (FLASH_D);
       
        // MSB is first, so shift leeft.
        value = value << 1;
       
        // Data is accepted on the rising edge of the clock.
        output_high (FLASH_CLK);
        output_low (FLASH_CLK);
    } // END for
}

/**
 *    Write the 24-bit address to the flash device through the serial interface.  This function
 *   only controls the clock line.  The chip select must be configured before calling
 *   this function.
 *
 *   @param address 24-bit flash device address
 */
void flashSendAddress(uint32_t address)
{
    uint8_t i;
   
    // Bit bang the 24-bits.
    for (i = 0; i < 24; ++i)
    {
        // Drive the data input pin.
        if ((address & 0x800000) == 0x800000)
            output_high (FLASH_D);
        else
            output_low (FLASH_D);
       
        // MSB is first, so shift left.
        address = address << 1;

        // Data is accepted on the rising edge of the clock.
        output_high (FLASH_CLK);
        output_low (FLASH_CLK);
    } // END for
}


But how do I use this driver, for example reading 256 bytes??
Code:

void print_all_mem(void)
{
byte out_buffer[256];
int32 my_adress = 0;
int16 i = 0;

my_adress=ee_adress; //last used

   for(i=256;i>0;i--){
    flashReadBlock(my_adress,out_buffer[i],8);
   }   
   printf("Saved data: %s",out_buffer);
}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Mon Jan 12, 2009 8:51 am     Reply with quote

Code:

void print_all_mem(void)
{
byte out_buffer[256];
int32 my_adress = 0;
int16 i = 0;

my_adress=ee_adress; //last used
    flashReadBlock(my_adress,out_buffer,256); // Read 256 byte of flash starting at my_adress, store in out_buffer

   printf("Saved data: ");
   for(i=0; i<256; i++){
     printf("%x ",out_buffer[i]);  // Display data as hex, not sure if it is a string or not !
   }   
}


Note I show the data as hex. To display it as a string requires it to be null terminated, If a null IS encountered then it will display data upto that point BUT unless that data contains printable characters you will see garbage.
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Mon Jan 12, 2009 9:19 am     Reply with quote

Ok, thanks, i did manage to get out the stuff, altough I really havent write anything in it yet Laughing
Thats my next question, in what way shold this memory be written to?
do it have to be blocks? or can I write byte by byte and read them also as byte by byte, or how to store and read ints, floats?
If I would like to store a float for example,
Code:

flashWriteBlock(adress,my_float,4); // to adress xx, my float value, length 4 bytes?
     adress+=4;
flashWriteBlock(adress,my_float,4);
//and so on??

And to read the float?
Code:

float my_float=0;
flashReadBlock(my_adress,my_float,4);

/Tagge
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Mon Jan 12, 2009 9:30 am     Reply with quote

The functions flashWriteBlock and flashReadBlock require an address of a variable or array, this is what the * refers to in the definition
void flashReadBlock(uint32_t address, uint8_t *block, uint16_t length)

So to read and write floats, ints or other vars you would use
flashWriteBlock(adress, &my_float, 4);
notice the & symbol, this means pass the address of the var my_float to the function.

A string is an array of chars (ints on a pic) so passing the array name is the same as passing the address of the start of the array.

char my_string[4];
flashWriteBlock(adress, my_string, 4);

A flash device usually has several operating modes, normally you do not need to worry about them and using a driver to write to any address will solve any problems. But for your info, a flash device has to erase its memory before writing to it, This usually is done in blocks, so writing blocks of data is usually quicker if your block size and start address is on a block boundary. This is quite hard to manage. Flash devices also have a limited number of writes and erases you can perform on them so some sort of management code would increase this, especially if you are only using a small block of memory.
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Fri Jan 16, 2009 12:59 pm     Reply with quote

Still having a problem, most probably with understanding Confused
It seems that only rubbish or nothing at all is saved and/or read from the flash.
I have also tryed to erase the entire flash everytime before writing, but no luck
Thanks/Tagge


Last edited by Tagge on Sat Jan 17, 2009 3:43 pm; edited 1 time in total
Guest








PostPosted: Sat Jan 17, 2009 2:39 pm     Reply with quote

Any words on performance?
Tagge



Joined: 23 Aug 2005
Posts: 93

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

PostPosted: Sat Jan 17, 2009 3:41 pm     Reply with quote

Figured it out at last Smile
No need for pull-ups or else.
And the driver from the start of this tread is ok.
Its just that this sort of flash needs to be erased before writing!
And that wasnt properly done in my application.

So to write for example a float is just:
flashWriteBlock(adress, &my_float, 4);

and to read is as simple:
flashReadBlock(address, my_float, 4)

But erase the flash before writing to it!

Thanks wayne_
/Tagge
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