Битовая маскировка для I2 C пишет? - PullRequest
0 голосов
/ 05 августа 2020

Об этом, вероятно, уже спрашивали, но я не понимаю, как делать маскировку при записи с использованием I2 C. Скажем, у меня есть функция с именем i2c_update со следующими параметрами:

dev Pointer to the device structure for the driver instance.
dev_addr    Address of the I2C device for updating.
reg_addr    Address of the internal register being updated.
mask    Bitmask for updating internal register.
value   Value for updating internal register.

Я знаю, как работать с dev, dev_addr and reg_addr, но не понимаю, как маскировать и какое значение использовать. Например, если 0x00000111 находится в реестре, который я хочу изменить в настоящее время, и я хочу изменить его на 0x01000000, какой mask и какой value я бы хотел использовать?

Спасибо!

редактировать: это ссылка на API, который я использую

Ответы [ 2 ]

0 голосов
/ 06 августа 2020

Я просмотрел исходный код проекта Zephyr и нашел реализацию функции здесь :

static inline int i2c_reg_update_byte(struct device *dev, u8_t dev_addr,
                      u8_t reg_addr, u8_t mask,
                      u8_t value)
{
    u8_t old_value, new_value;
    int rc;

    rc = i2c_reg_read_byte(dev, dev_addr, reg_addr, &old_value);
    if (rc != 0) {
        return rc;
    }

    new_value = (old_value & ~mask) | (value & mask);
    if (new_value == old_value) {
        return 0;
    }

    return i2c_reg_write_byte(dev, dev_addr, reg_addr, new_value);
}

Как видите, действие net равно

new_value = (old_value & ~mask) | (value & mask);

Таким образом, он назначит только биты value, соответствующие единицам в mask, new_value, а остальные останутся такими же, как old_value.

0 голосов
/ 06 августа 2020

Поиск функции в репозитории проекта занимает 5 минут

static inline int i2c_reg_update_byte(struct device *dev, uint8_t dev_addr,
                      uint8_t reg_addr, uint8_t mask,
                      uint8_t value)
{
    uint8_t old_value, new_value;
    int rc;

    rc = i2c_reg_read_byte(dev, dev_addr, reg_addr, &old_value);
    if (rc != 0) {
        return rc;
    }

    new_value = (old_value & ~mask) | (value & mask);
    if (new_value == old_value) {
        return 0;
    }

    return i2c_reg_write_byte(dev, dev_addr, reg_addr, new_value);
}

new_value = (old_value & ~mask) | (value & mask);:

old_value & ~mask - очищает маскированные биты

value & mask очищает все остальные биты, кроме маски.

| устанавливает очищенные биты в old_value с битами, оставшимися в value

Вам нужно больше объяснений? Если да, то самое время изучить побитовые операции.

...