Shop OBEX P1 Docs P2 Docs Learn Events
bit shifting a 48bits number — Parallax Forums

bit shifting a 48bits number

Peter VerkaikPeter Verkaik Posts: 3,956
edited 2007-12-24 23:02 in Propeller 1
Does anyone know a more elegant/better way to scale a 48bit number to a 32bit number?

· 'at this point responseBuffer[noparse][[/noparse]0] to responseBuffer[noparse][[/noparse]5] is filled, responseBuffer[noparse][[/noparse]0] is LSB
· if power2 == 0 'report bytes
··· if responseBuffer[noparse][[/noparse]4] <> 0 or responseBuffer[noparse][[/noparse]5]<>0 'bytesize is larger than 32bits
····· return -1
· if power2 == 10 'report kilobytes
··· responseBuffer[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]1]· 'shift 8bits
··· responseBuffer[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]2]
··· responseBuffer[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]3]
··· responseBuffer[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]4]
··· responseBuffer[noparse][[/noparse]4] := responseBuffer[noparse][[/noparse]5]
··· responseBuffer[noparse][[/noparse]0] := (responseBuffer[noparse][[/noparse]0] >> 2) | (responseBuffer[noparse][[/noparse]1] << 6)· 'shift 2bits
··· responseBuffer[noparse][[/noparse]1] := (responseBuffer[noparse][[/noparse]1] >> 2) | (responseBuffer[noparse][[/noparse]2] << 6)
··· responseBuffer[noparse][[/noparse]2] := (responseBuffer[noparse][[/noparse]2] >> 2) | (responseBuffer[noparse][[/noparse]3] << 6)
··· responseBuffer[noparse][[/noparse]3] := (responseBuffer[noparse][[/noparse]3] >> 2) | (responseBuffer[noparse][[/noparse]4] << 6)
· if power2 == 20 'report megabytes
··· responseBuffer[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]2]· 'shift 16bits
··· responseBuffer[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]3]
··· responseBuffer[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]4]
··· responseBuffer[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]5]
··· responseBuffer[noparse][[/noparse]0] := (responseBuffer[noparse][[/noparse]0] >> 4) | (responseBuffer[noparse][[/noparse]1] << 4)· 'shift 4 bits
··· responseBuffer[noparse][[/noparse]1] := (responseBuffer[noparse][[/noparse]1] >> 4) | (responseBuffer[noparse][[/noparse]2] << 4)
··· responseBuffer[noparse][[/noparse]2] := (responseBuffer[noparse][[/noparse]2] >> 4) | (responseBuffer[noparse][[/noparse]3] << 4)
··· responseBuffer[noparse][[/noparse]3] := (responseBuffer[noparse][[/noparse]3] >> 4)
· free.byte[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]0]
· free.byte[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]1]
· free.byte[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]2]
· free.byte[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]3]
· return free

regards peter

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2007-12-24 20:14
    I think this is fine, as long as you do not know where the LONG alignment is. A space optimization will be to perform the first part twice for mega bytes...
  • Tracy AllenTracy Allen Posts: 6,660
    edited 2007-12-24 20:37
    Peter,

    Could BYTEMOVE help with the first part? Is long alignment out of the question?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-12-24 21:04
    The responseBuffer is defined in the VAR section of an object.
    VAR
    · byte SPI_CS··· 'chip select· - connects to Datalogger pin CS
    · byte SPI_CLK·· 'clock output - connects to Datalogger pin SCLK······
    · byte SPI_SDI·· 'data input·· - connects to Datalogger pin SDO
    · byte SPI_SDO·· 'data output· - connects to Datalogger pin SDI

    · byte responseBuffer[noparse][[/noparse]BUFSIZE]

    Does the VAR section always start at a long boundary?
    Or should I define
    VAR
    · long dummy
    · byte SPI_CS··· 'chip select· - connects to Datalogger pin CS
    · byte SPI_CLK·· 'clock output - connects to Datalogger pin SCLK······
    · byte SPI_SDI·· 'data input·· - connects to Datalogger pin SDO
    · byte SPI_SDO·· 'data output· - connects to Datalogger pin SDI
    · byte responseBuffer[noparse][[/noparse]BUFSIZE]

    that way responseBuffer is known to be at a long boundary.

    regards peter
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-24 21:46
    No, Peter, it's not. VAR works differently.. However you can put it into the DAT section:
    DAT
       responseBuffer LONG BYTE 0[noparse][[/noparse]BUFSIZE]
    
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-12-24 22:14
    I want to support multiple devices so I can not use DAT.

    Space saving:

    · 'at this point responseBuffer[noparse][[/noparse]0] to responseBuffer[noparse][[/noparse]5] is filled, responseBuffer[noparse][[/noparse]0] is LSB
    · repeat while power2/10 > 0
    ··· responseBuffer[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]1]· 'shift 8bits
    ··· responseBuffer[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]2]
    ··· responseBuffer[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]3]
    ··· responseBuffer[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]4]
    ··· responseBuffer[noparse][[/noparse]4] := responseBuffer[noparse][[/noparse]5]
    ··· responseBuffer[noparse][[/noparse]5] := 0
    ··· responseBuffer[noparse][[/noparse]0] := (responseBuffer[noparse][[/noparse]0] >> 2) | (responseBuffer[noparse][[/noparse]1] << 6)· 'shift 2bits
    ··· responseBuffer[noparse][[/noparse]1] := (responseBuffer[noparse][[/noparse]1] >> 2) | (responseBuffer[noparse][[/noparse]2] << 6)
    ··· responseBuffer[noparse][[/noparse]2] := (responseBuffer[noparse][[/noparse]2] >> 2) | (responseBuffer[noparse][[/noparse]3] << 6)
    ··· responseBuffer[noparse][[/noparse]3] := (responseBuffer[noparse][[/noparse]3] >> 2) | (responseBuffer[noparse][[/noparse]4] << 6)
    ··· responseBuffer[noparse][[/noparse]4] := (responseBuffer[noparse][[/noparse]4] >> 2)
    ··· power2 -= 10
    · if responseBuffer[noparse][[/noparse]4] <> 0 or responseBuffer[noparse][[/noparse]5]<>0 'size cannot be represented by·32bits
    ··· return -1
    · free.byte[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]0]
    · free.byte[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]1]
    · free.byte[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]2]
    · free.byte[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]3]
    · return free

    This is somewhat better I guess.

    regards peter
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-24 22:22
    Do you know this variant of REPEAT?
    REPEAT power2/10
    
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-12-24 22:23
    The best I can come up with (thanks for·your latest suggestion)

    · 'at this point responseBuffer[noparse][[/noparse]0] to responseBuffer[noparse][[/noparse]5] is filled, responseBuffer[noparse][[/noparse]0] is LSB
    · repeat·power2/10
    ··· repeat i from 0 to 4
    ····· responseBuffer[noparse][[/noparse]i] := responseBuffer[noparse][[/noparse]i+1]· 'shift 8bits
    ··· responseBuffer[noparse][[/noparse]5] := 0
    ··· repeat i from 0 to 4
    ····· responseBuffer[noparse][[/noparse]i] := (responseBuffer[noparse][[/noparse]i] >> 2) | (responseBuffer[noparse][[/noparse]i+1] << 6)· 'shift 2bits
    ··· power2 -= 10
    · if responseBuffer[noparse][[/noparse]4] <> 0 or responseBuffer[noparse][[/noparse]5]<>0 'size cannot be represented by·32bits
    ··· return -1
    · free.byte[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]0]
    · free.byte[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]1]
    · free.byte[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]2]
    · free.byte[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]3]
    · return free

    regards peter
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-24 22:44
    I should also support Tracy's idea (useing BYTEMOVE for the first 5 bytes)!
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-12-24 23:02
    Right.

    · 'at this point responseBuffer[noparse][[/noparse]0] to responseBuffer[noparse][[/noparse]5] is filled, responseBuffer[noparse][[/noparse]0] is LSB
    · repeat·power2/10
    ··· bytemove(@responseBuffer,@responseBuffer+1,5)
    ··· responseBuffer[noparse][[/noparse]5] := 0
    ··· repeat i from 0 to 4
    ····· responseBuffer[noparse][[/noparse]i] := (responseBuffer[noparse][[/noparse]i] >> 2) | (responseBuffer[noparse][[/noparse]i+1] << 6)· 'shift 2bits
    ··· power2 -= 10
    · if responseBuffer[noparse][[/noparse]4] <> 0 or responseBuffer[noparse][[/noparse]5]<>0 'size cannot be represented by·32bits
    ··· return -1
    · free.byte[noparse][[/noparse]0] := responseBuffer[noparse][[/noparse]0]
    · free.byte[noparse][[/noparse]1] := responseBuffer[noparse][[/noparse]1]
    · free.byte[noparse][[/noparse]2] := responseBuffer[noparse][[/noparse]2]
    · free.byte[noparse][[/noparse]3] := responseBuffer[noparse][[/noparse]3]
    · return free

    That works. I will upload my DataloggerSPI object shortly where this is part of.

    Thanks.
    regards peter
Sign In or Register to comment.