drivers: i2c: stm32: add target mode in RTIO drivers
Implement I2C target mode in STM32 I2C RTIO drivers. The implementation in respectively i2c_ll_stm32_v1_rtio.c and i2c_ll_stm32_v2_rtio.c is based on the implementation of the non-RTIO drivers, respectively i2c_ll_stm32_v1.c and i2c_ll_stm32_v2_rtio.c. Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
This commit is contained in:
parent
e16c9bb41d
commit
79d1803efe
@ -114,14 +114,6 @@ struct i2c_stm32_data {
|
||||
unsigned int len;
|
||||
uint8_t *buf;
|
||||
} current;
|
||||
#ifdef CONFIG_I2C_TARGET
|
||||
bool master_active;
|
||||
struct i2c_target_config *slave_cfg;
|
||||
#ifdef CONFIG_I2C_STM32_V2
|
||||
struct i2c_target_config *slave2_cfg;
|
||||
#endif /* CONFIG_I2C_STM32_V2 */
|
||||
bool slave_attached;
|
||||
#endif /* CONFIG_I2C_TARGET */
|
||||
bool is_configured;
|
||||
bool smbalert_active;
|
||||
enum i2c_stm32_mode mode;
|
||||
@ -135,6 +127,15 @@ struct i2c_stm32_data {
|
||||
struct dma_block_config dma_blk_cfg;
|
||||
#endif /* CONFIG_I2C_STM32_V2_DMA */
|
||||
#endif /* CONFIG_I2C_RTIO */
|
||||
|
||||
#ifdef CONFIG_I2C_TARGET
|
||||
bool master_active;
|
||||
bool slave_attached;
|
||||
struct i2c_target_config *slave_cfg;
|
||||
#ifdef CONFIG_I2C_STM32_V2
|
||||
struct i2c_target_config *slave2_cfg;
|
||||
#endif /* CONFIG_I2C_STM32_V2 */
|
||||
#endif /* CONFIG_I2C_TARGET */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_I2C_RTIO
|
||||
@ -145,13 +146,14 @@ int i2c_stm32_msg_start(const struct device *dev, uint8_t flags,
|
||||
int i2c_stm32_transaction(const struct device *dev,
|
||||
struct i2c_msg msg, uint8_t *next_msg_flags,
|
||||
uint16_t periph);
|
||||
#endif /* CONFIG_I2C_RTIO */
|
||||
|
||||
int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config);
|
||||
|
||||
#ifdef CONFIG_I2C_TARGET
|
||||
int i2c_stm32_target_register(const struct device *dev, struct i2c_target_config *config);
|
||||
int i2c_stm32_target_unregister(const struct device *dev, struct i2c_target_config *config);
|
||||
#endif /* CONFIG_I2C_TARGET */
|
||||
#endif /* CONFIG_I2C_RTIO */
|
||||
|
||||
int i2c_stm32_activate(const struct device *dev);
|
||||
int i2c_stm32_configure_timing(const struct device *dev, uint32_t clk);
|
||||
|
||||
@ -40,7 +40,7 @@ LOG_MODULE_REGISTER(i2c_ll_stm32_rtio);
|
||||
#define I2C_STM32_DOMAIN_CLOCK_SUPPORT 0
|
||||
#endif
|
||||
|
||||
static int i2c_stm32_do_configure(const struct device *dev, uint32_t config)
|
||||
int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
@ -121,7 +121,7 @@ bool i2c_stm32_start(const struct device *dev)
|
||||
return i2c_stm32_msg_start(dev, flags, (uint8_t *)sqe->tx.buf,
|
||||
sqe->tx.buf_len, dt_spec->addr);
|
||||
case RTIO_OP_I2C_CONFIGURE:
|
||||
res = i2c_stm32_do_configure(dev, sqe->i2c_config);
|
||||
res = i2c_stm32_runtime_configure(dev, sqe->i2c_config);
|
||||
return i2c_rtio_complete(data->ctx, res);
|
||||
default:
|
||||
LOG_ERR("Invalid op code %d for submission %p\n", sqe->op, (void *)sqe);
|
||||
@ -214,6 +214,10 @@ static const struct i2c_driver_api api_funcs = {
|
||||
.transfer = i2c_stm32_transfer,
|
||||
.get_config = i2c_stm32_get_config,
|
||||
.iodev_submit = i2c_stm32_submit,
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
.target_register = i2c_stm32_target_register,
|
||||
.target_unregister = i2c_stm32_target_unregister,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int i2c_stm32_init(const struct device *dev)
|
||||
@ -259,7 +263,7 @@ static int i2c_stm32_init(const struct device *dev)
|
||||
|
||||
bitrate_cfg = i2c_map_dt_bitrate(cfg->bitrate);
|
||||
|
||||
ret = i2c_stm32_do_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
|
||||
ret = i2c_stm32_runtime_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("i2c: failure initializing");
|
||||
return ret;
|
||||
|
||||
@ -71,8 +71,17 @@ static void i2c_stm32_master_mode_end(const struct device *dev, int status)
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
|
||||
i2c_stm32_disable_transfer_interrupts(dev);
|
||||
LL_I2C_Disable(i2c);
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
data->master_active = false;
|
||||
if (data->slave_attached) {
|
||||
i2c_stm32_enable_transfer_interrupts(dev);
|
||||
LL_I2C_AcknowledgeNextData(i2c, LL_I2C_ACK);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
LL_I2C_Disable(i2c);
|
||||
if ((data->xfer_len == 0U) && i2c_rtio_complete(ctx, status)) {
|
||||
i2c_stm32_start(dev);
|
||||
}
|
||||
@ -277,12 +286,150 @@ static void handle_btf(const struct device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
static void i2c_stm32_target_event(const struct device *dev)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
const struct i2c_target_callbacks *target_cb =
|
||||
data->slave_cfg->callbacks;
|
||||
|
||||
if (LL_I2C_IsActiveFlag_TXE(i2c) && LL_I2C_IsActiveFlag_BTF(i2c)) {
|
||||
uint8_t val;
|
||||
|
||||
target_cb->read_processed(data->slave_cfg, &val);
|
||||
LL_I2C_TransmitData8(i2c, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_RXNE(i2c)) {
|
||||
uint8_t val = LL_I2C_ReceiveData8(i2c);
|
||||
|
||||
if (target_cb->write_received(data->slave_cfg, val)) {
|
||||
LL_I2C_AcknowledgeNextData(i2c, LL_I2C_NACK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_AF(i2c)) {
|
||||
LL_I2C_ClearFlag_AF(i2c);
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_STOP(i2c)) {
|
||||
LL_I2C_ClearFlag_STOP(i2c);
|
||||
target_cb->stop(data->slave_cfg);
|
||||
/* Prepare to ACK next transmissions address byte */
|
||||
LL_I2C_AcknowledgeNextData(i2c, LL_I2C_ACK);
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_ADDR(i2c)) {
|
||||
uint32_t dir = LL_I2C_GetTransferDirection(i2c);
|
||||
|
||||
if (dir == LL_I2C_DIRECTION_READ) {
|
||||
target_cb->write_requested(data->slave_cfg);
|
||||
LL_I2C_EnableIT_RX(i2c);
|
||||
} else {
|
||||
uint8_t val;
|
||||
|
||||
target_cb->read_requested(data->slave_cfg, &val);
|
||||
LL_I2C_TransmitData8(i2c, val);
|
||||
LL_I2C_EnableIT_TX(i2c);
|
||||
}
|
||||
|
||||
i2c_stm32_enable_transfer_interrupts(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach and start I2C as target */
|
||||
int i2c_stm32_target_register(const struct device *dev, struct i2c_target_config *config)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
uint32_t bitrate_cfg;
|
||||
int ret;
|
||||
|
||||
if (config == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->slave_attached) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (data->master_active) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
bitrate_cfg = i2c_map_dt_bitrate(cfg->bitrate);
|
||||
|
||||
ret = i2c_stm32_runtime_configure(dev, bitrate_cfg);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("i2c: failure initializing");
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->slave_cfg = config;
|
||||
|
||||
LL_I2C_Enable(i2c);
|
||||
|
||||
if (data->slave_cfg->flags == I2C_TARGET_FLAGS_ADDR_10_BITS) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
LL_I2C_SetOwnAddress1(i2c, config->address << 1U, LL_I2C_OWNADDRESS1_7BIT);
|
||||
data->slave_attached = true;
|
||||
|
||||
LOG_DBG("i2c: target registered");
|
||||
|
||||
i2c_stm32_enable_transfer_interrupts(dev);
|
||||
LL_I2C_AcknowledgeNextData(i2c, LL_I2C_ACK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_stm32_target_unregister(const struct device *dev, struct i2c_target_config *config)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
|
||||
if (!data->slave_attached) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->master_active) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
i2c_stm32_disable_transfer_interrupts(dev);
|
||||
|
||||
LL_I2C_ClearFlag_AF(i2c);
|
||||
LL_I2C_ClearFlag_STOP(i2c);
|
||||
LL_I2C_ClearFlag_ADDR(i2c);
|
||||
LL_I2C_Disable(i2c);
|
||||
|
||||
data->slave_attached = false;
|
||||
|
||||
LOG_DBG("i2c: target unregistered");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(CONFIG_I2C_TARGET) */
|
||||
|
||||
void i2c_stm32_event(const struct device *dev)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
if (data->slave_attached && !data->master_active) {
|
||||
i2c_stm32_target_event(dev);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (LL_I2C_IsActiveFlag_SB(i2c)) {
|
||||
handle_sb(dev);
|
||||
} else if (LL_I2C_IsActiveFlag_ADD10(i2c)) {
|
||||
@ -303,6 +450,15 @@ int i2c_stm32_error(const struct device *dev)
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
|
||||
if (data->slave_attached && !data->master_active) {
|
||||
/* No need for a target error function right now. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (LL_I2C_IsActiveFlag_AF(i2c)) {
|
||||
LL_I2C_ClearFlag_AF(i2c);
|
||||
LL_I2C_GenerateStopCondition(i2c);
|
||||
@ -338,6 +494,9 @@ int i2c_stm32_msg_start(const struct device *dev, uint8_t flags,
|
||||
data->msg_len = buf_len;
|
||||
data->is_restart = 0;
|
||||
data->slave_address = i2c_addr;
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
data->master_active = true;
|
||||
#endif
|
||||
|
||||
LL_I2C_Enable(i2c);
|
||||
|
||||
|
||||
@ -61,8 +61,260 @@ static void i2c_stm32_master_mode_end(const struct device *dev)
|
||||
if (LL_I2C_IsEnabledReloadMode(i2c)) {
|
||||
LL_I2C_DisableReloadMode(i2c);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
|
||||
data->master_active = false;
|
||||
if (!data->slave_attached) {
|
||||
LL_I2C_Disable(i2c);
|
||||
}
|
||||
#else
|
||||
LL_I2C_Disable(i2c);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
static void i2c_stm32_target_event(const struct device *dev)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
const struct i2c_target_callbacks *target_cb;
|
||||
struct i2c_target_config *target_cfg;
|
||||
|
||||
if (data->slave_cfg->flags != I2C_TARGET_FLAGS_ADDR_10_BITS) {
|
||||
uint8_t target_address;
|
||||
|
||||
/* Choose the right target from the address match code */
|
||||
target_address = LL_I2C_GetAddressMatchCode(i2c) >> 1;
|
||||
if (data->slave_cfg != NULL &&
|
||||
target_address == data->slave_cfg->address) {
|
||||
target_cfg = data->slave_cfg;
|
||||
} else if (data->slave2_cfg != NULL &&
|
||||
target_address == data->slave2_cfg->address) {
|
||||
target_cfg = data->slave2_cfg;
|
||||
} else {
|
||||
__ASSERT_NO_MSG(0);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* On STM32 the LL_I2C_GetAddressMatchCode & (ISR register) returns
|
||||
* only 7bits of address match so 10 bit dual addressing is broken.
|
||||
* Revert to assuming single address match.
|
||||
*/
|
||||
if (data->slave_cfg != NULL) {
|
||||
target_cfg = data->slave_cfg;
|
||||
} else {
|
||||
__ASSERT_NO_MSG(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target_cb = target_cfg->callbacks;
|
||||
|
||||
if (LL_I2C_IsActiveFlag_TXIS(i2c)) {
|
||||
uint8_t val;
|
||||
|
||||
if (target_cb->read_processed(target_cfg, &val) < 0) {
|
||||
LOG_ERR("Error continuing reading");
|
||||
} else {
|
||||
LL_I2C_TransmitData8(i2c, val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_RXNE(i2c)) {
|
||||
uint8_t val = LL_I2C_ReceiveData8(i2c);
|
||||
|
||||
if (target_cb->write_received(target_cfg, val)) {
|
||||
LL_I2C_AcknowledgeNextData(i2c, LL_I2C_NACK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_NACK(i2c)) {
|
||||
LL_I2C_ClearFlag_NACK(i2c);
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_STOP(i2c)) {
|
||||
i2c_stm32_disable_transfer_interrupts(dev);
|
||||
|
||||
/* Flush remaining TX byte before clearing Stop Flag */
|
||||
LL_I2C_ClearFlag_TXE(i2c);
|
||||
|
||||
LL_I2C_ClearFlag_STOP(i2c);
|
||||
|
||||
target_cb->stop(target_cfg);
|
||||
|
||||
/* Prepare to ACK next transmissions address byte */
|
||||
LL_I2C_AcknowledgeNextData(i2c, LL_I2C_ACK);
|
||||
}
|
||||
|
||||
if (LL_I2C_IsActiveFlag_ADDR(i2c)) {
|
||||
uint32_t dir;
|
||||
|
||||
LL_I2C_ClearFlag_ADDR(i2c);
|
||||
|
||||
dir = LL_I2C_GetTransferDirection(i2c);
|
||||
if (dir == LL_I2C_DIRECTION_WRITE) {
|
||||
if (target_cb->write_requested(target_cfg) < 0) {
|
||||
LOG_ERR("Error initiating writing");
|
||||
} else {
|
||||
LL_I2C_EnableIT_RX(i2c);
|
||||
}
|
||||
} else {
|
||||
uint8_t val;
|
||||
|
||||
if (target_cb->read_requested(target_cfg, &val) < 0) {
|
||||
LOG_ERR("Error initiating reading");
|
||||
} else {
|
||||
LL_I2C_TransmitData8(i2c, val);
|
||||
LL_I2C_EnableIT_TX(i2c);
|
||||
}
|
||||
}
|
||||
|
||||
i2c_stm32_enable_transfer_interrupts(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach and start I2C as target */
|
||||
int i2c_stm32_target_register(const struct device *dev,
|
||||
struct i2c_target_config *config)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
uint32_t bitrate_cfg;
|
||||
int ret;
|
||||
|
||||
if (config == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->slave_cfg && data->slave2_cfg) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (data->master_active) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
bitrate_cfg = i2c_map_dt_bitrate(cfg->bitrate);
|
||||
|
||||
ret = i2c_stm32_runtime_configure(dev, bitrate_cfg);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("i2c: failure initializing");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PM_DEVICE_RUNTIME)
|
||||
if (pm_device_wakeup_is_capable(dev)) {
|
||||
/* Mark device as active */
|
||||
(void)pm_device_runtime_get(dev);
|
||||
/* Enable wake-up from stop */
|
||||
LOG_DBG("i2c: enabling wakeup from stop");
|
||||
LL_I2C_EnableWakeUpFromStop(cfg->i2c);
|
||||
}
|
||||
#endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */
|
||||
|
||||
LL_I2C_Enable(i2c);
|
||||
|
||||
if (!data->slave_cfg) {
|
||||
data->slave_cfg = config;
|
||||
if (data->slave_cfg->flags == I2C_TARGET_FLAGS_ADDR_10_BITS) {
|
||||
LL_I2C_SetOwnAddress1(i2c, config->address, LL_I2C_OWNADDRESS1_10BIT);
|
||||
LOG_DBG("i2c: target #1 registered with 10-bit address");
|
||||
} else {
|
||||
LL_I2C_SetOwnAddress1(i2c, config->address << 1U, LL_I2C_OWNADDRESS1_7BIT);
|
||||
LOG_DBG("i2c: target #1 registered with 7-bit address");
|
||||
}
|
||||
|
||||
LL_I2C_EnableOwnAddress1(i2c);
|
||||
|
||||
LOG_DBG("i2c: target #1 registered");
|
||||
} else {
|
||||
data->slave2_cfg = config;
|
||||
|
||||
if (data->slave2_cfg->flags == I2C_TARGET_FLAGS_ADDR_10_BITS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
LL_I2C_SetOwnAddress2(i2c, config->address << 1U,
|
||||
LL_I2C_OWNADDRESS2_NOMASK);
|
||||
LL_I2C_EnableOwnAddress2(i2c);
|
||||
LOG_DBG("i2c: target #2 registered");
|
||||
}
|
||||
|
||||
data->slave_attached = true;
|
||||
|
||||
LL_I2C_EnableIT_ADDR(i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_stm32_target_unregister(const struct device *dev,
|
||||
struct i2c_target_config *config)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
struct i2c_stm32_data *data = dev->data;
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
|
||||
if (!data->slave_attached) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->master_active) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (config == data->slave_cfg) {
|
||||
LL_I2C_DisableOwnAddress1(i2c);
|
||||
data->slave_cfg = NULL;
|
||||
|
||||
LOG_DBG("i2c: target #1 unregistered");
|
||||
} else if (config == data->slave2_cfg) {
|
||||
LL_I2C_DisableOwnAddress2(i2c);
|
||||
data->slave2_cfg = NULL;
|
||||
|
||||
LOG_DBG("i2c: target #2 unregistered");
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return if there is a target remaining */
|
||||
if (data->slave_cfg || data->slave2_cfg) {
|
||||
LOG_DBG("i2c: target#%c still registered", data->slave_cfg?'1':'2');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise disable I2C */
|
||||
LL_I2C_DisableIT_ADDR(i2c);
|
||||
i2c_stm32_disable_transfer_interrupts(dev);
|
||||
|
||||
LL_I2C_ClearFlag_NACK(i2c);
|
||||
LL_I2C_ClearFlag_STOP(i2c);
|
||||
LL_I2C_ClearFlag_ADDR(i2c);
|
||||
|
||||
LL_I2C_Disable(i2c);
|
||||
|
||||
#if defined(CONFIG_PM_DEVICE_RUNTIME)
|
||||
if (pm_device_wakeup_is_capable(dev)) {
|
||||
/* Disable wake-up from STOP */
|
||||
LOG_DBG("i2c: disabling wakeup from stop");
|
||||
LL_I2C_DisableWakeUpFromStop(i2c);
|
||||
/* Release the device */
|
||||
(void)pm_device_runtime_put(dev);
|
||||
}
|
||||
#endif /* defined(CONFIG_PM_DEVICE_RUNTIME) */
|
||||
|
||||
data->slave_attached = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_I2C_TARGET) */
|
||||
|
||||
static void i2c_stm32_reload_burst(const struct device *dev)
|
||||
{
|
||||
const struct i2c_stm32_config *cfg = dev->config;
|
||||
@ -98,6 +350,13 @@ void i2c_stm32_event(const struct device *dev)
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
int ret = 0;
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
if (data->slave_attached && !data->master_active) {
|
||||
i2c_stm32_target_event(dev);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->burst_len != 0U) {
|
||||
/* Send next byte */
|
||||
if (LL_I2C_IsActiveFlag_TXIS(i2c)) {
|
||||
@ -166,6 +425,13 @@ int i2c_stm32_error(const struct device *dev)
|
||||
I2C_TypeDef *i2c = cfg->i2c;
|
||||
int ret = 0;
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
if (data->slave_attached && !data->master_active) {
|
||||
/* No need for a target error function right now. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (LL_I2C_IsActiveFlag_ARLO(i2c)) {
|
||||
LL_I2C_ClearFlag_ARLO(i2c);
|
||||
ret = -EIO;
|
||||
@ -233,6 +499,10 @@ int i2c_stm32_msg_start(const struct device *dev, uint8_t flags,
|
||||
LL_I2C_SetTransferRequest(i2c, transfer);
|
||||
LL_I2C_SetTransferSize(i2c, data->burst_len);
|
||||
|
||||
#if defined(CONFIG_I2C_TARGET)
|
||||
data->master_active = true;
|
||||
#endif
|
||||
|
||||
LL_I2C_Enable(i2c);
|
||||
|
||||
LL_I2C_GenerateStartCondition(i2c);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user