News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Store to SDWORD

Started by Giuseppe MPO, Jul 27, 2021, 11:49 PM

Previous topic - Next topic

Giuseppe MPO


I have a 36 bit number 2's complement notation
contained in 4 bytes and a half,
to store it in an SDWORD variable (32bit) can
I simply shift to the right 4 bits?

trastikata

Quote from: MPO on Jul 27, 2021, 11:49 PMI have a 36 bit number to store it in an SDWORD variable (32bit)

MPO is it to assume that the maximum value held in those 36 bits is actually signed 32 bits?

charliecoutas

An SDWORD is 32 bits long. I don't see how you can get 36 bits into a 32 bit space.

Giuseppe MPO

Quote from: trastikata on Jul 28, 2021, 07:16 AMMPO is it to assume that the maximum value held in those 36 bits is actually signed 32 bits?
The number in the variable is not a question of size, but a question of resolution,
36bit is useless and unwieldy for me to manage, for that it would be sufficient even at 32bit.
In fact I could also add that, for my uses, it would also be sufficient a SWORD

charliecoutas

Ah, I see what you mean. Yes, a shift right of 1 would halve the value and a shift of 4 would divide it by 16.
So yes, a right shift of 4 would do it. But what about the sign bit? This would always leave the sign bit clear so is that OK?

Charlie

John Drew

I'm trying to work out how you store the 36bit number and therefore how you can manipulate it. Are they bits or bytes coming in serially? If so we can work out how to deal with it.
John

tumbleweed

QuoteI have a 36 bit number 2's complement notation
contained in 4 bytes and a half
Just ignore the "half byte"... throw it away and use the first 4 bytes for a 32-bit result.

If you only need a SWORD then drop all but the first two bytes.

John Drew

As Charlie said, what about the sign bit? I bet it's in the half byte.
Wouldn't be hard to copy that into the high byte of the new SDWORD.
John

Giuseppe MPO

The half byte contains the sign and the most significant part of the number,
I can't ignore it. What I did is shift the whole thing 4 bits to the right and insert the half byte.
Then treating the resulting number as SDWORD,
I wanted to know if this is the right procedure.
To better explain the 36bit number is the result of a CIP peripheral of a PIC16F1619, the PID peripheral.

tumbleweed

QuoteThe half byte contains the sign and the most significant part of the number
You might have mentioned that to begin with.

assuming 2's compliment you've got-
PIDxACCU:  xxxx SSSS
PIDxACCUHH: byte 3
PIDxACCUHL: byte 2
PIDxACCULH: byte 1
PIDxACCULL: byte 0

create a 32 bit unsigned Dword comprised of bytes 3, 2, 1, and 0
shift 32-bit Dword right 4 times (to make room for SSSS)

shift byte PIDxACCU left 4 times
OR shifted PICxACCU with upper byte of 32-bit Dword

result is a 2's compliment signed 32-bit value (SDword)

Giuseppe MPO

Quote from: tumbleweed on Jul 28, 2021, 02:13 PMYou might have mentioned that to begin with.

assuming 2's compliment you've got-
PIDxACCU:  xxxx SSSS
PIDxACCUHH: byte 3
PIDxACCUHL: byte 2
PIDxACCULH: byte 1
PIDxACCULL: byte 0

create a 32 bit unsigned Dword comprised of bytes 3, 2, 1, and 0
shift 32-bit Dword right 4 times (to make room for SSSS)

shift byte PIDxACCU left 4 times
OR shifted PICxACCU with upper byte of 32-bit Dword

result is a 2's compliment signed 32-bit value (SDword)



Having done it like this:

      Dim Out_PID As Dword
      Dim Out_ParM As Byte = 0


      Out_ParM = PID1OUTU

      Out_PID.Byte3 = PID1OUTHH
              Out_PID.Byte2 = PID1OUTHL
              Out_PID.Byte1 = PID1OUTLH
              Out_PID.Byte0 = PID1OUTLL
             
             
              Out_PID = Out_PID >> 4
      Out_PID = Out_PID + (Out_ParM * 0x10000000)


Then treating the Out_PID variable as an SDWORD

to be right?

tumbleweed

That last part requires a 32-bit multiply, so it takes a bit of extra code + time, but it should get you there.

Try this:
'instead of
Out_PID = Out_PID + (Out_ParM * 0x10000000)

' use      
Out_ParM = PID1OUTU << 4
Out_PID.Byte3 = Out_PID.Byte3 | Out_ParM
It takes half the code

Giuseppe MPO

Quote from: tumbleweed on Jul 28, 2021, 02:13 PMYou might have mentioned that to begin with.

assuming 2's compliment you've got-
PIDxACCU:  xxxx SSSS
PIDxACCUHH: byte 3
PIDxACCUHL: byte 2
PIDxACCULH: byte 1
PIDxACCULL: byte 0

create a 32 bit unsigned Dword comprised of bytes 3, 2, 1, and 0
shift 32-bit Dword right 4 times (to make room for SSSS)

shift byte PIDxACCU left 4 times
OR shifted PICxACCU with upper byte of 32-bit Dword

result is a 2's compliment signed 32-bit value (SDword)

executing this method, I do not get a reduction of bits from 36 to 32,
but a series of nonsense numbers.
I do not think we can apply the procedure of shifting the bits in the 2's complement notation.
Unfortunately I'm getting confused,I can't resolve. Can anyone help me?

Thank you

trastikata

Quote from: MPO on Jul 31, 2021, 11:39 PMUnfortunately I'm getting confused,I can't resolve. Can anyone help me?

When you print PIDxOut, keep in mind that it is a signed value, thus use the modifier for signed variables i.e. SDec

Dim PIDxInDword As Dword   'Holds the first 32 bits
Dim PIDxInByte As Byte    'Holds the extra 4 bits
Dim PIDxOut As SDword   'Holds the 32 bit decimated value



Main:
    PIDxOut = Convert36bTo32b(PIDxInDword, PIDxInByte)
End

Proc Convert36bTo32b (PIDxInDword As Dword, PIDxInByte As Byte), SDword
    Dim TempWord As Word        'Temporary variable
    Dim TempSDword As SDword    'Temporary variable

    TempWord.Byte1 = PIDxInByte
    TempWord.Byte0 = PIDxInDword.Byte3
    TempWord = TempWord >> 4
    TempSDword = PIDxInDword >> 4
    TempSDword.Byte3 = TempWord.Byte0
   
    Result = TempSDword
EndProc

Giuseppe MPO