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

Int32 problem

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



Joined: 02 Aug 2005
Posts: 14

View user's profile Send private message

Int32 problem
PostPosted: Tue Aug 09, 2005 7:04 pm     Reply with quote

Hi,

I think I have a conversion problem. I just want to fill a int32 array named "test" with external eeprom data. When it dont get me the correct values I tried with a flat variable "tmp" and it was worse.

why if test[i] = tmp it print diferent values ?

Im using a PIC18F452.
Thanks.


Code:

void LoadReg()
{
long addr;
Int32 tmp;
Int32 test[6];

     addr=6;
     for (i=0; i <6 i++) {
          tmp = read_int32_ext_eeprom(addr);
          test[i] = tmp;
          addr+=4;
          printf("test[%d]=%lu      tmp=%lu\n\r", i, test[i], tmp);
     }

}

test[0]=570556930   tmp=33686018
test[1]=33561090     tmp=33686018
test[2]=69345794     tmp=33686786
test[3]=488768771   tmp=33686019
test[4]=7873026      tmp=33686018
test[5]=2                 tmp=572654082

jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Tue Aug 09, 2005 9:44 pm     Reply with quote

I just ran a modified version version of your code on a 18F452.

Here is the meat of what I wrote:

Code:



/*** Functions***/
int32 read_int32_eeprom(int8 address) {
   int8  i;
   int32 data;

   for(i = 0; i < 4; ++i) {
     *(&data + i) = read_eeprom(address + i);
   }

   return data;
}

/***   Main  ***/

   long int i;

   int8 addr;
   Int32 tmp;
   Int32 test[6];



     addr=6;
     for (i=0; i <6 ;i++) {
          tmp = read_int32_eeprom(addr);
          test[i] = tmp;
          addr+=4;
          printf("test[%lu]=%lu      tmp=%lu\n\r", i, test[i], tmp);
     }


My output was what was expected for reading un-initialized internal EEPROM. I would suspect there is a comm issue with your external EEPROM. If you post your full code one of the experts will probably be able to find the problem. Also, when you post code, cut and paste the code so no typos find there way into the post.

Good Luck,

John
Guest








PostPosted: Tue Aug 09, 2005 10:50 pm     Reply with quote

the code has 950 lines, anyway here I send you a smaller one.
The problem are two.

1) test[i] = tmp. The compiler can't make a correct casting to int32.

the same occurs doing test[i]=read_int32_ext_eeprom(addr);

2) variable tmp is overlapped with test[0];

thank you
leto

Code:

#include <18F452.h>
#device *=16
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP, NOCPD
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,stream=PC)

#define EEPROM_SDA  PIN_C4 
#define EEPROM_SCL  PIN_C3 

#include<24256.c>   // it has #use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL,FORCE_HW,fast)
#include <external_eeprom.c>


void main()
{
long addr;
int8  i;
int32 tmp;
int32 test[6];

       addr=6;
       for (i=0; i < 6 ; i++) {
            tmp = read_int32_ext_eeprom(addr);
            test[i] = tmp;   // <- here something wrong
            printf("test[%d]=%lu    tmp=%lu\n\r", i, test[i], tmp);                 
            addr+=4;
       }
}

[/code]
Ttelmah
Guest







PostPosted: Wed Aug 10, 2005 6:59 am     Reply with quote

Are you sure it is not just your output that it wrong?. You are trying to output 'test[i]', which is a long integer, using %d, which only handles shorts. You will see just the low byte of the value...

Best Wishes
Guest








PostPosted: Wed Aug 10, 2005 7:39 am     Reply with quote

Hi Ttelmah,

No, I use %d to print the index "i" but %lu to print int32 variable.
I think is a compiler bug. may be i am wrong. look at this:

the problem is with 18f452. I tried the same code with 16f877 and it works fine.

for example:

Code:

main()
{
     int32 test[1];
     int i;
     
     i=0;
     test[i] = 222222;                 // using index work wrong with 18f452
//     test[0];                            // it works fine
     printf("test  %lu", test[i]);


     result: 0
}


Thanks.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 10, 2005 7:45 am     Reply with quote

Look at the register locations using the simulator in MPLAB
MikeValencia



Joined: 04 Aug 2004
Posts: 238
Location: Chicago

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Wed Aug 10, 2005 7:46 am     Reply with quote

Ttelmah wrote:
Are you sure it is not just your output that it wrong?. You are trying to output 'test[i]', which is a long integer, using %d, which only handles shorts. You will see just the low byte of the value...

Best Wishes


I was looking at the original post late last night, and still can't figure out, by inspection alone, why it wouldn't work. Notice that his %d is only printing the index into the array, while he uses %lu for the two int32 values.

As for your first post about the output of the eeprom reading being wrong, I still can't see why test[i] = tmp does not reflect the same values when immediately doing a printf Question
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Aug 10, 2005 7:54 am     Reply with quote

You will notice that I did not use the %d format for the index of the array. My code would not compile until I changed it to the %lu format.

Some suggestions for your next steps in trouble-shooting:

1. Make a skeleton program with just the features you're trying to debug. I would try reading from the internal EEPROM first, before trying external. Use my function and printf statement.

Note: Ttelmah could probably correct me if I'm wrong, but I don't think there is any typecasting happening in the line where you think the problem is. Both of those values/variables are already int32.

2. See item #4 in the following post and provide all the info requested.

http://www.ccsinfo.com/forum/viewtopic.php?t=17013

The experts can usually recognize common problems from earlier compiler versions, etc. (I'm wondering how your code compiled with the %d format in the printf statement and mine would not?)

3. Try not to get fixated on one item that you have convinced yourself is the problem.

4. When you do find the problem and correct it, post any information back here so anybody else that encounters the same problem will have the solution.

Good Luck,

John
Ttelmah
Guest







PostPosted: Wed Aug 10, 2005 8:43 am     Reply with quote

jecottrell wrote:
You will notice that I did not use the %d format for the index of the array. My code would not compile until I changed it to the %lu format.

Some suggestions for your next steps in trouble-shooting:

1. Make a skeleton program with just the features you're trying to debug. I would try reading from the internal EEPROM first, before trying external. Use my function and printf statement.

Note: Ttelmah could probably correct me if I'm wrong, but I don't think there is any typecasting happening in the line where you think the problem is. Both of those values/variables are already int32.

2. See item #4 in the following post and provide all the info requested.

http://www.ccsinfo.com/forum/viewtopic.php?t=17013

The experts can usually recognize common problems from earlier compiler versions, etc. (I'm wondering how your code compiled with the %d format in the printf statement and mine would not?)

3. Try not to get fixated on one item that you have convinced yourself is the problem.

4. When you do find the problem and correct it, post any information back here so anybody else that encounters the same problem will have the solution.

Good Luck,

John


You are dead right, there is no typecasting in the line shown.

Sorry about thinking the 'L' was missing, I glanced along the line, and missed that the index was also being sent. However %ld, is still wrong, it should be %lu, since int32, defaults to unsigned.

The actual problem is in the read_int32_eeprom function. Adding '1' to a pointer to an int32, points to the _next_ int32, not to the next byte. This is standard C.
What should be done is:

Code:

/*** Functions***/
int32 read_int32_eeprom(int8 address) {
   int8  i;
   int32 data;
   int8 * addr;
   addr=&data;

   for(i = 0; i < 4; ++i) {
     *(&addr + i) = read_eeprom(address + i);
   }

   return data;
}


This generates a pointer to an int8, which will then increment as expected.
However I'd probably do it instead as:

Code:

/*** Functions***/
int32 read_int32_eeprom(int8 address) {
   int8  i;
   union {
       int32 data;
       int8 b[4];
   } temp;

   for(i = 0; i < 4; ) {
     temp.b[i++] = read_eeprom(address++);
   }

   return temp.data;
}


Which is 'tidier' code, and saves a few bytes (such as incrementing address, rather than performing a two byte addition every time round).

Best Wishes
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Aug 10, 2005 9:16 am     Reply with quote

Ahhhhhh, this is getting good.

First, I have to admit to some very wrong testing I did. I only read from the internal EEPROM to test my theory. Because the internal EEPROM defaults to 0xFF after each reprogram I wouldn't catch any "overlapping" reads......bad, bad, bad, bad.

In the future I promise to always write a known value prior to reading to validate any code.

Big Question:

I modified the external_eeprom.c function to read the internal EEPROM. Is the function contained therein, and the function that is in question here inherently wrong? Or is there just a difference in the way the internal and external EEPROM locations are accessed?

Thanks,

John
Guest








PostPosted: Wed Aug 10, 2005 9:20 am     Reply with quote

Im using read_int32_ext_eeprom function located in CCS\drivers directory and Im sure that is work fine, but just when you use a flat int32 variable not an indexed array.

e.g
Code:


int32 tmp;
tmp=read_int32_ext_eeprom(addr);


tmp get the correct value.

however if you assign the result to an array, it works wrong.

Code:


e.g

int32 tmp[2];
int i;

      i=0;
      tmp[i] = read_int32_ext_eeprom(addr);
      printf( "tmp array is=%lu",  tmp[i]);

it works wrong.


the same occurs without call to read_int32_ext_eeprom. Just try to do:

Code:

int32 tmp[2];
int32 flat;
     
      flat=70000;
      i=0;
      tmp[i] = tmp;


it works wrong;


if you use direct indexing it works ok.


Code:

int32 tmp[2];
int32 flat;
     
      flat=70000;
      tmp[0] = tmp;
Guest








PostPosted: Wed Aug 10, 2005 9:24 am     Reply with quote

But remember just with 18F452. 16F877 works fine.

thanks.
Guest








PostPosted: Wed Aug 10, 2005 10:53 am     Reply with quote

I did a debug with MPLAB and it doesnt work. I hope you can help me.
just work with flat int32 variable.

thank you.
JPA
Guest







PostPosted: Wed Aug 10, 2005 11:34 am     Reply with quote

Reading your discussion, I remember a problem I had with structure assignment.

When doing direct assignement: m = old_m, I had no problem.

When working with pointers or array, tab[i] = m or *(tab+i) = m or ... the assignement was not correct.

As a wraparound, I used the memcopy function and then had no more problem.
Guest








PostPosted: Wed Aug 10, 2005 1:27 pm     Reply with quote

thanks for your comment JPA.

I tried with:

Code:

int i;
int32 tmp;
int32 test[6];

for (i=0;i<6;i++) {
      tmp=read_int32_ext_eeprom( addr );
      memcpy (&test[i], &tmp, 4);
}


It is working well. So, I suppose that direct assignment to int32 or int16 array doesn't work correctly.

Thank you.
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