Error in Bit manipulation

int watch_get_date(uint8_t* year, uint8_t* month, uint8_t* day_of_month)
{
    uint8_t date_bits_low, date_bits_high;

    if (year == NULL || month == NULL || day_of_month == NULL)
    {
        return -1;
    }

    if (watch_i2c_read_byte(ADDRESS_DATE_LOW, &date_bits_low) != 0)
    {
        return -1;
    }
    if (watch_i2c_read_byte(ADDRESS_DATE_HIGH, &date_bits_high) != 0)
    {
        return -1;
    }

    watch_registers_get_date(
                date_bits_low, date_bits_low, year, month, day_of_month);

    return 0;
}

.h file
void watch_registers_get_date(
            uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year,
            uint8_t* month, uint8_t* day_of_month);
void watch_registers_get_date(
            uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year,
            uint8_t* month, uint8_t* day_of_month)
{
    
    *year = date_bits_low & 0b01111111 ; 
 
    *month = ((date_bits_high & 0b00000111)<<1) + (date_bits_low <<7);

    *day_of_month = ((date_bits_high & 0b11111000 >>3));

    
}

I keep getting an error with get date of month while making a test case can someone see what it is

And that error is...?

watch_registers_get_date *month somehowe i didnt shift the bits good

i was thinking of this
*month = ((date_bits_high & 0b00000111)<<1) + ((date_bits_low & 0b00000001)<<7);

but got this instead
*month = ((date_bits_high & 0b00000111)<<1) + (date_bits_low <<7);

Seems fishy, there are months above 128, but never odd ones. Maybe you want

*month = ((date_bits_high & 0b00000111) << 1 ) + (date_bits_low >> 7);

That doesn't look right. Should there be a date_bits_high in there?

its a project i learn for school i am new to this.
watch_registers_get_date *month somehowe i didnt shift the bits good

i was thinking of this
*month = ((date_bits_high & 0b00000111)<<1) + ((date_bits_low & 0b00000001)<<7);

but got this instead
*month = ((date_bits_high & 0b00000111)<<1) + (date_bits_low <<7);

i see 2 times date_bits_low :smiling_face_with_tear:

date_bits_low we have m[0]
date_bits_high we have m[3] m[2] m[1]

You can probably do it without an explicit shift (but I guess the compiler would do it in the back ground anyway). Something like:

*month = (date_bits_high % 8 ) * 2 + date_bits_low / 128 ;

i understand what you mean this i cant put in the code . after i create a testcase its an error because mine shifting is not good og *get month

Since the month field crosses the byte boundary I would glue the two bytes together into a 16-bit word and do the shifting and masking on the word.

void watch_registers_get_date(
  uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year,
  uint8_t* month, uint8_t* day_of_month)
{
  uint16_t fullDate = word(date_bits_high, date_bits_low);

  *year = fullDate & 0b01111111;

  *month = (fullDate >> 7) & 0b00001111;

  *day_of_month = (fullDate >> 11) & 0b00011111;
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.