@@ -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 )
258232static 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 ;
655629end :
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+
660695static 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