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");
 
      
 
   }
 
}
 
 | 	 
  | 
			 
		  |