Skip to content

Commit 624d9c1

Browse files
erian747jhedberg
authored andcommitted
drivers: i2c_stm32_v2: Refactor end of master transfer
The stm32_i2c_master_mode_end function can be replaced with a simple irq disable and giving to the device sync semaphore Signed-off-by: Erik Andersson <[email protected]>
1 parent 789e1d2 commit 624d9c1

File tree

1 file changed

+64
-81
lines changed

1 file changed

+64
-81
lines changed

drivers/i2c/i2c_ll_stm32_v2.c

Lines changed: 64 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -228,32 +228,6 @@ static void i2c_stm32_disable_transfer_interrupts(const struct device *dev)
228228
}
229229
}
230230

231-
static void i2c_stm32_master_mode_end(const struct device *dev)
232-
{
233-
const struct i2c_stm32_config *cfg = dev->config;
234-
struct i2c_stm32_data *data = dev->data;
235-
I2C_TypeDef *i2c = cfg->i2c;
236-
237-
i2c_stm32_disable_transfer_interrupts(dev);
238-
239-
if (LL_I2C_IsEnabledReloadMode(i2c)) {
240-
LL_I2C_DisableReloadMode(i2c);
241-
}
242-
243-
#if defined(CONFIG_I2C_TARGET)
244-
data->master_active = false;
245-
if (!data->slave_attached && !data->smbalert_active) {
246-
LL_I2C_Disable(i2c);
247-
}
248-
#else
249-
if (!data->smbalert_active) {
250-
LL_I2C_Disable(i2c);
251-
}
252-
#endif
253-
254-
k_sem_give(&data->device_sync_sem);
255-
}
256-
257231
#if defined(CONFIG_I2C_TARGET)
258232
static void i2c_stm32_slave_event(const struct device *dev)
259233
{
@@ -653,17 +627,77 @@ int i2c_stm32_error(const struct device *dev)
653627

654628
return 0;
655629
end:
656-
i2c_stm32_master_mode_end(dev);
630+
i2c_stm32_disable_transfer_interrupts(dev);
631+
/* Wakeup thread */
632+
k_sem_give(&data->device_sync_sem);
657633
return -EIO;
658634
}
659635

636+
static int stm32_i2c_irq_msg_finish(const struct device *dev, struct i2c_msg *msg)
637+
{
638+
struct i2c_stm32_data *data = dev->data;
639+
const struct i2c_stm32_config *cfg = dev->config;
640+
bool keep_enabled = (msg->flags & I2C_MSG_STOP) == 0U;
641+
int ret;
642+
643+
/* Wait for IRQ to complete or timeout */
644+
ret = k_sem_take(&data->device_sync_sem, K_MSEC(CONFIG_I2C_STM32_TRANSFER_TIMEOUT_MSEC));
645+
646+
#ifdef CONFIG_I2C_STM32_V2_DMA
647+
/* Stop DMA and invalidate cache if needed */
648+
dma_finish(dev, msg);
649+
#endif
650+
651+
/* Check for transfer errors or timeout */
652+
if (data->current.is_nack || data->current.is_arlo || (ret != 0)) {
653+
654+
if (data->current.is_arlo) {
655+
LOG_DBG("ARLO");
656+
}
657+
658+
if (data->current.is_nack) {
659+
LOG_DBG("NACK");
660+
}
661+
662+
if (data->current.is_err) {
663+
LOG_DBG("ERR %d", data->current.is_err);
664+
}
665+
666+
if (ret != 0) {
667+
LOG_DBG("TIMEOUT");
668+
}
669+
ret = -EIO;
670+
}
671+
672+
#if defined(CONFIG_I2C_TARGET)
673+
if (!keep_enabled || (ret != 0)) {
674+
data->master_active = false;
675+
}
676+
/* Don't disable I2C if a slave is attached */
677+
if (data->slave_attached) {
678+
keep_enabled = true;
679+
}
680+
#endif
681+
682+
/* Don't disable I2C if SMBus Alert is active */
683+
if (data->smbalert_active) {
684+
keep_enabled = true;
685+
}
686+
687+
/* If I2C no longer need to be enabled or on error */
688+
if (!keep_enabled || (ret != 0)) {
689+
LL_I2C_Disable(cfg->i2c);
690+
}
691+
692+
return ret;
693+
}
694+
660695
static int stm32_i2c_irq_xfer(const struct device *dev, struct i2c_msg *msg,
661696
uint8_t *next_msg_flags, uint16_t slave)
662697
{
663698
const struct i2c_stm32_config *cfg = dev->config;
664699
struct i2c_stm32_data *data = dev->data;
665700
I2C_TypeDef *regs = cfg->i2c;
666-
bool is_timeout = false;
667701

668702
data->current.len = msg->len;
669703
data->current.buf = msg->buf;
@@ -779,59 +813,8 @@ static int stm32_i2c_irq_xfer(const struct device *dev, struct i2c_msg *msg,
779813
/* Enable interrupts */
780814
LL_I2C_WriteReg(regs, CR1, cr1);
781815

782-
/* Wait for IRQ to complete or timeout */
783-
if (k_sem_take(&data->device_sync_sem,
784-
K_MSEC(CONFIG_I2C_STM32_TRANSFER_TIMEOUT_MSEC)) != 0U) {
785-
is_timeout = true;
786-
}
787-
788-
#ifdef CONFIG_I2C_STM32_V2_DMA
789-
/* Stop DMA and invalidate cache if needed */
790-
dma_finish(dev, msg);
791-
#endif
792-
/* Check for transfer errors or timeout */
793-
if (data->current.is_nack || data->current.is_arlo || is_timeout) {
794-
LL_I2C_Disable(regs);
795-
goto error;
796-
}
797-
798-
if ((msg->flags & I2C_MSG_STOP) != 0U) {
799-
/* Disable I2C if this was the last message and SMBus alert is not active */
800-
#if defined(CONFIG_I2C_TARGET)
801-
data->master_active = false;
802-
if (!data->slave_attached && !data->smbalert_active) {
803-
LL_I2C_Disable(regs);
804-
}
805-
#else
806-
if (!data->smbalert_active) {
807-
LL_I2C_Disable(regs);
808-
}
809-
#endif
810-
}
811-
812-
return 0;
813-
814-
error:
815-
if (data->current.is_arlo) {
816-
LOG_DBG("ARLO");
817-
data->current.is_arlo = 0U;
818-
}
819-
820-
if (data->current.is_nack) {
821-
LOG_DBG("NACK");
822-
data->current.is_nack = 0U;
823-
}
824-
825-
if (data->current.is_err) {
826-
LOG_DBG("ERR %d", data->current.is_err);
827-
data->current.is_err = 0U;
828-
}
829-
830-
if (is_timeout) {
831-
LOG_DBG("TIMEOUT");
832-
}
833-
834-
return -EIO;
816+
/* Wait for transfer to finish */
817+
return stm32_i2c_irq_msg_finish(dev, msg);
835818
}
836819

837820
#else /* !CONFIG_I2C_STM32_INTERRUPT */

0 commit comments

Comments
 (0)