This has probably already been asked but I'm having trouble understanding how to do masking when writing using I2C. Say I have a function called i2c_update
with the following parameters:
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.
I know how to deal with the dev, dev_addr and reg_addr
but I'm confused on how to mask and what value to use. For example, if 0x00000111
is at the register I want to modify currently and I want to change it to 0x01000000
what mask
and what value
would I want to use?
Thanks!
It takes 5 minutes to find the function in the project repo
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
- clears masked bits
value & mask
clears all other bits except the mask
|
sets the cleared bits in the old_value
with the bits left in the value
Do you need more explanation? If yes it is the time to learn a bit bitwise operations.
I have looked up the Zephyr project source code and found the implementation of the function here:
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);
}
As you can see the net action is
new_value = (old_value & ~mask) | (value & mask);
So it will only assign the bits of value
corresponding to ones in the mask
to the new_value
, and the rest will remain same as old_value
.
User contributions licensed under CC BY-SA 3.0