0

I want to create specific byte - uint8_t to set it in a register.

This byte consists from 2 sections. Bits <7:6> is a multiplication factor.

These 2 bits can be: 00 for multiplication with 1 01 for multiplication with 4 10 for multiplication with 16 11 for multiplication with 64

for these 2 bits i am using an enum like:

typedef enum multiFactorEnum{
FACTOR_1,
FACTOR_4,
FACTOR_16,
FACTOR_64
}MultiFactor;

For the rest bytes it can be whatever number from 1 - 63 (representing time) since this is the value if you set the bit <5:0> to 1.

So when i know what factor i should use i am creation the value as

uint8_t val = (MultiFactor::FACTOR16 << 6 ) | timeValue;

This is giving me an issue:

'<<' in boolean context, did you mean '<'

I tried to cast the enum to uint8_t but it is not correct.

kyrpav
  • 756
  • 1
  • 13
  • 43
  • Does this answer your question? [How do you set, clear, and toggle a single bit?](https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit) – Ghasem Ramezani Aug 28 '21 at 20:20
  • Just curious : Isn't that supposed to be an arithmetic bitwise OR (`|`) ? – WhozCraig Aug 28 '21 at 20:20
  • 1
    `|| timeValue;`, you mean `| timeValue;` right? – Nick is tired Aug 28 '21 at 20:21
  • 2
    Please note that there is no such language as "C/C++". Only the two separate and *very* different languages C and C++. Even such things as enumerations are different in the two languages. – Some programmer dude Aug 28 '21 at 20:21
  • i do not think so. My problem is with enum. I am expecting to get the value but it is not. so shifting an enum has no meaning if this is not done immediately to the value – kyrpav Aug 28 '21 at 20:23
  • dear nic and whozcraig you are correct i missclicked here it is only | – kyrpav Aug 28 '21 at 20:24
  • dear some programmer dude , c/c++ is ofcouse 2 different languages but what you are coding for microcontrollers such as esp32 you can use object oriented logic and code with several limitations of c. this is why it is usually writen like this. for your second comment, i want to shift the values 6 bits. and this is giving me issue when i try to do it by calling the enum. – kyrpav Aug 28 '21 at 20:28
  • 1
    `(MultiFactor::FACTOR16 << 6 ) | timeValue` can you explain what does it suppose to do? – 0___________ Aug 28 '21 at 20:28
  • 1
    There is an error in your `enum` declaration; remove the `=` before the opening `{`. – Adrian Mole Aug 28 '21 at 20:30
  • I need to get value of enum which is for specific factor16 = 2--> 10 (in bits) and shift it to bits <7:6> – kyrpav Aug 28 '21 at 20:30
  • 1
    @0___________ Looks alright to me - it's shifting the (2-bit) value of the enum constant into the upper two bits of the result. – Adrian Mole Aug 28 '21 at 20:32
  • I think that using `union` might be more appropriate when dealing with microcontrollers... – Phil1970 Aug 28 '21 at 20:45

2 Answers2

2
typedef enum{
    FACTOR_1 = 0,
    FACTOR_4 = 1 << 6,
    FACTOR_16 = 2 << 6,
    FACTOR_64 = 3 << 6,
}MultiFactor;
uint8_t val = MultiFactor::FACTOR_16 | timeValue;

if you need to clear bits 6:7 in the time value before ORing

uint8_t val = MultiFactor::FACTOR_16 | (timeValue & ~MultiFactor::FACTOR_64);
0___________
  • 60,014
  • 4
  • 34
  • 74
  • i will check the workaround but the question is why i can not call the enum and shift it whenever to whatever value i want which could be dynamic, cause i could use the same enum to the several cases – kyrpav Aug 28 '21 at 20:39
  • Much more better than original code as you don't have to do the shift every time. Even better would be to have `FACTOR_BITS` as an additional value (and 6 as a constant). – Phil1970 Aug 28 '21 at 20:43
  • if shifting is dynamic then and it is not always 6 then? and is the real answer that i should not use call to enum and shift it? – kyrpav Aug 28 '21 at 20:46
  • This would be a great answer on Code Review, but it doesn't answer the original question of why the expression in the question generates an error. – Mark Ransom Aug 28 '21 at 21:14
  • @MarkRansom it does not require an answer as it was a simple typo (`||` instead of `|`). – 0___________ Aug 28 '21 at 21:16
  • Then it should be closed instead of answered. – Mark Ransom Aug 28 '21 at 21:17
  • So it was closed at some point, then reopened? But with the typo gone I'm guessing it does not generate the stated error, so it should have remained closed. – Mark Ransom Aug 28 '21 at 21:20
  • @MarkRansom The answer would not be a great answer on Code Review and would be subject to deletion. – Peilonrayz Aug 28 '21 at 21:22
  • @Peilonrayz your comment here should be a subject of deletion too. – 0___________ Aug 28 '21 at 21:26
  • @markRansom you are correct. problem is on shifting of enum not in || which only exists on the example here from my typo problem. either way i am accepting the work around to finish this debate – kyrpav Aug 28 '21 at 21:38
1

You can also use a bit field within a union, if you like; it does the same thing, but is maybe a bit more intuitive:

typedef enum {
    factor_1  = 0,
    factor_4  = 1,
    factor_16 = 2,
    factor_64 = 3,
} factors_;


union Register{
    struct {
        uint8_t time: 6;
        uint8_t factor: 2;
    };
    uint8_t out;
};

int main() {
    Register myRegister;
    myRegister.factor = factor_64;
    myRegister.time = 1;
    uint8_t registerToSet = myRegister.out;
    return 0;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
LexusA
  • 23
  • 3