|
|
View previous topic :: View next topic |
Author |
Message |
rrb011270
Joined: 07 Sep 2003 Posts: 51
|
Ramtron FRAM FM24C256 |
Posted: Mon Sep 08, 2003 9:55 pm |
|
|
Mabuhay!
Does anybody have a sample code snippets regarding the read/write routines of FM24C256 using I2C protocol?
Any help will do regarding on how to use this chip using PIC18452 and CCS C-compiler with ICD-S.
I'll appreciate any help.
Thnx |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 09, 2003 12:22 am |
|
|
You can use the CCS driver file, 24256.C. But because the FRAM part
doesn't have a write delay time, you don't need the "ack polling" code
which is at the end of the CCS write routine.
Do you have the compiler ? If so, the 24256.C driver file will be here:
c:\Program Files\Picc\Drivers
In the following routine, you can comment out the "ack polling" code,
since it's not needed. I've done that below.
void write_ext_eeprom(long int address, byte data)
{
// short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
// i2c_start();
// status=i2c_write(0xa0);
// while(status==1)
// {
// i2c_start();
// status=i2c_write(0xa0);
// }
}
The sample CCS driver uses pins B1 and B0 for SDA and SCL.
You may want to change this to pins C4 and C3. This would give
you the option of using hardware i2c, which can run much faster
than software i2c. The FRAM chip can run at a much faster i2c
clock speed than an ordinary EEPROM.
------------
Edited to disable smilies. The line with the right-shift by 8 had
the smilie with the sunglasses inserted at the end. |
|
|
Guest
|
|
Posted: Tue Sep 09, 2003 1:23 am |
|
|
Is there a difference in the coding in using read/write routine if I am change the I2C setting from software to hardware?
Can u also provide me a simple code snippets that will use both the read/write routine?
Thanx
====================================
PCM programmer wrote: | You can use the CCS driver file, 24256.C. But because the FRAM part
doesn't have a write delay time, you don't need the "ack polling" code
which is at the end of the CCS write routine.
Do you have the compiler ? If so, the 24256.C driver file will be here:
c:\Program Files\Picc\Drivers
In the following routine, you can comment out the "ack polling" code,
since it's not needed. I've done that below.
void write_ext_eeprom(long int address, byte data)
{
// short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
// i2c_start();
// status=i2c_write(0xa0);
// while(status==1)
// {
// i2c_start();
// status=i2c_write(0xa0);
// }
}
The sample CCS driver uses pins B1 and B0 for SDA and SCL.
You may want to change this to pins C4 and C3. This would give
you the option of using hardware i2c, which can run much faster
than software i2c. The FRAM chip can run at a much faster i2c
clock speed than an ordinary EEPROM.
------------
Edited to disable smilies. The line with the right-shift by 8 had
the smilie with the sunglasses inserted at the end. |
|
|
|
rrb011270
Joined: 07 Sep 2003 Posts: 51
|
|
Posted: Tue Sep 09, 2003 1:33 am |
|
|
PCM programmer wrote: | You can use the CCS driver file, 24256.C. But because the FRAM part
doesn't have a write delay time, you don't need the "ack polling" code
which is at the end of the CCS write routine.
Do you have the compiler ? If so, the 24256.C driver file will be here:
c:\Program Files\Picc\Drivers
In the following routine, you can comment out the "ack polling" code,
since it's not needed. I've done that below.
void write_ext_eeprom(long int address, byte data)
{
// short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
// i2c_start();
// status=i2c_write(0xa0);
// while(status==1)
// {
// i2c_start();
// status=i2c_write(0xa0);
// }
}
The sample CCS driver uses pins B1 and B0 for SDA and SCL.
You may want to change this to pins C4 and C3. This would give
you the option of using hardware i2c, which can run much faster
than software i2c. The FRAM chip can run at a much faster i2c
clock speed than an ordinary EEPROM.
------------
Edited to disable smilies. The line with the right-shift by 8 had
the smilie with the sunglasses inserted at the end. |
Is there a difference in the coding in using read/write routine if I am going to change the I2C setting from software to hardware?
What would be the complete syntax in using I2C?
e.g #use i2c(master, .....)
Can u also provide me a simple code snippets that will use both the read/write routine? both in software and hardware?
Thanx |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 09, 2003 7:59 pm |
|
|
Here is a sample program that can be configured for either software
i2c or hardware i2c. Just comment out the appropriate #use i2c
statement. If you want to use these routines with the FM24C64,
then you can remove the "delay_ms(6);" statements in this code.
They are not needed with the FRAM chip.
// 24LC256.c -- Test program for the 24LC256 (32kb) eeprom.
// i2c clock speed with PCM vs. 2.734 (16F877 at 8 MHz):
// Software i2c
// SLOW: 62.5 KHz
// FAST: 62.5 KHz (same as slow speed)
// Hardware i2c
// SLOW: 98 KHz
// FAST: 362 KHz
// Note that with H/W i2c, the clock has an inverted duty cycle.
// This violates the i2c spec, but it appears to work OK anyway.
//-------------------------------------------------------------------------
// INCLUDE FILES
#include "16F877.h"
#device *=16
//------------------------------------------------------------------------
// DEFINES
#define EEPROM_PAGE_LEN 64 // Page length in bytes
#define EEPROM_PAGE_COUNT 512 // Nunber of pages in eeprom
#define EEPROM_I2C_WRITE_ADDR 0xA0
#define EEPROM_I2C_READ_ADDR 0xA1
//---------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use Delay(Clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// #use i2c(Master, SDA=PIN_C4, SCL=PIN_C3) // Software i2c
#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW) // Hardware i2c
#zero_ram
//--------------------------------------------------------------------------
// GLOBALS
char random_byte;
char page_write_buffer[EEPROM_PAGE_LEN];
char page_read_buffer[EEPROM_PAGE_LEN];
#byte SSPCON = 0x14
#byte SSPADD = 0x93
//---------------------------------------------------------------------------
// FUNCTION PROTOTYPES
void write_eeprom_byte(long addr, char data);
char read_eeprom_byte(long addr);
void write_eeprom_block(long addr, char block_len, char* in_buffer);
void read_eeprom_block(long addr, char block_len, char* out_buffer);
void erase_eeprom_page(long page);
void erase_eeprom(void);
void power_up_init(void);
char rand(void);
void srand(char seed);
void fill_page_buffer(char *ptr, char count);
//===========================================================================
void main()
{
char i;
long addr;
char value_read;
char random_value;
long page;
power_up_init();
printf("Erasing\n\r");
erase_eeprom();
// Verify that the eeprom was erased.
printf("\n\rVerify erase\n\r");
addr = 0;
for(page = 0; page < EEPROM_PAGE_COUNT; page++)
{
read_eeprom_block(addr, EEPROM_PAGE_LEN, page_read_buffer);
for(i = 0; i < EEPROM_PAGE_LEN; i++)
{
value_read = page_read_buffer[i];
if(value_read != 0)
printf("addr %lx wrote %02x read %02x\n\r", addr +i, 0, value_read);
}
addr += EEPROM_PAGE_LEN;
// Display an activity dot every 8 pages.
if((page % 8) == 0)
putc('.');
}
//---------------------------------------------
// Fill the entire EEPROM with random data.
printf("\n\rWriting\n\r");
// Init the random seed.
srand(0x55);
addr = 0;
for(page = 0; page < EEPROM_PAGE_COUNT; page++)
{
fill_page_buffer(page_write_buffer, EEPROM_PAGE_LEN);
write_eeprom_block(addr, EEPROM_PAGE_LEN, page_write_buffer);
addr += EEPROM_PAGE_LEN;
// Display an activity dot every 8 pages.
if((page % 8) == 0)
putc('.');
}
//-----------------------------------
// Read the data back and verify it.
printf("\n\rReading\n\r");
// Reset the randomizer.
srand(0x55);
addr = 0;
for(page = 0; page < EEPROM_PAGE_COUNT; page++)
{
fill_page_buffer(page_write_buffer, EEPROM_PAGE_LEN);
read_eeprom_block(addr, EEPROM_PAGE_LEN, page_read_buffer);
for(i = 0; i < EEPROM_PAGE_LEN; i++)
{
random_value = page_write_buffer[i];
value_read = page_read_buffer[i];
if(value_read != random_value)
printf("addr %lx wrote %02x read %02x\n\r", addr +i, random_value, value_read);
}
addr += EEPROM_PAGE_LEN;
// Display an activity dot every 8 pages.
if((page % 8) == 0)
putc('.');
}
printf("\n\rTest Done\n\r");
while(1);
}
//==============================================================================
void power_up_init(void)
{
output_high(PIN_C1); // Do this for a test. See if running i2c sets this low somehow.
output_low(PIN_C2); // Set the EEPROM's write protect pin low (write enabled)
output_float(PIN_C3); // Set both i2c pins as inputs
output_float(PIN_C4);
output_float(PIN_C7); // Set RS-232 Rx pin as an input
output_high(PIN_C6); // Set RS-232 Tx pin as an output
}
//-----------------------------------------------------------------------------
void write_eeprom_byte(long addr, char data)
{
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_write(data);
i2c_stop();
delay_ms(6); // Wait enough time for the write to occur
}
//-------------------------------------------------------------------------------
// This will write a block of bytes. The length can be from 1 to the page length.
// If the starting address and count are such that the bytes extend past the page,
// then the eeprom will internally wrap the address ptr around, and overwrite the
// bytes at the start of the page.
void write_eeprom_block(long addr, char block_len, char* in_buffer)
{
char i;
if(block_len == 0)
return;
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
for(i = 0; i < block_len; i++)
{
i2c_write(*in_buffer++);
}
i2c_stop();
delay_ms(6); // Wait enough time for the write to occur
}
//-------------------------------------------------------------------------------
char read_eeprom_byte(long addr)
{
char data;
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_start();
i2c_write(EEPROM_I2C_READ_ADDR);
data = i2c_read(0);
i2c_stop();
return(data);
}
//-------------------------------------------------------------------------------
void read_eeprom_block(long addr, char block_len, char* out_buffer)
{
char i;
char count;
if(block_len == 0)
return;
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_start();
i2c_write(EEPROM_I2C_READ_ADDR);
count = block_len -1;
for(i = 0; i < count; i++)
{
*out_buffer++ = i2c_read();
}
*out_buffer = i2c_read(0); // Last byte read must have no ACK
i2c_stop();
}
//-------------------------------------------------------------------------------------
// Erase one page (64 bytes) of the eeprom. The page can be from 0 to 511.
// The page is filled with zeros.
void erase_eeprom_page(long page)
{
char i;
long addr;
addr = (page << 6); // Convert page address to a byte address (multiply by 64)
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
for(i = 0; i < EEPROM_PAGE_LEN; i++)
{
i2c_write(0); // Fill page with all zeros
}
i2c_stop();
delay_ms(6);
}
//-------------------------------------------------------------------------------------
// Erase the entire eeprom by filling it with zeros.
void erase_eeprom(void)
{
long page;
for(page = 0; page < EEPROM_PAGE_COUNT; page++)
{
erase_eeprom_page(page);
// Display an activity dot every 8 pages.
if((page % 8) == 0)
{
putc('.');
}
}
}
//-------------------------------------------------------------------------------
// This function returns a random number.
// The sequence repeats after 255 calls.
// The srand() function should be called once, before starting
// a series of calls to this function.
//
// To create a random number, we calculate the parity on
// a byte that has been ANDed with 0xb4. We then shift that
// parity bit into the LSB of the byte.
char rand(void)
{
char sum;
sum = 0;
// This calculates parity on the selected bits (mask = 0xb4).
if(random_byte & 0x80)
sum = 1;
if(random_byte & 0x20)
sum ^= 1;
if(random_byte & 0x10)
sum ^= 1;
if(random_byte & 0x04)
sum ^= 1;
random_byte <<= 1;
random_byte |= sum;
return(random_byte);
}
//------------------------------------------------------------------------------------
// Set the randomizer's seed value.
void srand(char seed)
{
random_byte = seed;
}
//----------------------------------------------------------------------------------
// Fill the page buffer with random data.
void fill_page_buffer(char *ptr, char count)
{
char i;
for(i = 0; i < count; i++)
{
*ptr++ = rand();
}
}
// end of program |
|
|
Guest
|
|
Posted: Tue Sep 09, 2003 8:53 pm |
|
|
Mabuhay!
I review the code uv shared and found out it will do a read/write test on the eeprom randomly...
If for example I want to read/write test a certain block(64bytes) using the following procedure:
1] write 0x55 to block
2] read 0x55 to block
3] write 0xAA to block
4] read 0xAA to block
5] provide a complete command
How can I modify the code uv shared? how can I change the srand(0x55) to use 0xAA? or is there another way to do it?
Thanx |
|
|
Guest
|
|
Posted: Wed Sep 10, 2003 1:58 am |
|
|
Mabuhay!
#byte SSPCON = 0x14
#byte SSPADD = 0x93
What is the purpose of this instructions above?
What would be the changes of this code if I have more than 3 serial EEPROM 24LC256 or FM24C256? using an I2C protocol?
a sample code snippet will help.
Thanx |
|
|
Guest
|
|
Posted: Wed Sep 10, 2003 8:06 am |
|
|
original code:
#define EEPROM_PAGE_LEN 64 // Page length in bytes
#define EEPROM_PAGE_COUNT 512 // Nunber of pages in eeprom
change to:
#define EEPROM_PAGE_LEN 32 // Page length in bytes
#define EEPROM_PAGE_COUNT 1024 // Nunber of pages in eeprom
#device *=16 ---> wat is the purpose on this instruction?
original code:
// Erase one page (64 bytes) of the eeprom. The page can be from 0 to 511.
// The page is filled with zeros.
addr = (page << 6); // Convert page address to a byte address (multiply by 64)
change to:
addr = (page << 5); // Convert page address to a byte address (multiply by 32)
Is my modification correct? for a 32bytes page size and 1025 page count?
any help will do.
tenkyu |
|
|
|
|
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
|