|
|
View previous topic :: View next topic |
Author |
Message |
Tagge
Joined: 23 Aug 2005 Posts: 93
|
Using * and read write blocks M25P80 |
Posted: Mon Jan 12, 2009 7:38 am |
|
|
Hi, got a problem reading and writing to a M25P80 serial flash memory.
I think Im thinking wrong
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
|
|
Posted: Mon Jan 12, 2009 8:51 am |
|
|
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
|
|
Posted: Mon Jan 12, 2009 9:19 am |
|
|
Ok, thanks, i did manage to get out the stuff, altough I really havent write anything in it yet
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
|
|
Posted: Mon Jan 12, 2009 9:30 am |
|
|
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
|
|
Posted: Fri Jan 16, 2009 12:59 pm |
|
|
Still having a problem, most probably with understanding
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
|
|
Posted: Sat Jan 17, 2009 2:39 pm |
|
|
Any words on performance? |
|
|
Tagge
Joined: 23 Aug 2005 Posts: 93
|
|
Posted: Sat Jan 17, 2009 3:41 pm |
|
|
Figured it out at last
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 |
|
|
|
|
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
|