tags:

views:

92

answers:

1

I have a

#define PROT_EN_DAT  0x140  
//(320 in decimal)

Its loaded into 64 bit value register(ex setup_data[39:8]=PROT_EN_DATA)

Now i want to put this value(0x140)into

 uint8_t    bRequest
 uint16_t   wValue
 uint16_t   wIndex

How can load the value so that i don't have to manually do it for other values again. I think we can do with shift operators but don know how.

EDIT:Ya its related to USB. bRequest(8:15),wValue(16:31),wIndex(32:47) but setup_data is 64 bit value.I want to know how can i load proper values into the these fields.

For example say next time i am using #define PROT_EN2_REG 0x1D8. and say setup_data[39:8]=PROT_EN2_DATA

+3  A: 

General read form:

aField = (aRegister >> kBitFieldLSBIndex) & ((1 << kBitFieldWidth) - 1)

General write form:

mask = ((1 << kBitFieldWidth) - 1) << kBitFieldLSBIndex;
aRegister = (aRegister & ~mask) | ((aField << kBitFieldLSBIndex) & mask);

where:

  • aRegister is the value you read from the bit-field-packed register,
  • kBitFieldLSBIndex is the index of the least significant bit of the bit field, and
  • kBitFieldWidth is the width of the bit field, and
  • aField is the value of the bit field

These are generalized, and some operations (such as bit-masking) may be unnecessary in your case. Replace the 1 with 1L if the register is larger than 32 bits.

EDIT: In your example case (setup_data[39:8]=PROT_EN_DATA):

Read:

aField = (setup_data >> 8) & ((1L << 32) - 1L)

Write:

#define PROT_EN_MASK = (((1L << 32) - 1L) << 8) // 0x0000000FFFFFFFF0
setup_data = (setup_data & ~PROT_EN_MASK) | ((PROT_EN_DATA << 8) & PROT_EN_MASK);
Mike DeSimone
@Mike: Note that `1 << kBitFieldWidth` has undefined behavior if `kBitFieldWidth` ≥ 31 (for 32-bit `int`). In practice your code will work almost everywhere, but still gives the wrong result when working with a register whose size is larger than `int`: `1 << kBitFieldWidth` should be `(type_of_aRegister)1 << kBitFieldWidth`, and `aField << kBitFieldLSBIndex` should be `(type_of_aRegister)aField << kBitFieldWidth`.
Gilles
Yeah, I rely on the programmer to realize that they need to change the `1`s to `1L`s in the case of 64-bit registers, and to use unsigned storage types (as the question author did), but I'll update the answer anyway.
Mike DeSimone