OK, first the form code. I've included just my modifications to the automatically generated code. this code expects the form to have a read button and 3 Tedit boxes not included in an attempt to keep this post for getting too big.
...
Public { Public declarations }
ConfigObj:TConfigObj; // as part of the form
end;
Procedure TFrmConfig.FormCreate(Sender: TObject);
Begin
...
ConfigObj := TConfigObj.Create;
end;
Procedure TFrmConfig.FormDestroy(Sender: TObject);
Begin
ConfigObj.Free;
end;
Procedure TFrmConfig.BtnReadSDClick(Sender: TObject);
var filename:string;
Begin
filename := GetConfigFileName(SD_Device); // "F:Config.dat
// .. more file testing code removed
StatusMessage2('reading...'+filename);
if ConfigObj.ReadFromFile(filename) then
begin
PramToEdit();
ConfigObj.ReadFromFile(filename); // for some reason I need to do a display thing before the read takes hold
PramToEdit(); // this one works
end;
end;
procedure GetParam(var box:TEdit; AValue:double);
begin
box.Text := format(%.2f',[Avalue]);
end;
procedure TFrmconfig.PramToEdit();
begin
GetParam(ed_AcqTime, ConfigObj.uiAcqTime);
GetParam(ed_ProcTime, ConfigObj.uiProcTime);
GetParam(ed_AmpExcReg, ConfigObj.uiAmpDiffExReg);
end;
========= The configobj is in another unit. I'v reduced the number of parameters down to 3 (1 float and 2 words) but the others follow the same format
type
F32 = single;
U16 = word;
U8 = byte;
TConfigParmTable = packed record // entree def
prarmCode :U8;
byteoffset :U16; // 0 to 511 (where to find parameters)
size :U16;
end;
TConfigFilePrams = packed record
bidsmode :U8;
PrarmCount:U8;
// first table starts after these bytes
PrarmTable:TConfigParmTable; end;
TConfigFile = record case integer of
0:(Pram:TConfigFilePrams);
1:(raw:array[1..(8*1024)] of U8);
end;
TConfigDAQType = packed record // def DAQ parameters
AcqPts :U16; // rng=[10..500]
ProcPts :U16; // rng=[10..500]
AmpDiffExReg :F32; // rng=[0.0 .. 1.0]
end;
TConfigObj = class
my : record
Tag :integer;
CardType :U8;
DaqParam :TConfigDAQType; // Raw vars live here
fileOK :Boolean;
ConfigFile :TConfigFile;
FileName :string;
end; // of record
private { private declarations }
procedure DecodeConfigTable(Index: Integer);
Procedure SetU16Pts(value: double; Var saveto: U16; min,max:U16);
procedure Showstr(Str: String);
public { public declarations }
Constructor Create;
property Tag :integer read my.tag Write my.tag;
Procedure SetAmpDiffExReg (Const AValue: F32);
Function UIGet_ProcTime : double;
Procedure UISet_ProcTime (Const AValue: double);
Function UIGet_AcqTime : double;
Procedure UISet_AcqTime (Const AValue: double);
...
property uiAcqTime :double Read UIGet_AcqTime Write UISet_AcqTime;
property uiProcTime:double Read UIGet_ProcTime Write UISet_ProcTime;
property uiAmpDiffExReg :F32 Read my.DaqParam.AmpDiffExReg Write SetAmpDiffExReg;
function ReadFromFile(filename:string):Boolean;
End;
implementation
const
sampfreq = 50000.0;
Constructor TConfigObj.Create;
Begin
Inherited Create;
with my do begin
DaqParam.AcqPts := 500;
DaqParam.ProcPts := 500;
DaqParam.AmpDiffExReg := 0.00;
end;
end;
Procedure TConfigObj.SetU16Pts(value:double; var saveto:U16; min,max:U16);
begin
if (value < min) then saveto := min
else if (value > max) then saveto := max
else saveto := round(value);
End;
Function TConfigObj.UIGet_AcqTime: double; // checked
Begin
result := my.DaqParam.AcqPts *1000.0/sampfreq;
End;
Procedure TConfigObj.UISet_AcqTime(Const AValue: double); // checked
var f:double;
Begin
f := trunc(round(AValue*sampfreq/1000.0));
SetU16Pts(f, my.DaqParam.AcqPts, 10, 500);
end;
Function TConfigObj.UIGet_ProcTime: double; // checked
Begin
result := my.DaqParam.ProcPts *1000/sampfreq;
End;
Procedure TConfigObj.UISet_ProcTime(Const AValue: double); // checked
var f:double;
Begin
f := AValue * sampfreq/1000;
SetU16Pts(f, my.DaqParam.ProcPts , 10, 500);
End;
Procedure TConfigObj.SetAmpDiffExReg(Const AValue: F32);
Begin
if (Avalue < 0.0) then my.DaqParam.AmpDiffExReg:=0.0
else if (Avalue > 1.0) then my.DaqParam.AmpDiffExReg:=1.0
else my.DaqParam.AmpDiffExReg:=Avalue;
end;
function Tconfigobj.Readfromfile(filename: String): Boolean;
var fhandle:THandle;
i:integer;
begin
result := FALSE;
my.fileOK:=FALSE;
try
fhandle:=FileOpen(fileName, fmOpenRead+ fmShareDenyNone);
i := FileRead( Fhandle, my.ConfigFile, sizeof(TConfigFile));
if (i < sizeof(my.ConfigFile)) then
exit;
my.fileOK :=TRUE;
my.FileName :=filename; // save just incase I need it
my.CardType := my.ConfigFile.Pram.mode;
for i:=1 to my.ConfigFile.Pram.PrarmCount do begin
DecodeConfigTable(i);
end;
result := TRUE; // good read !! A breakpoint here shows my.DaqParam are equal to the file contents
finally
FileClose(fhandle);
end;
end;
procedure Tconfigobj.BinGetDAQ_params(tbl:TConfigParmTable);
var p:^TConfigDAQType;
begin
p := @my.ConfigFile.raw[tbl.byteoffset+1];
// move(p^, my.DaqParam, sizeof(my.DaqParam));
self.my.DaqParam := p^; // and that all that it takes to read all 32 bytes
end;
procedure Tconfigobj.DecodeConfigTable(index:integer);
var tbl:^TConfigParmTable;
begin
tbl := @my.ConfigFile.Pram.PrarmTable;
inc(tbl, index-1);
case tbl^.prarmCode of
DAQ_param : BinGetDAQ_params(tbl^); // TConfigDAQType
....
else ShowStr(' *** unknown type, no decoder yet ***');
end;
end;
thank you for looking.
mas