unitrant
Joined: 18 Jul 2005 Posts: 9 Location: Hertfordshire. UK
|
Ramtron FRAM driver |
Posted: Sat May 20, 2006 6:22 am |
|
|
The following is a simple adaptation of CCS 24256.c driver to suit the fast handling of the Ramtron 24C256 I2C FRAM. This code is referenced in the test file as FM24c256.c
Code: |
// add/remove comments to select speed of I2C bus
//#define I2C_CLK 100000
//#define I2C_CLK 400000
#define I2C_CLK 1000000
#USE I2C(MASTER, FORCE_HW, SCL=PIN_C3, SDA=PIN_C4, FAST=I2C_CLK)
#ifdef __PCH__
#byte SSPSTAT=0xFC7 // change to suit 18F processor
#define SMP SSPSTAT,7 // 1=Slew for 100kHz & 1MHz 0=400kHz
#endif
#ifdef __PCM__
#byte SSPSTAT=0x94 // change to suit 16F processor
#define SMP SSPSTAT,7 // 1=Slew for 100kHz & 1MHz 0=400kHz
#endif
#define FRAM_ADDR_WR 0xA0
#define FRAM_ADDR_RD 0xA1
#define FRAM_SIZE 32768
#define I2C_WR_ACK 0 // ACK state when writing
#define I2C_RD_NAK 0 // CCS value to NAK on read
#define I2C_RD_ACK 1 // CCS value to ACK on read
void init_ext_fram()
{
if(I2C_CLK==1000000)
bit_set(SMP); // #USE I2C sets incorrectly
}
int1 write_ext_fram(int16 start_addr, int8 data)
{
int8 result;
if(start_addr <= FRAM_SIZE)
{
i2c_start();
i2c_write(FRAM_ADDR_WR);
i2c_write(start_addr>>8);
i2c_write(start_addr);
result=i2c_write(data);
i2c_stop();
return(result==I2C_WR_ACK);
}
return(FALSE);
}
int1 write_seq_fram(int16 start_addr, int8 *pntr, int16 count)
{
// Does not allow memory wrapping on write
int8 result;
if(start_addr+count <= FRAM_SIZE)
{
i2c_start();
i2c_write(FRAM_ADDR_WR);
i2c_write(start_addr>>8);
i2c_write(start_addr);
do
{
restart_wdt(); //uncomment if slow speeds
result=i2c_write(*pntr++);
if(result!=I2C_WR_ACK)
break;
}while(--count);
i2c_stop();
return(result==I2C_WR_ACK);
}
return(FALSE);
}
int8 read_ext_fram(int16 start_addr)
{
int8 data;
i2c_start();
i2c_write(FRAM_ADDR_WR);
i2c_write(start_addr>>8);
i2c_write(start_addr);
i2c_start();
i2c_write(FRAM_ADDR_RD);
data=i2c_read(I2C_RD_NAK);
i2c_stop();
return(data);
}
void read_seq_fram(int16 start_addr, int8 *pntr, int16 count)
{
// memory wrapping is allowed on reads
i2c_start();
i2c_write(FRAM_ADDR_WR);
i2c_write(start_addr>>8);
i2c_write(start_addr);
i2c_start();
i2c_write(FRAM_ADDR_RD);
do
{
restart_wdt(); // uncomment if slow speeds
*pntr++=i2c_read(I2C_RD_ACK);
}while(--count>1);
*pntr=i2c_read(I2C_RD_NAK);
i2c_stop();
}
|
And the code below is for testing it:
Code: |
#ifdef __PCM__
#include <16F876.h>
#opt 9
#device *=16
//#device ICD=TRUE
#device adc=8
#use fast_io(C)
#FUSES WDT //Watch Dog Timer
#FUSES HS
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES PUT //No Power Up Timer
#use delay(clock=20000000,RESTART_WDT)
//#use delay(clock=8000000,RESTART_WDT)
#use rs232(restart_wdt,baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#endif
#ifdef __PCH__
#include <18F252.h>
#device adc=8
#opt 9
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //8MHz + Osc
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=8000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors)
#endif
#include "FM24c256.c"
#ZERO_RAM
int8 buffer[64];
void main()
{
#ifdef __PCM__
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_wdt(WDT_144MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
init_ext_fram();
set_tris_c(0xBF);
//enable_interrupts(GLOBAL);
#endif
#ifdef __PCH__
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_bit);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_oscillator(False);
init_ext_fram();
set_tris_c(0xBF);
#endif
while(TRUE)
{
int16 i;
int8 j;
int1 result;
printf("\r\nTest running...\r\n\r\n");
restart_wdt();
// high speed write
for(i=0;i<FRAM_SIZE/64;i++)
{
j=0;
do
{
buffer[j]=j++;
}while(j<64);
write_seq_fram(i*64,buffer,64);
}
result=TRUE;
restart_wdt();
for(i=0;i<FRAM_SIZE/64;i++)
{
read_seq_fram(i*64,buffer,64);
j=0;
do
{
if(buffer[j]!=j++)
{
result=FALSE;
break;
}
}while(j<64);
}
if(result)
printf("Success\r\n");
else
printf("Failure\r\n");
}
}
|
|
|