Advice on bit and byte manipulation

10 Jul 2012

I'm trying to translate some 8 bit code to MBED. What's the simplest approach to converting between high byte, low byte and 16 bit quantities. The compiler I was using supported "hi" and "lo" operators.

10 Jul 2012

us a union/struct

a struct takes up memory for each eliment,

whereas a union OVERLAPS each eliment,

if 8 bit micro then:

struct { ui64 Big; ui16 Medium [4] ui8 small [8] }

this would take 192 consecutive 8 bit memory locations, Whereras if a union would only be 64 bytes,

Big [ 12345678 ] Medium [ 12 ][ 34 ][ 56 ][ 78 ] Small [1][2][3][4][5][6][7][8]

check out google for more ansewrs :)

Ceri

10 Jul 2012

Show the code you're trying to convert. It will be easier to explain with a real example.

12 Jul 2012

Oh well it works now, mostly. Sorry if the shift-by-8-bits stuff makes experienced programmers cry, I did a bunch of odd stuff till it started to work, now I'm taking the junk out. Unusually the chip actually returns a signed short.

http://mbed.org/users/oliverb/code/MAX110/

Sorry the original is in an odd dielect of basic. Incidentally I did write this, a few years ago.

At the moment I'm mainly concerned with the "Endian-ness" of the SPI operations. Maybe I can just set the interface to 16 bits but I don't know which byte gets sent first.

module libmax110

const
      max_12bit=%1001001000000000
      max_13bit=%1000011000000000
      max_14bit=%1000110000000000
      max_div4 =%0000000100000000
      max_div2 =%0000000010000000
      max_chan1=%0000000000000000
      max_chan2=%0000000000010000
      max_full= %0000000000001100
'      max_gain= %0000000000001000
      max_ofs = %0000000000000100

'   procedure max_init(dim mode as word, dim byref port as byte, dim cs,bf as byte)
'
'   mode must be one of max_12bit, max_13bit, max_14bit
'   mode may be modified by "or-ing" with max_div2 or max_div4 to set clock divider
'   mode may be modified by "or-ing" with max_chan1 or max_chan2 to set input channel
'   mode may be modified by "or-ing" with a calibration type max_full,max_ofs
'
'   port is the port the busy and cs pins are connected to (doesn't have to be PORTC)
'   cs is the bit number for the chip select pin
'   bf is the bit number for the busy flag pin
'
'   function max_read(dim byref data as integer) as boolean
'
' notes returns true if a value was read, immediately restarts converter
' otherwise returns false
'
' result is integer, valid results are from -16384 through 16383.
' values beyond this are overrange
'

' MAX110/111 Control register bits
' 15         !NOOP   Set to 1 for action, 0 for pass-through
' 14         NU, set to 0
' 13         NU, set to 0
'                             CONV 4,3,2,1
' 12         CONV4                 1 0 0 1  20ms
' 11         CONV3                 0 0 1 1  40ms
' 10         CONV2                 0 1 1 0  160ms
'  9         CONV1                 0 0 0 0  200ms SPECIAL
'                    SPECIAL = NO INTERNAL GAIN CALIBRATION, FIX IN SOFTWARE
'  8         DV4           1=DIVIDE XCLK BY 4
'  7         DV2           1=DIVIDE XCLK BY 2
'
'  6         NU, set to 0
'  5         NU, set to 0

'  4         CHS               0:CHANNEL 1   1:CHANNEL2
'
'                                    CAL NUL FUNCTION
'                                     1   1   INTERNAL ZERO (PERFORM FIRST)
'  3         GAIN CAL                 1   0   INTERNAL GAIN (NEXT)
'  2         OFFSET NUL               0   1   INPUT NUL (LAST)
'                                     0   0   NORMAL CONVERT
'  1         PDX POWER DOWN OSC
'  0         PD POWER DOWN ADC


implements

dim
    max_mode as word
    max_port as ^byte
    max_cs,max_bf as byte

sub procedure max_setup(dim mode as word, dim byref port as byte, dim cs,bf as byte)
  max_mode=mode
  max_port=@port
  max_cs=cs
  max_bf=bf
  SPI_Init
  ClearBit(max_port^,max_cs)
  SPI_Write(hi(max_mode))
  SPI_Write(lo(max_mode))
  SetBit(max_port^,max_cs)
end sub
sub function max_read(dim byref data as integer) as boolean
dim t as word
  if TestBit(max_port^,max_bf) then
    if (max_mode) and %1100 then
      max_mode=max_mode-4
      ClearBit(max_port^,max_cs)
      SPI_Write(hi(max_mode))
      SPI_Write(lo(max_mode))
      SetBit(max_port^,max_cs)
      result=false
    else
      ClearBit(max_port^,max_cs)
      t = SPI_read(hi(max_mode))
      data = t*256 + SPI_read(lo(max_mode))
      SetBit(max_port^,max_cs)
      result=true
    end if
  else
    result=false
  end if
end sub
end.