Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 04:36 12 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PIO UINT32 counter to INT64 courtesy of Gemini

Author Message
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1360
Posted: 07:53am 10 Jul 2025
Copy link to clipboard 
Print this post

' --- GLOBAL VARIABLES (Must retain their values between counter readings) ---
' Declare these at the top of your program or in a GLOBAL block.
DIM LastRaw32BitReading AS INTEGER      ' Stores the previous 32-bit counter reading (0 to 4,294,967,295)
DIM TotalSigned64BitCount AS INTEGER    ' The accumulated 64-bit signed counter value
DIM CurrentRaw32BitReading AS INTEGER
DIM SignedDelta AS INTEGER

' --- INITIALIZATION (Run ONCE at program startup) ---
' Read the very first value of the counter to set the baseline.
' This assumes the counter starts at 0 or a known, consistent value.
' If the counter's initial state is truly arbitrary, you might need a reset mechanism.
TotalSigned64BitCount = 0 ' Start the total count at zero
LastRaw32BitReading = EXT_READ_32BIT_COUNTER_FUNCTION() ' REPLACE with your actual function to read the 32-bit counter

' --- COUNTER READING AND UPDATE LOGIC (Place this inside your main loop or timer interrupt) ---
' This block should be executed every time you want to update the counter.

   
   ' 1. Read the current 32-bit unsigned value from your external counter.
   CurrentRaw32BitReading = EXT_READ_32BIT_COUNTER_FUNCTION() ' REPLACE with your actual function

   ' 2. Calculate the raw difference.
   '    MicroMite BASIC performs this subtraction using 64-bit signed arithmetic.
   '    If the 32-bit counter has rolled over or under, this 'SignedDelta' will
   '    be a large positive or negative 64-bit number.
   SignedDelta = CurrentRaw32BitReading - LastRaw32BitReading

   ' 3. Correct for 32-bit unsigned rollovers/roll-unders.
   '    This is the core "magic" that converts the raw 64-bit difference
   '    into the correct signed 32-bit delta, accounting for the 32-bit wrap.
   '    Constants:
   '    &H100000000 = 2^32 = 4,294,967,296 (the full range of a 32-bit unsigned int)
   '    &H80000000  = 2^31 = 2,147,483,648 (the value of the 32-bit sign bit)

   ' If SignedDelta is a large positive number (e.g., Last=10, Current=4294967290, delta=4294967280)
   ' This indicates a roll-under from a small value to a large value (e.g., 10 -> -6)
   IF SignedDelta > 2147483647 THEN ' If delta > (2^31 - 1)
       SignedDelta = SignedDelta - 4294967296 ' Subtract 2^32 to make it correctly negative
   ' If SignedDelta is a large negative number (e.g., Last=4294967290, Current=10, delta=-4294967280)
   ' This indicates a roll-over from a large value to a small value (e.g., -6 -> 10)
   ELSEIF SignedDelta < -2147483648 THEN ' If delta < -2^31
       SignedDelta = SignedDelta + 4294967296 ' Add 2^32 to make it correctly positive
   END IF

   ' 4. Add the corrected signed delta to the total 64-bit counter.
   TotalSigned64BitCount = TotalSigned64BitCount + SignedDelta

   ' 5. Update LastRaw32BitReading for the next iteration.
   LastRaw32BitReading = CurrentRaw32BitReading

' --- TotalSigned64BitCount now holds the accurately extended signed 64-bit counter value ---
' PRINT "Extended 64-bit Counter: "; TotalSigned64BitCount


Stripped down and with short VAR names, ~60µS on RP2350 @378MHz
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5058
Posted: 09:26am 10 Jul 2025
Copy link to clipboard 
Print this post

On RP2040 @ 252MHz

x%=(x%<<32)/2^32

46us

If you define 2^32 up front as constant
const z%=2^32

x%=(x%<<32)/z%

38us

Volhout
Edited 2025-07-10 19:28 by Volhout
PicomiteVGA PETSCII ROBOTS
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1360
Posted: 10:36am 10 Jul 2025
Copy link to clipboard 
Print this post

Harm,

Yeah that's really quick  

However, I should've explained better; the one that I posted extends the counting range from:

INT32 (32-bit signed integer):

Minimum value: −2,147,483,648

Maximum value: 2,147,483,647

To:
INT64 (64-bit signed integer):

Minimum value: −9,223,372,036,854,775,808

Maximum value: 9,223,372,036,854,775,807


This could be very useful for a high-speed spindle that needs to run for thousands of years and not lose position due to rollover  
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025