Page 1 of 1

pointer stop working?

Posted: 29 May 2009 22:40
by Donald Shimoda
Seems like that code stop working on pro versions.

Code: Select all

procedure MemoryDallasWriteReal( EEdir : word ; dato: real);
var
  dir  : word;
  ptr  : ^real;
  i    : byte;
begin
  dir := EEdir;
  ptr := @dato;
  for i := 1 to 4 do
  begin
    ReadDallasByte(dir,ptr^);  // BYTE and BYTE
    dir := dir + 1;
    ptr := ptr + 1;
  end;
end;
the compiler raise a warning

39 1009 Warning: Implicit typecast performed from "integral" to "real" MemoryDallas.mpas

and the function always return in dato = 32.

????

Same to the inverse function

Code: Select all

procedure MemoryDallasWriteReal( EEdir : word ; dato: real);
var
  dir  : word;
  ptr  : ^real;
  i    : byte;
begin
  dir := EEdir;
  ptr := @dato;
  for i := 1 to 4 do
  begin
    WriteDallasByte(dir,ptr^);
    dir := dir + 1;
    ptr := ptr + 1;
  end;
end;
39 1018 Warning: Suspicious pointer conversion MemoryDallas.mpas


Any idea or workaround?

Posted: 30 May 2009 08:15
by Dany
Hi Donald,

Code: Select all

procedure MemoryDallasWriteReal( EEdir : word ; dato: real); 
One thing for sure: "dato" is a local variable, so the result will never appear to the caller of MemoryDallasWriteReal.
Try instead

Code: Select all

procedure MemoryDallasWriteReal( EEdir : word ; var dato: real); 
About the warnings: do not worry about them, a pointer handling is very soon suspicious in mP PRO.

Posted: 30 May 2009 12:09
by Donald Shimoda
Dany wrote:Hi Donald,

Code: Select all

procedure MemoryDallasWriteReal( EEdir : word ; dato: real); 
One thing for sure: "dato" is a local variable, so the result will never appear to the caller of MemoryDallasWriteReal.
Try instead

Code: Select all

procedure MemoryDallasWriteReal( EEdir : word ; var dato: real); 
Never mind, i just made a mistak and copy again the header of write procedure...
About the warnings: do not worry about them, a pointer handling is very soon suspicious in mP PRO.
I don't warned for the warning. It don't work, always return a real equal to 32!

Some in that code is wrong from pro versions (work fine in V 7.0) and i don't see what is wrong:

Code: Select all

procedure MemoryDallasReadReal( EEdir : word ; var dato: real);
var
  dir  : word;
  ptr  : ^real;
  i    : byte;
begin
  dir := EEdir;
  ptr := @dato;
  for i := 1 to 4 do
  begin
    ReadDallasByte(dir,ptr^);  // BYTE and BYTE
    dir := dir + 1;
    ptr := ptr + 1;
  end;
end; 
Do you see where is the problem?

Posted: 30 May 2009 12:46
by Dany
How does ReadDallasByte looks?

Posted: 30 May 2009 12:51
by Dany
Never mind my previous question.
This is the reason:

Code: Select all

  
var
  ptr  : ^real; 
...
  ptr := ptr + 1;
The behaviour in PRO is the one of Delphi: the pointer is incremented with the size of 1 real (since Ptr = ^real) = 4.
You want to handle the real byte by byte, so you will have to use:

Code: Select all

  
var
  ptr  : ^byte; // <-----here
...
  ptr := ptr + 1;

Posted: 30 May 2009 12:55
by Donald Shimoda
Dany wrote:How does ReadDallasByte looks?
Ok, there is the code for fram memory access:

Code: Select all

Procedure MemoryFramWriteByte(dir: word;datos: byte);
begin
  INTCON.GIE   := 0;  // Desactivo GIE
  soft_I2C_start();
  soft_I2C_write($A0); //write
  soft_I2C_write(Hi(dir));
  soft_I2C_write(Lo(dir));
  soft_I2C_write(datos);
  soft_I2C_stop;
  INTCON.GIE   := 1;  // Activo GIE
  Delay_500us;     // minimo 0.5 micro segundos
end;

function MemoryFramReadByte(dir: word): Byte;
var
  datos : byte;
begin
  INTCON.GIE   := 0;  // Desactivo GIE
  soft_I2C_start();
  soft_I2C_write($A0); //write
  soft_I2C_write(Hi(dir));
  soft_I2C_write(Lo(dir));
  Soft_I2C_start;
  soft_I2C_write($A1); //read
  datos := soft_I2C_read(0);
  soft_I2C_stop;
  INTCON.GIE   := 1;  // Activo GIE
  Delay_500us;    // minimo 0.5 micro segundos
  result := datos;
end;

procedure MemoryFramWriteWord(EEdir : word ; dato: word);
var
  dir  : word;
  ptr  : ^word;
  i    : byte;
begin
  dir := EEdir;
  ptr := @dato;
  for i := 1 to 2 do
  begin
    MemoryFramWriteByte(dir,ptr^);
    dir := dir + 1;
    ptr := ptr + 1;
  end;
end;

function MemoryFramReadWord(EEdir : word): word;
var
  dir  : word;
  ptr  : ^word;
  dato : word;
  i    : byte;
begin
  dir := EEdir;
  ptr := @dato;
  for i := 1 to 2 do
  begin
    ptr^ := MemoryFramReadByte(dir);
    dir := dir + 1;
    ptr := ptr + 1;
  end;
  result := dato;
end;

Posted: 30 May 2009 12:57
by Donald Shimoda
Dany wrote:Never mind my previous question.
This is the reason:

Code: Select all

  
var
  ptr  : ^real; 
...
  ptr := ptr + 1;
The behaviour in PRO is the one of Delphi: the pointer is incremented with the size of 1 real (since Ptr = ^real) = 4.
You want to handle the real byte by byte, so you will have to use:

Code: Select all

  
var
  ptr  : ^byte; // <-----here
...
  ptr := ptr + 1;
Thanks a lot, have a lot of sense now. Great if they put i some place on help. :?

Posted: 30 May 2009 13:37
by Dany
Great if they put i some place on help
It is in the help, section Pointer Atrithmetic, pointer addition:
If a pointer is declared to point to type, adding an integral value n to the pointer increments the pointer value by n * sizeof(type) as long as the pointer remains within the legal range (first element to one beyond the last element). If type has a size of 10 bytes, then adding 5 to a pointer to type advances the pointer 50 bytes in memory.
This was one of the more important changes in the PRO version to make it behave like Delphi concerning pointers :D

Posted: 30 May 2009 13:44
by Dany
Ok, there is the code for fram memory access
Where is "ReadDallasByte" (the procedure you used in "MemoryDallasReadReal")?

Your procedure "MemoryDallasReadReal" expects a byte back in the second parameter (which should be a var parameter then) of "ReadDallasByte", while the procedure "MemoryFramReadByte" takes only one parameter and gives the byte read back in the result of the function, so there is something not clear here.

Posted: 30 May 2009 13:48
by Donald Shimoda
Dany wrote:
Ok, there is the code for fram memory access
Where is "ReadDallasByte" (the procedure you used in "MemoryDallasReadReal")?
I send you the real code, that is, accesing fram.

Posted: 09 Jun 2009 18:58
by Dany
Donald Shimoda wrote:
Dany wrote:
Ok, there is the code for fram memory access
Where is "ReadDallasByte" (the procedure you used in "MemoryDallasReadReal")?
I send you the real code, that is, accesing fram.
Hi, Thanks. The problem occurs probably due the fact that in both the "...Word" routines the variable "Ptr" points to a word. It should point to a byte, because the data is read from or written to eeprom 1 byte at a time, and also "dato" is thus accessed 1 byte at a time. Incrementing "ptr" moves to pointer 2 places in stead of one (the size of a word)!.

Code: Select all

function MemoryFramReadWord(EEdir : word): word;
var
  dir  : word;
  ptr  : ^word;  // <----- make this ^byte in both read and write routines
  dato : word;
  i    : byte;
begin
  dir := EEdir;
  ptr := @dato;
  for i := 1 to 2 do
  begin
    ptr^ := MemoryFramReadByte(dir);
    dir := dir + 1;
    ptr := ptr + 1;
  end;
  result := dato;
end;