@@ -150,92 +150,80 @@ static int configure_dma(struct stream const *dma, struct dma_config *dma_cfg,
150
150
151
151
return 0 ;
152
152
}
153
- #endif /* CONFIG_I2C_STM32_V2_DMA */
154
153
155
- static inline void msg_init (const struct device * dev , struct i2c_msg * msg ,
156
- uint8_t * next_msg_flags , uint16_t slave ,
157
- uint32_t transfer )
154
+ static inline void dma_xfer_start (const struct device * dev , struct i2c_msg * msg )
158
155
{
159
156
const struct i2c_stm32_config * cfg = dev -> config ;
160
157
struct i2c_stm32_data * data = dev -> data ;
161
158
I2C_TypeDef * i2c = cfg -> i2c ;
162
159
163
- if (LL_I2C_IsEnabledReloadMode (i2c )) {
164
- LL_I2C_SetTransferSize (i2c , msg -> len );
160
+ if (msg -> flags & I2C_MSG_READ ) {
161
+ /* Configure RX DMA */
162
+ data -> dma_blk_cfg .source_address = LL_I2C_DMA_GetRegAddr (
163
+ cfg -> i2c , LL_I2C_DMA_REG_DATA_RECEIVE );
164
+ data -> dma_blk_cfg .source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE ;
165
+ data -> dma_blk_cfg .dest_address = (uint32_t )msg -> buf ;
166
+ data -> dma_blk_cfg .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
167
+ data -> dma_blk_cfg .block_size = msg -> len ;
168
+
169
+ if (configure_dma (& cfg -> rx_dma , & data -> dma_rx_cfg ,
170
+ & data -> dma_blk_cfg ) != 0 ) {
171
+ LOG_ERR ("Problem setting up RX DMA" );
172
+ return ;
173
+ }
174
+ data -> current .buf += msg -> len ;
175
+ data -> current .len -= msg -> len ;
176
+ LL_I2C_EnableDMAReq_RX (i2c );
165
177
} else {
166
- if (I2C_ADDR_10_BITS & data -> dev_config ) {
167
- LL_I2C_SetMasterAddressingMode (i2c ,
168
- LL_I2C_ADDRESSING_MODE_10BIT );
169
- LL_I2C_SetSlaveAddr (i2c , (uint32_t ) slave );
170
- } else {
171
- LL_I2C_SetMasterAddressingMode (i2c ,
172
- LL_I2C_ADDRESSING_MODE_7BIT );
173
- LL_I2C_SetSlaveAddr (i2c , (uint32_t ) slave << 1 );
178
+ if (data -> current .len ) {
179
+ /* Configure TX DMA */
180
+ data -> dma_blk_cfg .source_address =
181
+ (uint32_t )data -> current .buf ;
182
+ data -> dma_blk_cfg .source_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
183
+ data -> dma_blk_cfg .dest_address = LL_I2C_DMA_GetRegAddr (
184
+ cfg -> i2c , LL_I2C_DMA_REG_DATA_TRANSMIT );
185
+ data -> dma_blk_cfg .dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE ;
186
+ data -> dma_blk_cfg .block_size = msg -> len ;
187
+
188
+ if (configure_dma (& cfg -> tx_dma , & data -> dma_tx_cfg ,
189
+ & data -> dma_blk_cfg ) != 0 ) {
190
+ LOG_ERR ("Problem setting up TX DMA" );
191
+ return ;
192
+ }
193
+ data -> current .buf += data -> current .len ;
194
+ data -> current .len -= data -> current .len ;
195
+ LL_I2C_EnableDMAReq_TX (i2c );
174
196
}
197
+ }
175
198
176
- if (!(msg -> flags & I2C_MSG_STOP ) && next_msg_flags &&
177
- !(* next_msg_flags & I2C_MSG_RESTART )) {
178
- LL_I2C_EnableReloadMode (i2c );
179
- } else {
180
- LL_I2C_DisableReloadMode (i2c );
181
- }
182
- LL_I2C_DisableAutoEndMode (i2c );
183
- LL_I2C_SetTransferRequest (i2c , transfer );
184
- LL_I2C_SetTransferSize (i2c , msg -> len );
199
+ }
185
200
186
- #if defined(CONFIG_I2C_TARGET )
187
- data -> master_active = true;
188
- #endif
201
+ static inline void dma_finish (const struct device * dev , struct i2c_msg * msg )
202
+ {
203
+ const struct i2c_stm32_config * cfg = dev -> config ;
204
+ struct i2c_stm32_data * data = dev -> data ;
205
+ I2C_TypeDef * i2c = cfg -> i2c ;
189
206
190
- #ifdef CONFIG_I2C_STM32_V2_DMA
191
- if (msg -> len ) {
192
- if (msg -> flags & I2C_MSG_READ ) {
193
- /* Configure RX DMA */
194
- data -> dma_blk_cfg .source_address = LL_I2C_DMA_GetRegAddr (
195
- cfg -> i2c , LL_I2C_DMA_REG_DATA_RECEIVE );
196
- data -> dma_blk_cfg .source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE ;
197
- data -> dma_blk_cfg .dest_address = (uint32_t )msg -> buf ;
198
- data -> dma_blk_cfg .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
199
- data -> dma_blk_cfg .block_size = msg -> len ;
200
-
201
- if (configure_dma (& cfg -> rx_dma , & data -> dma_rx_cfg ,
202
- & data -> dma_blk_cfg ) != 0 ) {
203
- LOG_ERR ("Problem setting up RX DMA" );
204
- return ;
205
- }
206
- data -> current .buf += msg -> len ;
207
- data -> current .len -= msg -> len ;
208
- LL_I2C_EnableDMAReq_RX (i2c );
209
- } else {
210
- if (data -> current .len ) {
211
- /* Configure TX DMA */
212
- data -> dma_blk_cfg .source_address =
213
- (uint32_t )data -> current .buf ;
214
- data -> dma_blk_cfg .source_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
215
- data -> dma_blk_cfg .dest_address = LL_I2C_DMA_GetRegAddr (
216
- cfg -> i2c , LL_I2C_DMA_REG_DATA_TRANSMIT );
217
- data -> dma_blk_cfg .dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE ;
218
- data -> dma_blk_cfg .block_size = msg -> len ;
219
-
220
- if (configure_dma (& cfg -> tx_dma , & data -> dma_tx_cfg ,
221
- & data -> dma_blk_cfg ) != 0 ) {
222
- LOG_ERR ("Problem setting up TX DMA" );
223
- return ;
224
- }
225
- data -> current .buf += data -> current .len ;
226
- data -> current .len -= data -> current .len ;
227
- LL_I2C_EnableDMAReq_TX (i2c );
228
- }
229
- }
207
+ /* Stop the DMA */
208
+ if (data -> current .msg -> flags & I2C_MSG_READ ) {
209
+ dma_stop (cfg -> rx_dma .dev_dma , cfg -> rx_dma .dma_channel );
210
+ LL_I2C_DisableDMAReq_RX (i2c );
211
+ #if defined(CONFIG_DCACHE ) && defined(CONFIG_I2C_STM32_V2_DMA )
212
+ if (!buf_in_nocache ((uintptr_t )msg -> buf , msg -> len ) &&
213
+ ((msg -> flags & I2C_MSG_RW_MASK ) == I2C_MSG_READ )) {
214
+ LOG_DBG ("Rx buffer at %p (len %zu) is in cached memory; invalidating cache" ,
215
+ msg -> buf , msg -> len );
216
+ sys_cache_data_invd_range ((void * )msg -> buf , msg -> len );
230
217
}
231
- #endif /* CONFIG_I2C_STM32_V2_DMA */
232
-
233
- LL_I2C_Enable (i2c );
234
-
235
- LL_I2C_GenerateStartCondition (i2c );
218
+ #endif /* CONFIG_DCACHE && CONFIG_I2C_STM32_V2_DMA */
219
+ } else {
220
+ dma_stop (cfg -> tx_dma .dev_dma , cfg -> tx_dma .dma_channel );
221
+ LL_I2C_DisableDMAReq_TX (i2c );
236
222
}
237
223
}
238
224
225
+ #endif /* CONFIG_I2C_STM32_V2_DMA */
226
+
239
227
#ifdef CONFIG_I2C_STM32_INTERRUPT
240
228
241
229
static void i2c_stm32_disable_transfer_interrupts (const struct device * dev )
@@ -277,17 +265,6 @@ static void i2c_stm32_master_mode_end(const struct device *dev)
277
265
LL_I2C_Disable (i2c );
278
266
}
279
267
#endif
280
-
281
- #ifdef CONFIG_I2C_STM32_V2_DMA
282
- if (data -> current .msg -> flags & I2C_MSG_READ ) {
283
- dma_stop (cfg -> rx_dma .dev_dma , cfg -> rx_dma .dma_channel );
284
- LL_I2C_DisableDMAReq_RX (i2c );
285
- } else {
286
- dma_stop (cfg -> tx_dma .dev_dma , cfg -> tx_dma .dma_channel );
287
- LL_I2C_DisableDMAReq_TX (i2c );
288
- }
289
- #endif /* CONFIG_I2C_STM32_V2_DMA */
290
-
291
268
k_sem_give (& data -> device_sync_sem );
292
269
}
293
270
@@ -826,6 +803,7 @@ static int stm32_i2c_irq_xfer(const struct device *dev, struct i2c_msg *msg,
826
803
LL_I2C_WriteReg (regs , CR2 , cr2 );
827
804
828
805
uint32_t cr1 = LL_I2C_ReadReg (regs , CR1 );
806
+
829
807
/* Set common interrupt enable bits */
830
808
cr1 |= I2C_CR1_ERRIE | I2C_CR1_STOPIE | I2C_CR1_TCIE | I2C_CR1_NACKIE ;
831
809
@@ -845,6 +823,11 @@ static int stm32_i2c_irq_xfer(const struct device *dev, struct i2c_msg *msg,
845
823
if (k_sem_take (& data -> device_sync_sem , K_MSEC (msg -> len + 10 )) != 0 ) {
846
824
is_timeout = true;
847
825
}
826
+
827
+ #ifdef CONFIG_I2C_STM32_V2_DMA
828
+ /* Stop DMA and invalidate cache if needed */
829
+ dma_finish (dev , msg );
830
+ #endif
848
831
/* Check for transfer errors or timeout */
849
832
if (data -> current .is_nack || data -> current .is_arlo || is_timeout ) {
850
833
LL_I2C_Disable (regs );
@@ -864,14 +847,6 @@ static int stm32_i2c_irq_xfer(const struct device *dev, struct i2c_msg *msg,
864
847
}
865
848
#endif
866
849
}
867
- #if defined(CONFIG_DCACHE ) && defined(CONFIG_I2C_STM32_V2_DMA )
868
- if (!buf_in_nocache ((uintptr_t )msg -> buf , msg -> len ) &&
869
- ((msg -> flags & I2C_MSG_RW_MASK ) == I2C_MSG_READ )) {
870
- LOG_DBG ("Rx buffer at %p (len %zu) is in cached memory; invalidating cache" ,
871
- msg -> buf , msg -> len );
872
- sys_cache_data_invd_range ((void * )msg -> buf , msg -> len );
873
- }
874
- #endif /* CONFIG_DCACHE && CONFIG_I2C_STM32_V2_DMA */
875
850
return 0 ;
876
851
error :
877
852
if (data -> current .is_arlo ) {
@@ -934,6 +909,46 @@ static inline int check_errors(const struct device *dev, const char *funcname)
934
909
return - EIO ;
935
910
}
936
911
912
+ static inline void msg_init (const struct device * dev , struct i2c_msg * msg ,
913
+ uint8_t * next_msg_flags , uint16_t slave ,
914
+ uint32_t transfer )
915
+ {
916
+ const struct i2c_stm32_config * cfg = dev -> config ;
917
+ struct i2c_stm32_data * data = dev -> data ;
918
+ I2C_TypeDef * i2c = cfg -> i2c ;
919
+
920
+ if (LL_I2C_IsEnabledReloadMode (i2c )) {
921
+ LL_I2C_SetTransferSize (i2c , msg -> len );
922
+ } else {
923
+ if (I2C_ADDR_10_BITS & data -> dev_config ) {
924
+ LL_I2C_SetMasterAddressingMode (i2c ,
925
+ LL_I2C_ADDRESSING_MODE_10BIT );
926
+ LL_I2C_SetSlaveAddr (i2c , (uint32_t ) slave );
927
+ } else {
928
+ LL_I2C_SetMasterAddressingMode (i2c ,
929
+ LL_I2C_ADDRESSING_MODE_7BIT );
930
+ LL_I2C_SetSlaveAddr (i2c , (uint32_t ) slave << 1 );
931
+ }
932
+
933
+ if (!(msg -> flags & I2C_MSG_STOP ) && next_msg_flags &&
934
+ !(* next_msg_flags & I2C_MSG_RESTART )) {
935
+ LL_I2C_EnableReloadMode (i2c );
936
+ } else {
937
+ LL_I2C_DisableReloadMode (i2c );
938
+ }
939
+ LL_I2C_DisableAutoEndMode (i2c );
940
+ LL_I2C_SetTransferRequest (i2c , transfer );
941
+ LL_I2C_SetTransferSize (i2c , msg -> len );
942
+
943
+ #if defined(CONFIG_I2C_TARGET )
944
+ data -> master_active = true;
945
+ #endif
946
+ LL_I2C_Enable (i2c );
947
+
948
+ LL_I2C_GenerateStartCondition (i2c );
949
+ }
950
+ }
951
+
937
952
static inline int msg_done (const struct device * dev ,
938
953
unsigned int current_msg_flags )
939
954
{
0 commit comments