Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-27 Thread James Richters
>Look at synaser, its TBlockSerial class has a RecvTerminated method that
does just that.
>http://synapse.ararat.cz/doc/help/synaser.TBlockSerial.html#RecvTerminated
>https://sourceforge.net/p/synalist/code/HEAD/tree/trunk/
>Bye
>--
>Luca

Thank you for the suggestion and the links, that does look like it would
take care of the issue for me.
James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Luca Olivetti

On 26/07/16 13:58, James Richters wrote:

but I don’t want it to get stuck in an endless loop which could happen if:

A: nothing is ever received

B: garbage is being received due to bad connection or baudrate
mismatch.. etc..


Look at synaser, its TBlockSerial class has a RecvTerminated method that 
does just that.


http://synapse.ararat.cz/doc/help/synaser.TBlockSerial.html#RecvTerminated

https://sourceforge.net/p/synalist/code/HEAD/tree/trunk/

Bye
--
Luca

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread James Richters
Thank You I found the sleep procedure  Thank you for explaining that it
was looking for a pointer, that was helpful.  A little cutting and pasting
and now I have 3 more ways to sleep... Sleep_S will probably be sufficient
and is the most flexible, because if you have 1,000,000,000 seconds you
don't need precision down to 100nS.. but you have it anyway, you could
specify 10.001 seconds and it would work... it comes out to
10001 intervals... I'm not going to wait over 31 years to test
it though :)

Thanks for the help everyone, now I can adjust my delay from 36uS for
baudrates of 25 all the way to 30mS for a baudrate of 300.   I know
sleep isn't exact, it's more of a minimum and then you need to also wait for
the processor to get back to you, but I think it will be close enough
without excessive delays.

I posted it on github if anyone happens across this doing a search they can
find it here:
https://github.com/Zaaphod/FPC-Delay
 


>You need to declare a LargeInteger and pass the pointer to it to
NtDelayExecution(). LargeInteger itself is declared as a case-record 
>consisting of two 32-bit values (LowPart and HighPart) and a 64-bit value
(QuadPart). Best is you assign your value to QuadPart, as
> that sets the record in one go.
>Oh and I forgot to mention that you need to use a negative value for
relative sleeps (otherwise you'll wait until that time from the 
>system start on has passed, so "1" would be a no-op basically ;) )

>For an example see the implementation of Sleep in the SysUtils unit of the
NativeNT target: rtl/nativent/sysutils.pp (near the end of the file)

>Regards,
>Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Sven Barth
On 26.07.2016 21:52, James Richters wrote:
>> An alternative would be NtDelayExecution from unit jwanative. Its interval
> argument is in multiples of 100ns
>> and is essentially what Windows' Sleep() uses internally.
>> Note: The first argument "Alertable" determines whether the function can be
> interrupted by NtAlertThread 
>> (and whatever Windows API functions use that internally).
> 
> This sounds like it would work, but I can't figure out how to use it.  Do
> you have an example?  
> I've tried just a quick test like this:
> 
> uses
>   windows,jwanative;
> Var
>   DelayInterval : PLarge_Integer;
>   Variable1:integer;
> begin
> DelayInterval:=1;
> Variable1:=NtDelayExecution(true,DelayInterval);
> end.
> 
> It won't let me set DelayInterval with a constant, I get "Incompatible
> Types: got "shortint" expected "Plarge_Integer"  
> I really don't undertand these variable types that it wants.  

You need to declare a LargeInteger and pass the pointer to it to
NtDelayExecution(). LargeInteger itself is declared as a case-record
consisting of two 32-bit values (LowPart and HighPart) and a 64-bit
value (QuadPart). Best is you assign your value to QuadPart, as that
sets the record in one go.
Oh and I forgot to mention that you need to use a negative value for
relative sleeps (otherwise you'll wait until that time from the system
start on has passed, so "1" would be a no-op basically ;) )

For an example see the implementation of Sleep in the SysUtils unit of
the NativeNT target: rtl/nativent/sysutils.pp (near the end of the file)

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread James Richters
>An alternative would be NtDelayExecution from unit jwanative. Its interval
argument is in multiples of 100ns
>and is essentially what Windows' Sleep() uses internally.
>Note: The first argument "Alertable" determines whether the function can be
interrupted by NtAlertThread 
>(and whatever Windows API functions use that internally).

This sounds like it would work, but I can't figure out how to use it.  Do
you have an example?  
I've tried just a quick test like this:

uses
  windows,jwanative;
Var
  DelayInterval : PLarge_Integer;
  Variable1:integer;
begin
DelayInterval:=1;
Variable1:=NtDelayExecution(true,DelayInterval);
end.

It won't let me set DelayInterval with a constant, I get "Incompatible
Types: got "shortint" expected "Plarge_Integer"  
I really don't undertand these variable types that it wants.  

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Sven Barth
On 26.07.2016 19:05, Dmitry Boyarintsev wrote:
> On Tue, Jul 26, 2016 at 12:38 PM, James Richters
> >
> wrote:
> 
> What I need is a timer that I can specify in microseconds, a
> millisecond is too long.   I am using it for timing to read in a
> string on a serial connection.  My fastest baudrate is 25, so at
> that rate I would need to delay only 36 microseconds.  So I can’t
> use sleep () or delay () because they only go down to 1mS and that’s
> too slow.
> 
> 
> Here's an example of Sleep with microseconds that I came up with
> 
> procedure SleepMcs(mcs: Int64);
> var
>   ct : TLargeInteger;
>   fr : TLargeInteger;
>   af  : TLargeInteger;
>   trg : TLargeInteger;
> const
>   NanoInMicro = 1000;
> begin
>   QueryPerformanceCounter(ct);
>   QueryPerformanceFrequency(fr);
>   trg:=round(mcs * NanoInMicro / (NSInSec/fr));
>   repeat
> QueryPerformanceCounter(af);
>   until trg<=(af-ct);
> end;
> 
> I'm hoping that there's a better solution out there, because this
> procedure will end up with 100% CPU load.
> I doubt it's possible to unload the CPU, since the windows scheduler is
> in milliseconds accuracy.
> May be a lower (kernel/driver) level allows that.

An alternative would be NtDelayExecution from unit jwanative. Its
interval argument is in multiples of 100ns and is essentially what
Windows' Sleep() uses internally.
Note: The first argument "Alertable" determines whether the function can
be interrupted by NtAlertThread (and whatever Windows API functions use
that internally).

Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Dmitry Boyarintsev
On Tue, Jul 26, 2016 at 1:58 PM, James Richters <
ja...@productionautomation.net> wrote:

> I think there may be a solution with this performance counter for my
> purposes…  here’s what I’m trying to accomplish:
>
Well, Windows provides a different means of waiting (and waiting with time
out) for the Serial port communication.

The whole topic is discussed here:
https://msdn.microsoft.com/en-us/library/ff802693.aspx#serial_topic1

I'm thinking that using performance counter is a little of over-engineering

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread James Richters
I think there may be a solution with this performance counter for my purposes…  
here’s what I’m trying to accomplish:

 

I’m trying to read a string from a serial port until I get a linefeed, but I 
don’t want it to get stuck in an endless loop which could happen if:

A: nothing is ever received

B: garbage is being received due to bad connection or baudrate mismatch.. etc..

So I keep reading the port in a loop until

A:  I try 10 times and still get nothing

B:  I get the data I’m looking for ending with a #10 

C:  I get too much data, then I stop after 254 bytes, the response should never 
be that long, so I’ll flag that as garbage.

D: I try 1000 times and still do not have a #10 but I also do not have 254+ 
bytes

 

For fast baud rates, this works fine, but for slow baudrates, I reach 1000 
tries way before the string is finished, so I planned on putting in a delay 
calculated from the baudrate… however I think I can take a different approach 
here.  I don’t really care the exact amount of time between retries, I just 
want to try for a long enough length of total time before giving up, so I don’t 
get stuck in a loop.   Perhaps I can read   QueryPerformanceCounter(ct); during 
the loop and if it exceeds the set amount of time, then use that to end the 
loop and give up.   

 

Here’s my function as it is.. fyi, my entire project is in turbo pascal 
compatibility mode:

 

Function ReadSerial(SerPortNum:Byte):String;

Var

   Loopcount:Word;

   CharCount:Byte;

   InputString:String;

   InputLetter:Char;

Begin

   LoopCount:=0;

   CharCount:=0;

   InputString:='';

   repeat

  Status:= SerRead(SerialHandle[SerPortNum], Inputletter, 1);

  if (status > 0) {and ((InputLetter<>#10) AND (InputLetter<>#13))} then

   begin

  Inc(CharCount);

  case InputLetter of

  ' ':InputString:=InputString+'.';

  #10:InputString:=InputString+'#10';

  #13:InputString:=InputString+'#13';

  else

 InputString:=InputString+(InputLetter);

end;

 end;

  Inc(Loopcount);

  {need delay here for slow baud rates}

Until (InputLetter=#10) OR ((Loopcount>10) AND (InputString='')) OR 
(CharCount>254) OR (Loopcount>1000);

ReadSerial:=InputString;

end;

 

 

From: fpc-pascal-boun...@lists.freepascal.org 
[mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev
Sent: Tuesday, July 26, 2016 1:05 PM
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Microsecond Delay Suggestions?

 

On Tue, Jul 26, 2016 at 12:38 PM, James Richters 
<ja...@productionautomation.net <mailto:ja...@productionautomation.net> > wrote:

What I need is a timer that I can specify in microseconds, a millisecond is too 
long.   I am using it for timing to read in a string on a serial connection.  
My fastest baudrate is 25, so at that rate I would need to delay only 36 
microseconds.  So I can’t use sleep () or delay () because they only go down to 
1mS and that’s too slow.

 

Here's an example of Sleep with microseconds that I came up with 


procedure SleepMcs(mcs: Int64);
var
  ct : TLargeInteger;
  fr : TLargeInteger;
  af  : TLargeInteger;
  trg : TLargeInteger;
const
  NanoInMicro = 1000;
begin
  QueryPerformanceCounter(ct);
  QueryPerformanceFrequency(fr);
  trg:=round(mcs * NanoInMicro / (NSInSec/fr));
  repeat
QueryPerformanceCounter(af);
  until trg<=(af-ct);
end;

I'm hoping that there's a better solution out there, because this procedure 
will end up with 100% CPU load.

I doubt it's possible to unload the CPU, since the windows scheduler is in 
milliseconds accuracy.

May be a lower (kernel/driver) level allows that.

 

thanks,

Dmitry 

 

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Dmitry Boyarintsev
On Tue, Jul 26, 2016 at 12:38 PM, James Richters <
ja...@productionautomation.net> wrote:

> What I need is a timer that I can specify in microseconds, a millisecond
> is too long.   I am using it for timing to read in a string on a serial
> connection.  My fastest baudrate is 25, so at that rate I would need to
> delay only 36 microseconds.  So I can’t use sleep () or delay () because
> they only go down to 1mS and that’s too slow.
>

Here's an example of Sleep with microseconds that I came up with

procedure SleepMcs(mcs: Int64);
var
  ct : TLargeInteger;
  fr : TLargeInteger;
  af  : TLargeInteger;
  trg : TLargeInteger;
const
  NanoInMicro = 1000;
begin
  QueryPerformanceCounter(ct);
  QueryPerformanceFrequency(fr);
  trg:=round(mcs * NanoInMicro / (NSInSec/fr));
  repeat
QueryPerformanceCounter(af);
  until trg<=(af-ct);
end;

I'm hoping that there's a better solution out there, because this procedure
will end up with 100% CPU load.
I doubt it's possible to unload the CPU, since the windows scheduler is in
milliseconds accuracy.
May be a lower (kernel/driver) level allows that.

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread James Richters
That looks great.   I’ll give it a try!  Thank you very much for the suggestion 
and the example

 

From: fpc-pascal-boun...@lists.freepascal.org 
[mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev
Sent: Tuesday, July 26, 2016 11:45 AM
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Microsecond Delay Suggestions?

 

On Tue, Jul 26, 2016 at 11:21 AM, Dmitry Boyarintsev <skalogryz.li...@gmail.com 
<mailto:skalogryz.li...@gmail.com> > wrote:

Maybe you want to look into QueryPerformanceCounter.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx 
<https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904%28v=vs.85%29.aspx>
 

Here's an example:

{$mode objfpc}{$H+}

uses
  Windows;

const
  MSInSec = 1000;
  MCInSec = MSInSec * 1000;
  NSInSec = MCInSec * 1000;

function LargeLoop: Integer;
var
  i : integer;
begin
  Result:=0;
  for i:=0 to 1000 do
inc(Result);
   //or you can verify Sleep(milliseconds)
   //Sleep(100);
end;

var
  fr : TLargeInteger;
  ct : TLargeInteger;
  af : TLargeInteger;
  d  : double;
  diff : TLargeInteger;
begin
  QueryPerformanceFrequency(fr);
  writeln('Frequency: ' ,fr);
  d:=(1/fr) * NSInSec;
  writeln('Freq in Time: ', d:0:0, ' ns (roughly)');
  QueryPerformanceCounter(ct);
  LargeLoop;
  QueryPerformanceCounter(af);
  diff := af - ct;
  writeln('Loop:');
  writeln('  Ticks: ', diff);
  writeln('  Time:  ', ((diff/fr) * NSInSec):0:0,' ns' );
  writeln(' ', ((diff/fr) * MCInSec):0:6,' mcs' );
  writeln(' ', ((diff/fr) * MSInSec):0:6,' ms' );
end.

 

 

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread James Richters
I don’t need a 55mS tick, there was a DOS timer that ticked every 55mS, which I 
used to calibrate a delayloop.. however I can’t use any of that on windows, I 
can’t even make the DOS function call, and even if I had a way to calibrate my 
delay loop, it would be meaningless because I have to share the processor with 
windows, so creating a delay by just looping a lot doesn’t work at all in 
windows… depending on what else is running I would get totally different time 
delays out of the loop.

 

What I need is a timer that I can specify in microseconds, a millisecond is too 
long.   I am using it for timing to read in a string on a serial connection.  
My fastest baudrate is 25, so at that rate I would need to delay only 36 
microseconds.  So I can’t use sleep () or delay () because they only go down to 
1mS and that’s too slow.

 

From: fpc-pascal-boun...@lists.freepascal.org 
[mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev
Sent: Tuesday, July 26, 2016 11:19 AM
To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org>
Subject: Re: [fpc-pascal] Microsecond Delay Suggestions?

 

On Tue, Jul 26, 2016 at 11:16 AM, James Richters 
<ja...@productionautomation.net <mailto:ja...@productionautomation.net> > wrote:

Any suggestions on how to do this on windows with a console application?


I don't have an answer, but I'm wondering what kind of task is that? 
Why do you need this 55mS tick?

thanks,

Dmitry

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Dmitry Boyarintsev
On Tue, Jul 26, 2016 at 11:21 AM, Dmitry Boyarintsev <
skalogryz.li...@gmail.com> wrote:

> Maybe you want to look into QueryPerformanceCounter.
>
> https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
>
> Here's an example:

{$mode objfpc}{$H+}

uses
  Windows;

const
  MSInSec = 1000;
  MCInSec = MSInSec * 1000;
  NSInSec = MCInSec * 1000;

function LargeLoop: Integer;
var
  i : integer;
begin
  Result:=0;
  for i:=0 to 1000 do
inc(Result);
   //or you can verify Sleep(milliseconds)
   //Sleep(100);
end;

var
  fr : TLargeInteger;
  ct : TLargeInteger;
  af : TLargeInteger;
  d  : double;
  diff : TLargeInteger;
begin
  QueryPerformanceFrequency(fr);
  writeln('Frequency: ' ,fr);
  d:=(1/fr) * NSInSec;
  writeln('Freq in Time: ', d:0:0, ' ns (roughly)');
  QueryPerformanceCounter(ct);
  LargeLoop;
  QueryPerformanceCounter(af);
  diff := af - ct;
  writeln('Loop:');
  writeln('  Ticks: ', diff);
  writeln('  Time:  ', ((diff/fr) * NSInSec):0:0,' ns' );
  writeln(' ', ((diff/fr) * MCInSec):0:6,' mcs' );
  writeln(' ', ((diff/fr) * MSInSec):0:6,' ms' );
end.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread James Richters
Any Suggestions for a microsecond delay?  I had a scheme in my old dos program 
where I would run a massive loop at the beginning of my program and time it 
with DOS 55mS ticks, then do the math and figure out how many times I needed to 
loop for a given delay.. worked great on DOS with nothing else using the 
processor, but completely invalid for windows.  I see delay() and sleep() but 
they are both only good down to 1mS and I would like to go down to 1uS.  Any 
suggestions on how to do this on windows with a console application? 

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Dmitry Boyarintsev
On Tue, Jul 26, 2016 at 11:19 AM, Dmitry Boyarintsev <
skalogryz.li...@gmail.com> wrote:

> On Tue, Jul 26, 2016 at 11:16 AM, James Richters <
> ja...@productionautomation.net> wrote:
>
>> Any suggestions on how to do this on windows with a console application?
>>
>
> I don't have an answer, but I'm wondering what kind of task is that?
> Why do you need this 55mS tick?
>
Maybe you want to look into QueryPerformanceCounter.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Microsecond Delay Suggestions?

2016-07-26 Thread Dmitry Boyarintsev
On Tue, Jul 26, 2016 at 11:16 AM, James Richters <
ja...@productionautomation.net> wrote:

> Any suggestions on how to do this on windows with a console application?
>

I don't have an answer, but I'm wondering what kind of task is that?
Why do you need this 55mS tick?

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal