1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

cpu/nrf52 i2c: Always buffer writes

The underlying peripheral can only read from RAM. This uses the
existing infrastructure (already needed to work around the lack of a
hardware support for I2C_NOSTART) to unconditionally copy any to-be-sent
data into RAM.
This commit is contained in:
chrysn 2024-01-25 15:23:07 +01:00
parent 0a06b0c1d8
commit b80d1e622f

View File

@ -92,6 +92,14 @@ static inline NRF_TWIM_Type *bus(i2c_t dev)
return i2c_config[dev].dev;
}
/**
* @brief Like i2c_write_bytes, but with the constraint (created by the
* hardware) that data is in RAM
*/
static int direct_i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data,
size_t len,
uint8_t flags);
/**
* Block until the interrupt described by inten_success_flag or
* TWIM_INTEN_ERROR_Msk fires.
@ -262,7 +270,7 @@ int i2c_write_regs(i2c_t dev, uint16_t addr, uint16_t reg,
}
memcpy(&tx_buf[reg_addr_len], data, len);
int ret = i2c_write_bytes(dev, addr, tx_buf, reg_addr_len + len, flags);
int ret = direct_i2c_write_bytes(dev, addr, tx_buf, reg_addr_len + len, flags);
/* Release tx_buf */
mutex_unlock(&buffer_lock);
@ -331,6 +339,27 @@ int i2c_read_regs(i2c_t dev, uint16_t addr, uint16_t reg,
int i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_t len,
uint8_t flags)
{
/* These are critical for the memcpy; direct_i2c_write_bytes makes some
* more */
assert((len > 0) && (len < 256));
/* Lock tx_buf */
mutex_lock(&buffer_lock);
memcpy(tx_buf, data, len);
int result = direct_i2c_write_bytes(dev, addr, tx_buf, len, flags);
/* Release tx_buf */
mutex_unlock(&buffer_lock);
return result;
}
int direct_i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data,
size_t len,
uint8_t flags)
{
assert((dev < I2C_NUMOF) && data && (len > 0) && (len < 256));