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

Ramtron FRAM driver

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
unitrant



Joined: 18 Jul 2005
Posts: 9
Location: Hertfordshire. UK

View user's profile Send private message

Ramtron FRAM driver
PostPosted: Sat May 20, 2006 6:22 am     Reply with quote

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



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

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

PostPosted: Sun May 21, 2006 9:16 pm     Reply with quote

I put a driver in the library also.
A nice feature of mine it that it can span multi chips in the multi-read and multi-write.
http://www.ccsinfo.com/forum/viewtopic.php?t=24099
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Wed Mar 21, 2007 2:16 am     Reply with quote

Can this driver be used for smaller memory chips? What changes have to be made?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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