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 support@ccsinfo.com

Calculation of variables in external EEPROM bytes

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



Joined: 04 Feb 2014
Posts: 9

View user's profile Send private message

Calculation of variables in external EEPROM bytes
PostPosted: Fri Feb 07, 2014 10:57 pm     Reply with quote

Calculation of variables in external EEPROM bytes

CCS Community. Help!
How to calculate the external EEPROM (24C64), where the page is 32 bytes.
Total pages is 256 by 32 bytes.
With constant string of 22 bytes.

Thank you.
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sat Feb 08, 2014 12:29 am     Reply with quote

42 (Hitchhikers guide to the Galaxy). You are going to have to do a better job of explaining what you are trying to do and at least make an effort to create some code to accomplish whatever it is you are doing.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
azand1



Joined: 04 Feb 2014
Posts: 9

View user's profile Send private message

CALCULATING EXTERNAL EEPROM 24C64 BYTES
PostPosted: Sat Feb 08, 2014 8:39 am     Reply with quote

CALCULATING EXTERNAL EEPROM 24C64 BYTES
Here the basic program
How to make a routine for computing string of 22 bytes in pages of 32 bytes.




Made an improvement in the program.
I could change the size of the string to 16 bytes (page 2 x 16 = 32), solved my problem. But, still insisting that it has solution.
This problem almost ready.

I ask for help.
Missing another part of the string.


RESULT IS

I would like to improve this routine.
I did two string .....
More than that, given problems.


// 10 de Fevereiro de 2014 02:27h
#include <16F876A.H>
#device *=16
#use delay(clock=4000000)
#fuses HS,NOPROTECT,NOWDT,NOBROWNOUT,PUT
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 8192 // EEPROM 24C64 –24C64: 8Kx8 (256 pages of 32 bytes)
int8 EEPROM_PAGE_LENGTH= 32; //chip dependent. Set based on datasheet
#define EEPROM_PAGE_LEN 32 // Page length in bytes FOR EEprom
#define EEPROM_PAGE_COUNT 256 // Nunber of pages in eeprom
#define EEPROM_SIZE_STRINGS 22 // sizer fix of string
#define EEPROM_COUNT_STRINGS 300 // number of strings
//
#define EEPROM_I2C_WRITE_ADDR 0xA0
#define EEPROM_I2C_READ_ADDR 0xA1
//
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3//
#use I2C(MASTER, SDA=EEPROM_SDA, SCL=EEPROM_SCL,FAST=400000)

long int Count_Eeprom =0;
//char *Ptr2=Buffer2;
// SILVIAGHIJLMNOPQRSTUVW Wilson dos
// 10 22
char Buffer3[22] = {'W','i','l','s','o','n',' ','d','o','s',' ','A','n','j','o','s','.','R','u','a',' ','D'};
char Buffer1[22] = {'S','I','L','V','I','A','G','H','I','J','L','M','N','O','P','Q','R','S','T','U','V','W'};
char Buffer2[32];
long int page=0;
int8 Count_letters=0;
void init_ext_eeprom() {
output_low(eeprom_scl);
output_high(eeprom_sda);
delay_ms(200);
}

void read_eeprom_block(long addr, char block_len, char* out_buffer) // corrigida ....................
{
char i;
char count;

if(block_len == 0) // 0 Não pode ter pagina com 2 bytes
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();
delay_ms(6);
}
//****************************** ALEATÓRIO *****************************

///////////////////////////////////////////////////////
// Erase one page (32 bytes) of the eeprom. The page can be from 0 to 256.
// The page is filled with zeros.

void erase_eeprom_page(long int page)
{
char i;
long int addr;
long int apagar;
addr = (page << 5); // 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
Count_Eeprom++;
}

i2c_stop();
delay_ms(11);
//if((page % 8) == 0)
putc('.');
}
/////////////////////////////////////////////////////

void i2c_write_bloco(long address,char length, char *data,){
unsigned int16 dataIndex = 0;
unsigned int16 pageIndex;
unsigned int8 atualiza_end =0;
finish:
if( atualiza_end == 15){ address= Count_Eeprom; atualiza_end=10; }

pageIndex = address % EEPROM_PAGE_LENGTH; // 0 % 32

// while(dataIndex < length){

//Start I2C command
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write(address >> 8);
i2c_write(address);

//Loop through just the data on the current page
while(pageIndex < EEPROM_PAGE_LENGTH && dataIndex < length)
{
i2c_write(data[dataIndex++]);
pageIndex++;
Count_Eeprom++;
Count_letters++;
}
printf("\r\npageIndex: %lu < EEPROM_PAGE_LENGTH: %u dataIndex:%lu < length:%u "pageIndex,EEPROM_PAGE_LENGTH,dataIndex,length);
printf("\r\ndata : %u Count_Eeprom:%lu Count_letters:%u"data,Count_Eeprom,Count_letters);
i2c_stop();

if( atualiza_end == 10){
atualiza_end=0;
goto sai_ja;
}

if(Count_letters == 22) //OK
{
Count_letters=0;
}

else{ /// ?????????????????????????????????

EEPROM_PAGE_LENGTH=pageIndex;
if(Count_letters != 22){
EEPROM_PAGE_LENGTH=22;
length =22;
atualiza_end =15;
dataIndex=10;
pageIndex=0;
goto finish;

}

}
sai_ja :delay_cycles(6);
delay_ms(6); // opcional
}
///////////////////////////////////////////////////

void main(void) {
int8 n;
long int apagar;
int8 cmd =10;
delay_ms(1000);
puts("Inicio");
init_ext_eeprom();

delay_ms(15);
delay_ms(15);
apagar=0;
for (apagar=0;apagar< 4;apagar++)
erase_eeprom_page(apagar);

delay_ms(15);
Count_Eeprom=0;

//write_eeprom_block(0, 32, Buffer1); // &Buffer1);
puts("\r\n");
puts("Comecou");
delay_ms(1000);
Count_Eeprom=0;

i2c_write_bloco(Count_Eeprom,22,Buffer1);
delay_ms(15);
i2c_write_bloco(Count_Eeprom,22,Buffer3);

delay_ms(15);

puts("\r\n");
Count_Eeprom=0;
read_eeprom_block(Count_Eeprom, 32, Buffer2);
for (n=0;n<32;n++)
{ putchar((char)Buffer2[n]); }
//

delay_ms(15);

puts("\r\n");
Count_Eeprom=32;
read_eeprom_block(Count_Eeprom, 32, Buffer2);
for (n=0;n<32;n++)
{ putchar((char)Buffer2[n]); }
while(TRUE);;


}

/*
Inicio
....

Comecou

pageIndex: 22 < EEPROM_PAGE_LENGTH: 32 dataIndex:22 < length:22
data : 59 Count_Eeprom:22 Count_letters:22
pageIndex: 32 < EEPROM_PAGE_LENGTH: 32 dataIndex:10 < length:22
data : 37 Count_Eeprom:32 Count_letters:10
pageIndex: 22 < EEPROM_PAGE_LENGTH: 22 dataIndex:22 < length:22
data : 37 Count_Eeprom:44 Count_letters:22

SILVIAGHIJLMNOPQRSTUVWWilson dos

Anjos.Rua D

*/


Last edited by azand1 on Mon Feb 10, 2014 12:55 pm; edited 6 times in total
azand1



Joined: 04 Feb 2014
Posts: 9

View user's profile Send private message

Routine eemprom page?
PostPosted: Sun Feb 09, 2014 11:08 am     Reply with quote

Nobody knows make a page in eeprom routine?
I'm Newbie in C language.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 11:17 am     Reply with quote

I still don't understand what the problem is.

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 11:47 am     Reply with quote

I think he wants to know how to calculate the page boundaries.
The 24LC64 eeprom has 32 pages with 32 bytes in each page.
So, to get the starting address of each page, multiply the desired page
number by 32:

Page 0 is (0 * 32) = address 0
Page 1 is (1 * 32) = address 32
Page 2 is (2 * 32) = address 64
Page 3 is (3 * 32) = address 96
etc.
azand1



Joined: 04 Feb 2014
Posts: 9

View user's profile Send private message

I want to put 300 strings in order (continuous). Each string
PostPosted: Sun Feb 09, 2014 12:13 pm     Reply with quote

I've tried to explain my doubts above.
I want to put 300 strings in order (continuous). Each string is 22 bytes.

The strings that will get the RS232 to an array after shipping
to eeprom.

I want to make those written in block (page), it is much faster.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 1:10 pm     Reply with quote

300 * 22 = 6600 bytes. That exceeds the capacity of the 24C64 eeprom,
which has only 1024 bytes in it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19383

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 1:26 pm     Reply with quote

Er. Calculation gone wrong somewhere.

24C64, has 8KB, not 1KB....

However start with a comment, poster should be using the 24LC64, not the 24C64. The former is the current replacement for the latter, which is obsolete.

Also remember that with a 'string', there is an extra termination byte.

Personally, I'd suggest using 24byte records. 32byte page. Then 3 EEPROM pages, will hold 4 records. 300*24byte records, will then use 225 pages. Write in 96byte blocks.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 1:34 pm     Reply with quote

You are right, Ttelmah. I popped up the data sheet and left it un-zoomed,
and I didn't see the first part of:
Quote:
eight blocks of 1K x 8-bit

And it's before my coffee as well.
Ttelmah



Joined: 11 Mar 2010
Posts: 19383

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 1:38 pm     Reply with quote

First mistake I remember from you, in many a month!.... Smile
Many more from me.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1329

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 2:48 pm     Reply with quote

If I understand your question correctly, you want to be able to write more than just a single byte at a time but also avoid the issue of page boundaries messing with the writing. I use a function for work that does this, but I don't have it in front of me. Below is my attempt at trying to recreate it from memory.

Some notes:
1. I don't use I2C anymore (I use SPI eeproms), so I don't know if the I2C parts are correct. That's partially off of old memory and the datasheet. It's up to you to make sure the I2C parts are functionally correct (or perhaps you will get lucky and some other users can correct any mistakes).

2. This is just off the top of my head from some old memories, so there could be holes. The important part here is the idea of the algorithm used. Which is, calculate where in the current page you are, making sure to stop the command at the end of the page and start a new command at the beginning of the next page, and finally, making sure all the data gets written.

3. I typically work with PIC24 parts. I don't have as much experience with non PCD chips, so something I take for granted as quick/easy might not be on your chips.

With that said, here is a stab at an algorithm for writing long data without having to worry about page boundaries.

Code:

#define EEPROM_PAGE_LENGTH 32    //chip dependent. Set based on datasheet
#define EEPROM_I2C_ADDR    0xA0  //hardware dependent.  Set based on circuit.  8 bit address format

void i2c_write_eeprom(unsigned int16 address, unsigned int8 *data, unsigned int16 length){
   unsigned int16 dataIndex = 0;
   unsigned int16 pageIndex;
   BOOLEAN writing;
   
   //figure out index relative to page boundary
   pageIndex = address % EEPROM_PAGE_LENGTH;
   
   //loop through each page
   while(dataIndex < length){
      //Start I2C command
      i2c_start();
      i2c_write(EEPROM_I2C_ADDR);
      i2c_write(address >> 8);
      i2c_write(address);
     
      //Loop through just the data on the current page
      while(pageIndex < EEPROM_PAGE_LENGTH && dataIndex < length){
         i2c_write(data[dataIndex++]);
         pageIndex++;
      }
      i2c_stop();  //page write done
      pageIndex = 0;  //reset for next time
     
      //This part just polls the chip to make sure the write finished.
      //It could be replaced with just a delay_ms() call.  If so,
      //reference the datasheet to see what the appropriate time is.
      do{
         i2c_start();
         writing = i2c_write(EEPROM_I2C_ADDR);
      }while(writing);
      i2c_stop();
   }

}



Last edited by jeremiah on Sun Feb 09, 2014 9:18 pm; edited 1 time in total
azand1



Joined: 04 Feb 2014
Posts: 9

View user's profile Send private message

Someone's starting to endender what I mean.
PostPosted: Sun Feb 09, 2014 4:44 pm     Reply with quote

Sorry about the bad English because I'm from Brazil. AZAND1

My friend jeremiah.
Understand that I meant.



The idea is:

10 = 32-22 (string) / / I record 22 bytes on the same page
-12 = 10-22 (String) / / Part of the string on the same page

12 remaining on another page.

 
/ *
   Have an error in your routina.
    below:

       / / This part just polls the chip to make sure the write finished.
       / / It could be Replaced with just a delay_ms () call. If so,
       / / reference the datasheet to see what the time is Appropriate.
       i2c_start ();
       do {
          i2c_start ();
          writing i2c_write = (EEPROM_I2C_ADDR);
       } while (writing);
       i2c_stop ();
* /
Ttelmah



Joined: 11 Mar 2010
Posts: 19383

View user's profile Send private message

PostPosted: Mon Feb 10, 2014 1:20 am     Reply with quote

And, as I say, think again, and don't use 22byte.

Use 24.

Even if the extra bytes are not needed (however one may be, a '22 character' string, needs 23 bytes), it makes the maths, and storage so much easier.

3 EEPROM pages, will hold 4 records.

Write a 96byte block (3 pages).

On the error '=' misplaced.
writing=i2c_write(EEPROM_I2C_ADDR);

Best Wishes
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