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

93C56LN EEPROM Reading/Writing Data

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mytolocia



Joined: 11 Jun 2016
Posts: 1

View user's profile Send private message

93C56LN EEPROM Reading/Writing Data
PostPosted: Wed Oct 05, 2016 6:57 am     Reply with quote

I have PIC18F25J11 and NS93C56LN Serial EEPROM. My aim is to write a data to an address of EEPROM and read it back properly. Unfortunately, i get irrelevant values (i print them to LCD).

And yes, CCS has driver for "9356"(which didn't work for me) but i have 93C56LN which belongs to "National Semiconductor" and the CCS one is for Microchip version (i assume). So i decided to write my own C file by inspiring from what i read on this forum (bitbanging etc, thanks to Asmboy).

Here is the code. Hope i can find what i am doing wrong. Thank you in advance.
Code:

#include <main.h>
#include <9356_5.c>
#include <LCD.c>
int16 a;
int8 address=0b00001111;
int16 data=0b0000000000000011; // ilgili adrese 3 yaz

void main()
{

setup_comparator(NC_NC_NC_NC); // C portunun üzerindeki comparatoru kapat.

Enable_ext_EEPROM();
delay_ms(10);
write_ext_eeprom(address,data);
   while(TRUE)
   {

a = read_ext_eeprom(address);
printf(lcd_putc,"\f %Lu",a);
delay_ms(1000);

   
   }

}


<9356_5.c>
Code:

#define EEPROM_SELECT PIN_C2
#define EEPROM_CLK    PIN_C3
#define EEPROM_DI     PIN_C4
#define EEPROM_DO     PIN_C5

void Enable_ext_EEPROM()
{
   int i;
   unsigned int16 work=0b10011000000; //  S(1) + OP(00) + 11XXXXXX
   #bit pob=work.15
   output_low(EEPROM_DI);
   delay_cycles(4);
   output_low(EEPROM_CLK);
   delay_cycles(4);
   output_low(EEPROM_SELECT);
   delay_cycles(4);
   output_high(EEPROM_SELECT);
   
   for(i=1;i<=11;++i)
   {
     delay_cycles(2);
     if(pob)  output_high(EEPROM_DI );
      else     output_low(EEPROM_DI);
      output_high(EEPROM_CLK);
     work <<=1;
      output_low(EEPROM_CLK);
   }
   output_low(EEPROM_SELECT);
   delay_cycles(4);
   output_low(EEPROM_DI);
}

void Disable_ext_EEPROM()
{
   int cmd[2];
   int i;

   output_low(EEPROM_DI);
   output_low(EEPROM_CLK);
   output_low(EEPROM_SELECT);

   cmd[0]=0x00;
   cmd[1]=0x08;

   for(i=1;i<=4;++i)
      shift_left(cmd,2,0);
   output_high(EEPROM_SELECT);
   for(i=1;i<=12;++i)
   {
      output_bit(EEPROM_DI, shift_left(cmd,2,0));
      output_high(EEPROM_CLK);
      output_low(EEPROM_CLK);
   }
   output_low(EEPROM_DI);
   output_low(EEPROM_SELECT);
}


void write_ext_eeprom(int8 address, int16 data)
{
   
   int i,k,z;
   unsigned int8 work=0b10100000;
   #bit pob=work.7
   #bit pob2=address.7
   #bit pob3=data.15
   
   output_high(EEPROM_SELECT);
   delay_cycles(4);
   for(i=1;i<=4;++i) // S(1) + OP(01) + A7(dont care- 0);
   {
     delay_cycles(2);
     if(pob)  output_high(EEPROM_DI );
      else     output_low(EEPROM_DI);
      output_high(EEPROM_CLK);
     work <<=1;
      output_low(EEPROM_CLK);
   }
   for(i=k;k<=7;++k) // Address A6-A0
   {
     delay_cycles(2);
     if(pob2)  output_high(EEPROM_DI );
      else     output_low(EEPROM_DI);
      output_high(EEPROM_CLK);
     address <<=1;
      output_low(EEPROM_CLK);
   }
   for(z=1;z<=16;++z) // Data A15-A0
   {
     delay_cycles(2);
     if(pob3)  output_high(EEPROM_DI );
      else     output_low(EEPROM_DI);
      output_high(EEPROM_CLK);
     data <<=1;
      output_low(EEPROM_CLK);
   }
   output_low(EEPROM_SELECT);
   delay_cycles(2);
   //output_low(EEPROM_DI);
   
   
}

int16 read_ext_eeprom(int8 address)
{
   int i,k,z;
   int16 data;
   unsigned int8 work=0b11000000;
   #bit pob=work.7
   #bit pob2=address.7

   output_high(EEPROM_SELECT);
   
   for(i=1;i<=4;++i) // S(1) + OP(10) + A7 (dont care - 0 )
   {
     delay_cycles(2);
     if(pob)  output_high(EEPROM_DI );
      else     output_low(EEPROM_DI);
      output_high(EEPROM_CLK);
     work <<=1;
      output_low(EEPROM_CLK);
   }
   
   for(k=1;k<=7;++k) //A6-A0 Address
   {
     delay_cycles(2);
     if(pob2)  output_high(EEPROM_DI );
      else     output_low(EEPROM_DI);
      output_high(EEPROM_CLK);
     address <<=1;
      output_low(EEPROM_CLK);
   }
   for(z=1;z<=16;z++){  // D15-D0 Okuma
         shift_left(&data,2,input(EEPROM_DO));
         output_low(EEPROM_CLK);  // CLOCK düşün kenarında EEPROM'dan data geliyor.
         output_high(EEPROM_CLK);
   }
   output_low(EEPROM_SELECT);
   return(data);
}
}


Operation Table

93C56LN Datasheet :
panda-bg.com/datasheet/1562-050607-93C56LN-NS.pdf
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 05, 2016 12:37 pm     Reply with quote

Quote:
And yes, CCS has driver for "9356"(which didn't work for me) but i have
93C56LN which belongs to "National Semiconductor" and the CCS one is
for Microchip version (i assume).

Can you post a list of the differences that you noticed between the
Microchip eeprom and the National Semiconductor one ?
I could do it by comparing the data sheets, but if you've already done it,
then it would be easier if you posted the list.

I wrote a software SPI driver for the Microchip 93LC56B (x16 org).
See if this works for you:
http://www.ccsinfo.com/forum/viewtopic.php?t=38064
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Thu Oct 06, 2016 1:47 am     Reply with quote

There is a comment. Use delay_us, not delay_cycles.

I can't tell how long any of the delays actually are. He doesn't post his clock line. The PIC could be running at 48MHz. If so, delay_cycles(4), gives 4/12000000 sec. 0.33uSec. The chip has a minimum tCs, of 1uSec.... Crying or Very sad

Why fiddle going DIY?. CCS has a nice software SPI driver available for you in #USE SPI (this can be set to use software or hardware), and in software mode this can do variable length operations. The whole thing can be done in about twenty lines using CCS code, with a much higher chance of success. DIY solutions were necessary some years ago, but with the #USE, have become rather pointless.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Thu Oct 06, 2016 2:52 am     Reply with quote

I've taken a few minutes, to type in a basic test program to show what I mean:

Code:

#include <18F25J11.h>
//test driver for National NM9356/66
#device ADC=10
#fuses NOWDT, NOXINST, STVREN
#fuses INTRC_PLL_IO, NOFCMEN, NOPROTECT
#fuses NOIOL1WAY, LPT1OSC

#use delay(internal=32MHz)
//Basic debugging setup, maximum clock rate on internal oscillator
#use RS232(UART1, baud=9600, parity=N, bits=8, ERRORS)
//standard RS232 I/O

#define EEPROM_CS     PIN_C2
#define EEPROM_CLK    PIN_C3
#define EEPROM_DI     PIN_C4
#define EEPROM_DO     PIN_C5 //connection names at the memory

#use SPI(DO=EEPROM_DI, DI=EEPROM_DO, CLK=EEPROM_CLK, MODE=0, FORCE_SW, STREAM=NM93)
//setup SPI. My output to input on chip, input to output etc..
//by default will clock as fast as possible (chip supports 3MHz).
//Microwire is mode0 only.

#define READ93 (int16)0b11000000000
#define WRITE93 (int16)0b10100000000
#define WEN93 (int16)0b10011000000
#define ERASE93 (int16)0b11100000000
#define ERAL93 (int16)0b10010000000
#define WRALL93 (int16)0b10001000000
#define WDS93 (int16)0b10000000000
//NM93C56/66 instructions
#define NM93C66 FALSE //set TRUE to use 66, instead of 56

void enable_write93(void)
{
   //enable write mode
   output_high(EEPROM_CS);
   spi_xfer(NM93, WEN93, 11); //clock out 11 bit write enable command
   output_low(EEPROM_CS);
}

void disable_write93(void)
{
   //disable write mode
   output_high(EEPROM_CS);
   spi_xfer(NM93, WDS93, 11); //clock out 11 bit write disable command
   output_low(EEPROM_CS);   
}

int16 ReadWord_from93(int8 address)
{
   //read a 16bit word from chip 7 bit address for 56, or 8 for 66
   int16 tempL;
   if (!NM93C66)
      address &= 0x7F; //only 7 bit addresses for 56
   output_high(EEPROM_CS);
   spi_xfer(NM93, READ93 | address, 11); //clock out 11 bits
   tempL=spi_xfer(NM93, 0L, 11);
   output_low(EEPROM_CS);
   return tempL;
}

int1 WriteWord_to93(int8 address, int16 data)
{
   //write a 16 bit word to chip
   int1 status;
   int8 loop=0;
   if (!NM93C66)
      address &= 0x7F; //only 6 bit addresses for 56
   enable_write93(); //enable write mode   
     
   output_high(EEPROM_CS);
   spi_xfer(NM93, WRITE93 | address, 11); //clock out 11 bits
   spi_xfer(NM93, data, 16); //send 16 bits of data
   output_low(EEPROM_CS);
   do
   {//Modifying to wait for status high - should be up to 10mSec
       delay_ms(1);
       output_high(EEPROM_CS);
       //our DI is now the status from the chip

       status = input(EEPROM_DO);
       output_low(EEPROM_CS); //deselect again
   } while ((status==0) && (++loop<12));
   //should get here before 12 counts, with status==1
   //if reach here with status==0, there has been a problem
   //Now need to disable write mode
   delay_us(1);
   disable_write93();
   
   return status;
}


void main()
{
   int16 val16;
   int16 tostore=0xAA55; //initial test value
   int1 status;
   output_low(EEPROM_CS); //ensure starts with CS low.
   output_low(EEPROM_CLK); //and clock
   while(TRUE)
   {
      //Now a basic test.
      //First try reading address 0
      val16=ReadWord_from93(0);
      //send to serial
      printf("First time chip = %Lu\r\n",val16);
      //now try changing this, and get the chip's status after command
      status=WriteWord_to93(0, tostore++);
      //change the value so loop will give different on second pass
     
      //Read the value again to see if it worked
      val16=ReadWord_from93(0);
      //display what happened.
      printf("status = %u, read back %Lu\r\n", status, val16);

      //Now stop, and only repeat if a 'line feed' is sent on serial
      while (getc() != '\n')
         ;
   }
}


Haven't got a chip handy to test, but this should be close to right.

Have just modified the code to test the chip status at 1mSec intervals, and exit the write as soon as this goes high. Should be faster than just waiting. If it stays low for >10mSec, then there is a problem (will timeout at 12mSec), and exit.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion 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