Revision 732a4657

View differences:

kernel/ChibiOS
1
Subproject commit 5b8695ccbd8388b7ac880d57fb1fdbc9a0d4c6ca
1
Subproject commit 14eea36396e50de3f4f54a53862b130162449821
kernel/patches/I2C-without-DMA.patch
1 1
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
2
index 6ade226..96c9da0 100644
3 2
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
4 3
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
5 4
@@ -34,6 +34,7 @@
6
 /* Driver local definitions.                                                 */

7
 /*===========================================================================*/

8
 
9
+#if STM32_I2C_I2C1_USE_DMA

10
 #define I2C1_RX_DMA_CHANNEL                                                 \

11
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM,                        \

12
                        STM32_I2C1_RX_DMA_CHN)

5
 /* Driver local definitions.                                                 */
6
 /*===========================================================================*/
7
 
8
+#if STM32_I2C_I2C1_USE_DMA
9
 #define I2C1_RX_DMA_CHANNEL                                                 \
10
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM,                        \
11
                        STM32_I2C1_RX_DMA_CHN)
13 12
@@ -41,7 +42,9 @@
14
 #define I2C1_TX_DMA_CHANNEL                                                 \

15
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM,                        \

16
                        STM32_I2C1_TX_DMA_CHN)

17
+#endif

18
 
19
+#if STM32_I2C_I2C2_USE_DMA

20
 #define I2C2_RX_DMA_CHANNEL                                                 \

21
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM,                        \

22
                        STM32_I2C2_RX_DMA_CHN)

13
 #define I2C1_TX_DMA_CHANNEL                                                 \
14
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM,                        \
15
                        STM32_I2C1_TX_DMA_CHN)
16
+#endif
17
 
18
+#if STM32_I2C_I2C2_USE_DMA
19
 #define I2C2_RX_DMA_CHANNEL                                                 \
20
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM,                        \
21
                        STM32_I2C2_RX_DMA_CHN)
23 22
@@ -49,7 +52,9 @@
24
 #define I2C2_TX_DMA_CHANNEL                                                 \

25
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM,                        \

26
                        STM32_I2C2_TX_DMA_CHN)

27
+#endif

28
 
29
+#if STM32_I2C_I2C3_USE_DMA

30
 #define I2C3_RX_DMA_CHANNEL                                                 \

31
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM,                        \

32
                        STM32_I2C3_RX_DMA_CHN)

23
 #define I2C2_TX_DMA_CHANNEL                                                 \
24
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM,                        \
25
                        STM32_I2C2_TX_DMA_CHN)
26
+#endif
27
 
28
+#if STM32_I2C_I2C3_USE_DMA
29
 #define I2C3_RX_DMA_CHANNEL                                                 \
30
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM,                        \
31
                        STM32_I2C3_RX_DMA_CHN)
33 32
@@ -57,6 +62,7 @@
34
 #define I2C3_TX_DMA_CHANNEL                                                 \

35
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM,                        \

36
                        STM32_I2C3_TX_DMA_CHN)

37
+#endif

38
 
39
 /*===========================================================================*/

40
 /* Driver constants.                                                         */

33
 #define I2C3_TX_DMA_CHANNEL                                                 \
34
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM,                        \
35
                        STM32_I2C3_TX_DMA_CHN)
36
+#endif
37
 
38
 /*===========================================================================*/
39
 /* Driver constants.                                                         */
41 40
@@ -72,6 +78,20 @@
42
 #define I2C_EV6_MASTER_REC_MODE_SELECTED                                    \

43
   ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR))

44
 
45
+#define I2C_EV7_MASTER_REC_BYTE_RECEIVED                                    \

46
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_RXNE))

47
+

48
+#define I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP                               \

49
+  ((uint32_t)(I2C_SR1_RXNE))

50
+

51
+#define I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED                              \

52
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) |                         \

53
+              I2C_SR1_BTF | I2C_SR1_RXNE))

54
+

55
+#define I2C_EV8_MASTER_BYTE_TRANSMITTING                                    \

56
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA)<< 16) |           \

57
+              I2C_SR1_TXE))

58
+

59
 #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED                                   \

60
   ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) |          \

61
               I2C_SR1_BTF | I2C_SR1_TXE))

41
 #define I2C_EV6_MASTER_REC_MODE_SELECTED                                    \
42
   ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR))
43
 
44
+#define I2C_EV7_MASTER_REC_BYTE_RECEIVED                                    \
45
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_RXNE))
46
+
47
+#define I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP                               \
48
+  ((uint32_t)(I2C_SR1_RXNE))
49
+
50
+#define I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED                              \
51
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) |                         \
52
+              I2C_SR1_BTF | I2C_SR1_RXNE))
53
+
54
+#define I2C_EV8_MASTER_BYTE_TRANSMITTING                                    \
55
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA)<< 16) |           \
56
+              I2C_SR1_TXE))
57
+
58
 #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED                                   \
59
   ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) |          \
60
               I2C_SR1_BTF | I2C_SR1_TXE))
62 61
@@ -129,8 +149,24 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
63
   dp->SR1 = 0;
64
 
65
   /* Stops the associated DMA streams.*/
66
-  dmaStreamDisable(i2cp->dmatx);
67
-  dmaStreamDisable(i2cp->dmarx);
68
+#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
69
+  if (&I2CD1 == i2cp) {
70
+    dmaStreamDisable(i2cp->dmatx);
71
+    dmaStreamDisable(i2cp->dmarx);
72
+  }
73
+#endif
74
+#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
75
+  if (&I2CD2 == i2cp) {
76
+    dmaStreamDisable(i2cp->dmatx);
77
+    dmaStreamDisable(i2cp->dmarx);
78
+  }
79
+#endif
80
+#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
81
+  if (&I2CD3 == i2cp) {
82
+    dmaStreamDisable(i2cp->dmatx);
83
+    dmaStreamDisable(i2cp->dmarx);
84
+  }
85
+#endif
86
 }
87
 
88
 /**
89
@@ -236,13 +272,17 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) {
90
 }
91
 
92
 /**
93
- * @brief   I2C shared ISR code.
94
+ * @brief   I2C shared ISR code for DMA access.
95
  *
96
  * @param[in] i2cp      pointer to the @p I2CDriver object
97
  *
98
  * @notapi
99
  */
100
-static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
101
+#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) ||                       \
102
+    (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) ||                       \
103
+    (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) ||                       \
104
+    defined(__DOXYGEN__)
105
+static void i2c_lld_serve_event_interrupt_dma(I2CDriver *i2cp) {
106
   I2C_TypeDef *dp = i2cp->i2c;
107
   uint32_t regSR2 = dp->SR2;
108
   uint32_t event = dp->SR1;
62
   dp->SR1 = 0;
63
 
64
   /* Stops the associated DMA streams.*/
65
-  dmaStreamDisable(i2cp->dmatx);
66
-  dmaStreamDisable(i2cp->dmarx);
67
+#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
68
+  if (&I2CD1 == i2cp) {
69
+    dmaStreamDisable(i2cp->dmatx);
70
+    dmaStreamDisable(i2cp->dmarx);
71
+  }
72
+#endif
73
+#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
74
+  if (&I2CD2 == i2cp) {
75
+    dmaStreamDisable(i2cp->dmatx);
76
+    dmaStreamDisable(i2cp->dmarx);
77
+  }
78
+#endif
79
+#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
80
+  if (&I2CD3 == i2cp) {
81
+    dmaStreamDisable(i2cp->dmatx);
82
+    dmaStreamDisable(i2cp->dmarx);
83
+  }
84
+#endif
85
 }
86
 
87
 /**
88
@@ -235,14 +271,18 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) {
89
   dp->CR1 = regCR1;
90
 }
91
 
92
+#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) ||                       \
93
+    (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) ||                       \
94
+    (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) ||                       \
95
+    defined(__DOXYGEN__)
96
 /**
97
- * @brief   I2C shared ISR code.
98
+ * @brief   I2C shared ISR code for DMA access.
99
  *
100
  * @param[in] i2cp      pointer to the @p I2CDriver object
101
  *
102
  * @notapi
103
  */
104
-static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
105
+static void i2c_lld_serve_event_interrupt_dma(I2CDriver *i2cp) {
106
   I2C_TypeDef *dp = i2cp->i2c;
107
   uint32_t regSR2 = dp->SR2;
108
   uint32_t event = dp->SR1;
109 109
@@ -252,7 +292,7 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
110
      done by the DMA.*/
111
   switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
112
   case I2C_EV5_MASTER_MODE_SELECT:
113
-    if ((i2cp->addr >> 8) > 0) { 
114
+    if ((i2cp->addr >> 8) > 0) {
115
       /* 10-bit address: 1 1 1 1 0 X X R/W */
116
       dp->DR = 0xF0 | (0x6 & (i2cp->addr >> 8)) | (0x1 & i2cp->addr);
117
     } else {
118
@@ -293,6 +333,140 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
119
   if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
120
     (void)dp->SR2;
121
 }
122
+#endif /* any I2CDx uses DMA mode */
123
+
124
+/**
125
+ * @brief   I2C shared ISR code for non-DMA access.
126
+ *
127
+ * @param[in] i2cp      pointer to the @p I2CDriver object
128
+ *
129
+ * @notapi
130
+ */
131
+#if (STM32_I2C_USE_I2C1 && !STM32_I2C_I2C1_USE_DMA) ||                      \
132
+    (STM32_I2C_USE_I2C2 && !STM32_I2C_I2C2_USE_DMA) ||                      \
133
+    (STM32_I2C_USE_I2C3 && !STM32_I2C_I2C3_USE_DMA) ||                      \
134
+    defined(__DOXYGEN__)
135
+static void i2c_lld_serve_event_interrupt_isr(I2CDriver *i2cp) {
136
+  I2C_TypeDef *dp = i2cp->i2c;
137
+  uint32_t regSR2 = dp->SR2;
138
+  uint32_t event = dp->SR1;
139
+
140
+  switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
141
+  case I2C_EV5_MASTER_MODE_SELECT:
142
+    dp->CR2 |= I2C_CR2_ITBUFEN;
143
+    dp->DR = i2cp->addr;
144
+    break;
145
+  case I2C_EV6_MASTER_TRA_MODE_SELECTED:
146
+    (void)dp->SR2; // clear ADDR flag
147
+    /* EV8_1 */
148
+    dp->DR = *(i2cp->txbuf);
149
+
150
+    ++i2cp->txbuf;
151
+    --i2cp->txbytes;
152
+
153
+    /* if N == 1, skip the I2C_EV8_MASTER_BYTE_TRANSMITTING event
154
+     * but enter I2C_EV8_2_MASTER_BYTE_TRANSMITTED next */
155
+    if (i2cp->txbytes == 0) {
156
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
157
+    }
158
+    break;
159
+  case I2C_EV6_MASTER_REC_MODE_SELECTED:
160
+    switch (i2cp->rxbytes) {
161
+    case 1:
162
+      dp->CR1 &= ~I2C_CR1_ACK;
163
+      (void)dp->SR2; // clear ADDR flag
164
+      dp->CR1 |= I2C_CR1_STOP;
165
+      break;
166
+    case 2:
167
+      (void)dp->SR2; // clear ADDR flag
168
+      /* EV6_1 */
169
+      dp->CR1 |= I2C_CR1_POS;
170
+      dp->CR1 &= ~I2C_CR1_ACK;
171
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
172
+      break;
173
+    case 3: /* N == 3 is a very special case, since EV7 is completely skipped */
174
+      (void)dp->SR2; // clear ADDR flag
175
+      /* Disable the I2C_EV7_MASTER_REC_BYTE_RECEIVED event
176
+       * but enter I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP next */
177
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
178
+      break;
179
+    default: /* N > 2 */
180
+      (void)dp->SR2; // clear ADDR flag
181
+      break;
182
+    }
183
+    break;
184
+  case I2C_EV7_MASTER_REC_BYTE_RECEIVED:
185
+    if (i2cp->rxbytes > 3) {
186
+      *(i2cp->rxbuf) = dp->DR;
187
+      ++i2cp->rxbuf;
188
+      --i2cp->rxbytes;
189
+    }
190
+    if (i2cp->rxbytes == 3) {
191
+      /* Disable this event for DataN-2, but force into event
192
+       * I2C_EV7_2_EV7_3_MASTER_REC_BYTE_RECEIVED_QUEUED by not reading dp->DR. */
193
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
194
+    }
195
+    break;
196
+  case I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP:
197
+    osalDbgAssert(i2cp->rxbytes == 1, "more than 1 byte to be received");
198
+    *(i2cp->rxbuf) = dp->DR;
199
+    --i2cp->rxbytes;
200
+    dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
201
+    _i2c_wakeup_isr(i2cp);
202
+    break;
203
+  case I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED:
204
+    if (i2cp->rxbytes == 3) {
205
+      /* EV7_2 (N > 2) */
206
+      dp->CR1 &= ~I2C_CR1_ACK;
207
+      *(i2cp->rxbuf) = dp->DR;
208
+      ++i2cp->rxbuf;
209
+      dp->CR1 |= I2C_CR1_STOP;
210
+      *(i2cp->rxbuf) = dp->DR;
211
+      ++i2cp->rxbuf;
212
+      i2cp->rxbytes -= 2;
213
+      /* enable I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP event */
214
+      dp->CR2 |= I2C_CR2_ITBUFEN;
215
+    } else {
216
+      /* EV7_3 (N == 2) */
217
+      dp->CR1 |= I2C_CR1_STOP;
218
+      *(i2cp->rxbuf) = dp->DR;
219
+      ++i2cp->rxbuf;
220
+      *(i2cp->rxbuf) = dp->DR;
221
+      i2cp->rxbytes -= 2;
222
+
223
+      dp->CR1 &= ~I2C_CR1_POS;
224
+      dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
225
+
226
+      _i2c_wakeup_isr(i2cp);
227
+    }
228
+    break;
229
+  case I2C_EV8_MASTER_BYTE_TRANSMITTING:
230
+    dp->DR = *(i2cp->txbuf);
231
+    ++i2cp->txbuf;
232
+    --i2cp->txbytes;
233
+
234
+    /* if this was the last byte, ensure that this event is not entered again */
235
+    if (i2cp->txbytes == 0) {
236
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
237
+    }
238
+    break;
239
+  case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
240
+    if (i2cp->rxbytes > 0) {
241
+      /* start "read after write" operation (LSB of address = 1 => read) */
242
+      i2cp->addr |= 0x01;
243
+      dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
244
+    } else {
245
+      dp->CR1 |= I2C_CR1_STOP;
246
+      dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
247
+      _i2c_wakeup_isr(i2cp);
248
+    }
249
+    break;
250
+  default:
251
+    osalDbgAssert(i2cp->rxbytes != 1, "more than 1 byte to be received");
252
+    break;
253
+  }
254
+}
255
+#endif /* any I2CDx uses non-DMA mode */
256
 
257
 /**
258
  * @brief   DMA RX end IRQ handler.
259
@@ -302,6 +476,10 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
260
  *
261
  * @notapi
262
  */
263
+#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) ||                      \
264
+    (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) ||                      \
265
+    (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) ||                      \
266
+    defined(__DOXYGEN__)
267
 static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags) {
268
   I2C_TypeDef *dp = i2cp->i2c;
269
 
270
@@ -347,6 +525,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
271
      of R/W transaction itself.*/
272
   dp->CR2 |= I2C_CR2_ITEVTEN;
273
 }
274
+#endif /* any I2CDx uses DMA mode */
275
 
276
 /**
277
  * @brief   I2C error handler.
278
@@ -359,8 +538,24 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
279
 static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) {
280
 
281
   /* Clears interrupt flags just to be safe.*/
282
-  dmaStreamDisable(i2cp->dmatx);
283
-  dmaStreamDisable(i2cp->dmarx);
284
+#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
285
+  if (&I2CD1 == i2cp) {
286
+    dmaStreamDisable(i2cp->dmatx);
287
+    dmaStreamDisable(i2cp->dmarx);
288
+  }
289
+#endif
290
+#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
291
+  if (&I2CD2 == i2cp) {
292
+    dmaStreamDisable(i2cp->dmatx);
293
+    dmaStreamDisable(i2cp->dmarx);
294
+  }
295
+#endif
296
+#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
297
+  if (&I2CD3 == i2cp) {
298
+    dmaStreamDisable(i2cp->dmatx);
299
+    dmaStreamDisable(i2cp->dmarx);
300
+  }
301
+#endif
302
 
303
   i2cp->errors = I2C_NO_ERROR;
304
 
305
@@ -407,7 +602,11 @@ OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
306
 
307
   OSAL_IRQ_PROLOGUE();
308
 
309
-  i2c_lld_serve_event_interrupt(&I2CD1);
310
+#if STM32_I2C_I2C1_USE_DMA
311
+  i2c_lld_serve_event_interrupt_dma(&I2CD1);
312
+#else
313
+  i2c_lld_serve_event_interrupt_isr(&I2CD1);
314
+#endif
315
 
316
   OSAL_IRQ_EPILOGUE();
317
 }
318
@@ -437,7 +636,11 @@ OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
319
 
320
   OSAL_IRQ_PROLOGUE();
321
 
322
-  i2c_lld_serve_event_interrupt(&I2CD2);
323
+#if STM32_I2C_I2C2_USE_DMA
324
+  i2c_lld_serve_event_interrupt_dma(&I2CD2);
325
+#else
326
+  i2c_lld_serve_event_interrupt_isr(&I2CD2);
327
+#endif
328
 
329
   OSAL_IRQ_EPILOGUE();
330
 }
331
@@ -469,7 +672,11 @@ OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
332
 
333
   OSAL_IRQ_PROLOGUE();
334
 
335
-  i2c_lld_serve_event_interrupt(&I2CD3);
336
+#if STM32_I2C_I2C3_USE_DMA
337
+  i2c_lld_serve_event_interrupt_dma(&I2CD3);
338
+#else
339
+  i2c_lld_serve_event_interrupt_isr(&I2CD3);
340
+#endif
341
 
342
   OSAL_IRQ_EPILOGUE();
343
 }
344
@@ -506,24 +713,30 @@ void i2c_lld_init(void) {
345
   i2cObjectInit(&I2CD1);
346
   I2CD1.thread = NULL;
347
   I2CD1.i2c    = I2C1;
348
+#if STM32_I2C_I2C1_USE_DMA
349
   I2CD1.dmarx  = STM32_DMA_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM);
350
   I2CD1.dmatx  = STM32_DMA_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM);
351
+#endif
352
 #endif /* STM32_I2C_USE_I2C1 */
353
 
354
 #if STM32_I2C_USE_I2C2
355
   i2cObjectInit(&I2CD2);
356
   I2CD2.thread = NULL;
357
   I2CD2.i2c    = I2C2;
358
+#if STM32_I2C_I2C2_USE_DMA
359
   I2CD2.dmarx  = STM32_DMA_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM);
360
   I2CD2.dmatx  = STM32_DMA_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM);
361
+#endif
362
 #endif /* STM32_I2C_USE_I2C2 */
363
 
364
 #if STM32_I2C_USE_I2C3
365
   i2cObjectInit(&I2CD3);
366
   I2CD3.thread = NULL;
367
   I2CD3.i2c    = I2C3;
368
+#if STM32_I2C_I2C3_USE_DMA
369
   I2CD3.dmarx  = STM32_DMA_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM);
370
   I2CD3.dmatx  = STM32_DMA_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM);
371
+#endif
372
 #endif /* STM32_I2C_USE_I2C3 */
373
 }
374
 
375
@@ -540,20 +753,24 @@ void i2c_lld_start(I2CDriver *i2cp) {
376
   /* If in stopped state then enables the I2C and DMA clocks.*/
377
   if (i2cp->state == I2C_STOP) {
378
 
379
-    i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
380
-                      STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
381
-                      STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
382
-                      STM32_DMA_CR_DIR_M2P;
383
-    i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
384
-                      STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
385
-                      STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
386
-                      STM32_DMA_CR_DIR_P2M;
387
-
388
 #if STM32_I2C_USE_I2C1
389
     if (&I2CD1 == i2cp) {
390
+#if STM32_I2C_I2C1_USE_DMA
391
       bool b;
392
 
393
+      i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
394
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
395
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
396
+                        STM32_DMA_CR_DIR_M2P;
397
+      i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
398
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
399
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
400
+                        STM32_DMA_CR_DIR_P2M;
401
+#endif
402
+
403
       rccResetI2C1();
404
+
405
+#if STM32_I2C_I2C1_USE_DMA
406
       b = dmaStreamAllocate(i2cp->dmarx,
407
                             STM32_I2C_I2C1_IRQ_PRIORITY,
408
                             (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
409
@@ -564,22 +781,52 @@ void i2c_lld_start(I2CDriver *i2cp) {
410
                             (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
411
                             (void *)i2cp);
412
       osalDbgAssert(!b, "stream already allocated");
413
+#endif
414
+
415
       rccEnableI2C1(true);
416
       nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
417
       nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
418
 
419
+#if STM32_I2C_I2C1_USE_DMA
420
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
421
                        STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
422
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
423
                        STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
424
+
425
+      /* I2C registers pointed by the DMA.*/
426
+      dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
427
+      dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
428
+#endif
429
+
430
+      /* Reset i2c peripheral.*/
431
+      dp->CR1 = I2C_CR1_SWRST;
432
+      dp->CR1 = 0;
433
+#if STM32_I2C_I2C1_USE_DMA
434
+      dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
435
+#else
436
+      dp->CR2 = I2C_CR2_ITERREN;
437
+#endif
438
     }
439
 #endif /* STM32_I2C_USE_I2C1 */
440
 
441
 #if STM32_I2C_USE_I2C2
442
     if (&I2CD2 == i2cp) {
443
+#if STM32_I2C_I2C2_USE_DMA
444
       bool b;
445
 
446
+      i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
447
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
448
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
449
+                        STM32_DMA_CR_DIR_M2P;
450
+      i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
451
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
452
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
453
+                        STM32_DMA_CR_DIR_P2M;
454
+#endif
455
+
456
       rccResetI2C2();
457
+
458
+#if STM32_I2C_I2C2_USE_DMA
459
       b = dmaStreamAllocate(i2cp->dmarx,
460
                             STM32_I2C_I2C2_IRQ_PRIORITY,
461
                             (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
462
@@ -590,22 +837,52 @@ void i2c_lld_start(I2CDriver *i2cp) {
463
                             (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
464
                             (void *)i2cp);
465
       osalDbgAssert(!b, "stream already allocated");
466
+#endif
467
+
468
       rccEnableI2C2(true);
469
       nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
470
       nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
471
 
472
+#if STM32_I2C_I2C2_USE_DMA
473
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
474
                        STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
475
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
476
                        STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
477
+
478
+      /* I2C registers pointed by the DMA.*/
479
+      dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
480
+      dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
481
+#endif
482
+
483
+      /* Reset i2c peripheral.*/
484
+      dp->CR1 = I2C_CR1_SWRST;
485
+      dp->CR1 = 0;
486
+#if STM32_I2C_I2C2_USE_DMA
487
+      dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
488
+#else
489
+      dp->CR2 = I2C_CR2_ITERREN;
490
+#endif
491
     }
492
 #endif /* STM32_I2C_USE_I2C2 */
493
 
494
 #if STM32_I2C_USE_I2C3
495
     if (&I2CD3 == i2cp) {
496
+#if STM32_I2C_I2C3_USE_DMA
497
       bool b;
498
 
499
+      i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
500
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
501
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
502
+                        STM32_DMA_CR_DIR_M2P;
503
+      i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
504
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
505
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
506
+                        STM32_DMA_CR_DIR_P2M;
507
+#endif
508
+
509
       rccResetI2C3();
510
+
511
+#if STM32_I2C_I2C3_USE_DMA
512
       b = dmaStreamAllocate(i2cp->dmarx,
513
                             STM32_I2C_I2C3_IRQ_PRIORITY,
514
                             (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
515
@@ -616,27 +893,35 @@ void i2c_lld_start(I2CDriver *i2cp) {
516
                             (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
517
                             (void *)i2cp);
518
       osalDbgAssert(!b, "stream already allocated");
519
+#endif
520
+
521
       rccEnableI2C3(true);
522
       nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
523
       nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
524
 
525
+#if STM32_I2C_I2C3_USE_DMA
526
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
527
                        STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
528
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
529
                        STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
530
+
531
+      /* I2C registers pointed by the DMA.*/
532
+      dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
533
+      dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
534
+#endif
535
+
536
+      /* Reset i2c peripheral.*/
537
+      dp->CR1 = I2C_CR1_SWRST;
538
+      dp->CR1 = 0;
539
+#if STM32_I2C_I2C3_USE_DMA
540
+      dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
541
+#else
542
+      dp->CR2 = I2C_CR2_ITERREN;
543
+#endif
544
     }
545
 #endif /* STM32_I2C_USE_I2C3 */
546
   }
547
 
548
-  /* I2C registers pointed by the DMA.*/
549
-  dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
550
-  dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
551
-
552
-  /* Reset i2c peripheral.*/
553
-  dp->CR1 = I2C_CR1_SWRST;
554
-  dp->CR1 = 0;
555
-  dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
556
-
557
   /* Setup I2C parameters.*/
558
   i2c_lld_set_clock(i2cp);
559
   i2c_lld_set_opmode(i2cp);
560
@@ -659,11 +944,13 @@ void i2c_lld_stop(I2CDriver *i2cp) {
561
 
562
     /* I2C disable.*/
563
     i2c_lld_abort_operation(i2cp);
564
-    dmaStreamRelease(i2cp->dmatx);
565
-    dmaStreamRelease(i2cp->dmarx);
566
 
567
 #if STM32_I2C_USE_I2C1
568
     if (&I2CD1 == i2cp) {
569
+#if STM32_I2C_I2C1_USE_DMA
570
+      dmaStreamRelease(i2cp->dmatx);
571
+      dmaStreamRelease(i2cp->dmarx);
572
+ #endif
573
       nvicDisableVector(I2C1_EV_IRQn);
574
       nvicDisableVector(I2C1_ER_IRQn);
575
       rccDisableI2C1();
576
@@ -672,6 +959,10 @@ void i2c_lld_stop(I2CDriver *i2cp) {
577
 
578
 #if STM32_I2C_USE_I2C2
579
     if (&I2CD2 == i2cp) {
580
+#if STM32_I2C_I2C2_USE_DMA
581
+      dmaStreamRelease(i2cp->dmatx);
582
+      dmaStreamRelease(i2cp->dmarx);
583
+ #endif
584
       nvicDisableVector(I2C2_EV_IRQn);
585
       nvicDisableVector(I2C2_ER_IRQn);
586
       rccDisableI2C2();
587
@@ -680,6 +971,10 @@ void i2c_lld_stop(I2CDriver *i2cp) {
588
 
589
 #if STM32_I2C_USE_I2C3
590
     if (&I2CD3 == i2cp) {
591
+#if STM32_I2C_I2C3_USE_DMA
592
+      dmaStreamRelease(i2cp->dmatx);
593
+      dmaStreamRelease(i2cp->dmarx);
594
+ #endif
595
       nvicDisableVector(I2C3_EV_IRQn);
596
       nvicDisableVector(I2C3_ER_IRQn);
597
       rccDisableI2C3();
598
@@ -730,10 +1025,43 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
599
   /* Releases the lock from high level driver.*/
600
   osalSysUnlock();
601
 
602
-  /* RX DMA setup.*/
603
-  dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
604
-  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
605
-  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
606
+  /* RX (DMA) setup.*/
607
+#if STM32_I2C_USE_I2C1
608
+  if (&I2CD1 == i2cp) {
609
+#if STM32_I2C_I2C1_USE_DMA
610
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
611
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
612
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
613
+#else
614
+    i2cp->rxbuf = rxbuf;
615
+    i2cp->rxbytes = rxbytes;
616
+#endif
617
+  }
618
+#endif
619
+#if STM32_I2C_USE_I2C2
620
+  if (&I2CD2 == i2cp) {
621
+#if STM32_I2C_I2C2_USE_DMA
622
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
623
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
624
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
625
+#else
626
+    i2cp->rxbuf = rxbuf;
627
+    i2cp->rxbytes = rxbytes;
628
+#endif
629
+  }
630
+#endif
631
+#if STM32_I2C_USE_I2C3
632
+  if (&I2CD3 == i2cp) {
633
+#if STM32_I2C_I2C3_USE_DMA
634
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
635
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
636
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
637
+#else
638
+    i2cp->rxbuf = rxbuf;
639
+    i2cp->rxbytes = rxbytes;
640
+#endif
641
+  }
642
+#endif
643
 
644
   /* Calculating the time window for the timeout on the busy bus condition.*/
645
   start = osalOsGetSystemTimeX();
646
@@ -810,15 +1138,61 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
647
   /* Releases the lock from high level driver.*/
648
   osalSysUnlock();
649
 
650
-  /* TX DMA setup.*/
651
-  dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
652
-  dmaStreamSetMemory0(i2cp->dmatx, txbuf);
653
-  dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
654
-
655
-  /* RX DMA setup.*/
656
-  dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
657
-  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
658
-  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
659
+  /* TX (DMA) and RX (DMA) setup */
660
+#if STM32_I2C_USE_I2C1
661
+  if (&I2CD1 == i2cp) {
662
+#if STM32_I2C_I2C1_USE_DMA
663
+    dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
664
+    dmaStreamSetMemory0(i2cp->dmatx, txbuf);
665
+    dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
666
+
667
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
668
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
669
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
670
+#else
671
+    i2cp->txbuf = txbuf;
672
+    i2cp->txbytes = txbytes;
673
+    i2cp->rxbuf = rxbuf;
674
+    i2cp->rxbytes = rxbytes;
675
+#endif
676
+  }
677
+#endif
678
+#if STM32_I2C_USE_I2C2
679
+  if (&I2CD2 == i2cp) {
680
+#if STM32_I2C_I2C2_USE_DMA
681
+    dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
682
+    dmaStreamSetMemory0(i2cp->dmatx, txbuf);
683
+    dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
684
+
685
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
686
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
687
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
688
+#else
689
+    i2cp->txbuf = txbuf;
690
+    i2cp->txbytes = txbytes;
691
+    i2cp->rxbuf = rxbuf;
692
+    i2cp->rxbytes = rxbytes;
693
+#endif
694
+  }
695
+#endif
696
+#if STM32_I2C_USE_I2C3
697
+  if (&I2CD3 == i2cp) {
698
+#if STM32_I2C_I2C3_USE_DMA
699
+    dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
700
+    dmaStreamSetMemory0(i2cp->dmatx, txbuf);
701
+    dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
702
+
703
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
704
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
705
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
706
+#else
707
+    i2cp->txbuf = txbuf;
708
+    i2cp->txbytes = txbytes;
709
+    i2cp->rxbuf = rxbuf;
710
+    i2cp->rxbytes = rxbytes;
711
+#endif
712
+  }
713
+#endif
714
 
715
   /* Calculating the time window for the timeout on the busy bus condition.*/
716
   start = osalOsGetSystemTimeX();
110
      done by the DMA.*/
111
   switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
112
   case I2C_EV5_MASTER_MODE_SELECT:
113
-    if ((i2cp->addr >> 8) > 0) { 
114
+    if ((i2cp->addr >> 8) > 0) {
115
       /* 10-bit address: 1 1 1 1 0 X X R/W */
116
       dp->DR = 0xF0 | (0x6 & (i2cp->addr >> 8)) | (0x1 & i2cp->addr);
117
     } else {
118
@@ -293,7 +333,146 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
119
   if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
120
     (void)dp->SR2;
121
 }
122
+#endif /* any I2CDx uses DMA mode */
123
+
124
+#if (STM32_I2C_USE_I2C1 && !STM32_I2C_I2C1_USE_DMA) ||                      \
125
+    (STM32_I2C_USE_I2C2 && !STM32_I2C_I2C2_USE_DMA) ||                      \
126
+    (STM32_I2C_USE_I2C3 && !STM32_I2C_I2C3_USE_DMA) ||                      \
127
+    defined(__DOXYGEN__)
128
+/**
129
+ * @brief   I2C shared ISR code for non-DMA access.
130
+ *
131
+ * @param[in] i2cp      pointer to the @p I2CDriver object
132
+ *
133
+ * @notapi
134
+ */
135
+static void i2c_lld_serve_event_interrupt_isr(I2CDriver *i2cp) {
136
+  I2C_TypeDef *dp = i2cp->i2c;
137
+  uint32_t regSR2 = dp->SR2;
138
+  uint32_t event = dp->SR1;
139
+
140
+  switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
141
+  case I2C_EV5_MASTER_MODE_SELECT:
142
+    dp->CR2 |= I2C_CR2_ITBUFEN;
143
+    dp->DR = i2cp->addr;
144
+    break;
145
+  case I2C_EV6_MASTER_TRA_MODE_SELECTED:
146
+    (void)dp->SR2; // clear ADDR flag
147
+    /* EV8_1 */
148
+    dp->DR = *(i2cp->txbuf);
149
+
150
+    ++i2cp->txbuf;
151
+    --i2cp->txbytes;
152
+
153
+    /* if N == 1, skip the I2C_EV8_MASTER_BYTE_TRANSMITTING event
154
+     * but enter I2C_EV8_2_MASTER_BYTE_TRANSMITTED next */
155
+    if (i2cp->txbytes == 0) {
156
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
157
+    }
158
+    break;
159
+  case I2C_EV6_MASTER_REC_MODE_SELECTED:
160
+    switch (i2cp->rxbytes) {
161
+    case 1:
162
+      dp->CR1 &= ~I2C_CR1_ACK;
163
+      (void)dp->SR2; // clear ADDR flag
164
+      dp->CR1 |= I2C_CR1_STOP;
165
+      break;
166
+    case 2:
167
+      (void)dp->SR2; // clear ADDR flag
168
+      /* EV6_1 */
169
+      dp->CR1 |= I2C_CR1_POS;
170
+      dp->CR1 &= ~I2C_CR1_ACK;
171
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
172
+      break;
173
+    case 3: /* N == 3 is a very special case, since EV7 is completely skipped */
174
+      (void)dp->SR2; // clear ADDR flag
175
+      /* Disable the I2C_EV7_MASTER_REC_BYTE_RECEIVED event
176
+       * but enter I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP next */
177
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
178
+      break;
179
+    default: /* N > 2 */
180
+      (void)dp->SR2; // clear ADDR flag
181
+      break;
182
+    }
183
+    break;
184
+  case I2C_EV7_MASTER_REC_BYTE_RECEIVED:
185
+    if (i2cp->rxbytes > 3) {
186
+      *(i2cp->rxbuf) = dp->DR;
187
+      ++i2cp->rxbuf;
188
+      --i2cp->rxbytes;
189
+    }
190
+    if (i2cp->rxbytes == 3) {
191
+      /* Disable this event for DataN-2, but force into event
192
+       * I2C_EV7_2_EV7_3_MASTER_REC_BYTE_RECEIVED_QUEUED by not reading dp->DR. */
193
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
194
+    }
195
+    break;
196
+  case I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP:
197
+    osalDbgAssert(i2cp->rxbytes == 1, "more than 1 byte to be received");
198
+    *(i2cp->rxbuf) = dp->DR;
199
+    --i2cp->rxbytes;
200
+    dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
201
+    _i2c_wakeup_isr(i2cp);
202
+    break;
203
+  case I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED:
204
+    if (i2cp->rxbytes == 3) {
205
+      /* EV7_2 (N > 2) */
206
+      dp->CR1 &= ~I2C_CR1_ACK;
207
+      *(i2cp->rxbuf) = dp->DR;
208
+      ++i2cp->rxbuf;
209
+      dp->CR1 |= I2C_CR1_STOP;
210
+      *(i2cp->rxbuf) = dp->DR;
211
+      ++i2cp->rxbuf;
212
+      i2cp->rxbytes -= 2;
213
+      /* enable I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP event */
214
+      dp->CR2 |= I2C_CR2_ITBUFEN;
215
+    } else {
216
+      /* EV7_3 (N == 2) */
217
+      dp->CR1 |= I2C_CR1_STOP;
218
+      *(i2cp->rxbuf) = dp->DR;
219
+      ++i2cp->rxbuf;
220
+      *(i2cp->rxbuf) = dp->DR;
221
+      i2cp->rxbytes -= 2;
222
+
223
+      dp->CR1 &= ~I2C_CR1_POS;
224
+      dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
225
+
226
+      _i2c_wakeup_isr(i2cp);
227
+    }
228
+    break;
229
+  case I2C_EV8_MASTER_BYTE_TRANSMITTING:
230
+    dp->DR = *(i2cp->txbuf);
231
+    ++i2cp->txbuf;
232
+    --i2cp->txbytes;
233
+
234
+    /* if this was the last byte, ensure that this event is not entered again */
235
+    if (i2cp->txbytes == 0) {
236
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
237
+    }
238
+    break;
239
+  case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
240
+    if (i2cp->rxbytes > 0) {
241
+      /* start "read after write" operation (LSB of address = 1 => read) */
242
+      i2cp->addr |= 0x01;
243
+      dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
244
+    } else {
245
+      dp->CR1 |= I2C_CR1_STOP;
246
+      dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
247
+      _i2c_wakeup_isr(i2cp);
248
+    }
249
+    break;
250
+  default:
251
+    osalDbgAssert(i2cp->rxbytes != 1, "more than 1 byte to be received");
252
+    break;
253
+  }
254
+}
255
+#endif /* any I2CDx uses non-DMA mode */
256
 
257
+
258
+#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) ||                      \
259
+    (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) ||                      \
260
+    (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) ||                      \
261
+    defined(__DOXYGEN__)
262
 /**
263
  * @brief   DMA RX end IRQ handler.
264
  *
265
@@ -347,6 +526,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
266
      of R/W transaction itself.*/
267
   dp->CR2 |= I2C_CR2_ITEVTEN;
268
 }
269
+#endif /* any I2CDx uses DMA mode */
270
 
271
 /**
272
  * @brief   I2C error handler.
273
@@ -359,8 +539,24 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
274
 static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) {
275
 
276
   /* Clears interrupt flags just to be safe.*/
277
-  dmaStreamDisable(i2cp->dmatx);
278
-  dmaStreamDisable(i2cp->dmarx);
279
+#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
280
+  if (&I2CD1 == i2cp) {
281
+    dmaStreamDisable(i2cp->dmatx);
282
+    dmaStreamDisable(i2cp->dmarx);
283
+  }
284
+#endif
285
+#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
286
+  if (&I2CD2 == i2cp) {
287
+    dmaStreamDisable(i2cp->dmatx);
288
+    dmaStreamDisable(i2cp->dmarx);
289
+  }
290
+#endif
291
+#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
292
+  if (&I2CD3 == i2cp) {
293
+    dmaStreamDisable(i2cp->dmatx);
294
+    dmaStreamDisable(i2cp->dmarx);
295
+  }
296
+#endif
297
 
298
   i2cp->errors = I2C_NO_ERROR;
299
 
300
@@ -407,7 +603,11 @@ OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
301
 
302
   OSAL_IRQ_PROLOGUE();
303
 
304
-  i2c_lld_serve_event_interrupt(&I2CD1);
305
+#if STM32_I2C_I2C1_USE_DMA
306
+  i2c_lld_serve_event_interrupt_dma(&I2CD1);
307
+#else
308
+  i2c_lld_serve_event_interrupt_isr(&I2CD1);
309
+#endif
310
 
311
   OSAL_IRQ_EPILOGUE();
312
 }
313
@@ -437,7 +637,11 @@ OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
314
 
315
   OSAL_IRQ_PROLOGUE();
316
 
317
-  i2c_lld_serve_event_interrupt(&I2CD2);
318
+#if STM32_I2C_I2C2_USE_DMA
319
+  i2c_lld_serve_event_interrupt_dma(&I2CD2);
320
+#else
321
+  i2c_lld_serve_event_interrupt_isr(&I2CD2);
322
+#endif
323
 
324
   OSAL_IRQ_EPILOGUE();
325
 }
326
@@ -469,7 +673,11 @@ OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
327
 
328
   OSAL_IRQ_PROLOGUE();
329
 
330
-  i2c_lld_serve_event_interrupt(&I2CD3);
331
+#if STM32_I2C_I2C3_USE_DMA
332
+  i2c_lld_serve_event_interrupt_dma(&I2CD3);
333
+#else
334
+  i2c_lld_serve_event_interrupt_isr(&I2CD3);
335
+#endif
336
 
337
   OSAL_IRQ_EPILOGUE();
338
 }
339
@@ -540,19 +748,22 @@ void i2c_lld_start(I2CDriver *i2cp) {
340
   /* If in stopped state then enables the I2C and DMA clocks.*/
341
   if (i2cp->state == I2C_STOP) {
342
 
343
-    i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
344
-                      STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
345
-                      STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
346
-                      STM32_DMA_CR_DIR_M2P;
347
-    i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
348
-                      STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
349
-                      STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
350
-                      STM32_DMA_CR_DIR_P2M;
351
-
352
 #if STM32_I2C_USE_I2C1
353
     if (&I2CD1 == i2cp) {
354
+#if STM32_I2C_I2C1_USE_DMA
355
+      i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
356
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
357
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
358
+                        STM32_DMA_CR_DIR_M2P;
359
+      i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
360
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
361
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
362
+                        STM32_DMA_CR_DIR_P2M;
363
+#endif
364
+
365
       rccResetI2C1();
366
 
367
+#if STM32_I2C_I2C1_USE_DMA
368
       i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
369
                                     STM32_I2C_I2C1_IRQ_PRIORITY,
370
                                     (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
371
@@ -563,22 +774,50 @@ void i2c_lld_start(I2CDriver *i2cp) {
372
                                     (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
373
                                     (void *)i2cp);
374
       osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
375
+#endif
376
 
377
       rccEnableI2C1(true);
378
       nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
379
       nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
380
 
381
+#if STM32_I2C_I2C1_USE_DMA
382
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
383
                        STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
384
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
385
                        STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
386
+
387
+      /* I2C registers pointed by the DMA.*/
388
+      dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
389
+      dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
390
+#endif
391
+
392
+      /* Reset i2c peripheral.*/
393
+      dp->CR1 = I2C_CR1_SWRST;
394
+      dp->CR1 = 0;
395
+#if STM32_I2C_I2C1_USE_DMA
396
+      dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
397
+#else
398
+      dp->CR2 = I2C_CR2_ITERREN;
399
+#endif
400
     }
401
 #endif /* STM32_I2C_USE_I2C1 */
402
 
403
 #if STM32_I2C_USE_I2C2
404
     if (&I2CD2 == i2cp) {
405
+#if STM32_I2C_I2C2_USE_DMA
406
+      i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
407
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
408
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
409
+                        STM32_DMA_CR_DIR_M2P;
410
+      i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
411
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
412
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
413
+                        STM32_DMA_CR_DIR_P2M;
414
+#endif
415
+
416
       rccResetI2C2();
417
 
418
+#if STM32_I2C_I2C2_USE_DMA
419
       i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
420
                                     STM32_I2C_I2C2_IRQ_PRIORITY,
421
                                     (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
422
@@ -589,22 +828,50 @@ void i2c_lld_start(I2CDriver *i2cp) {
423
                                     (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
424
                                     (void *)i2cp);
425
       osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
426
+#endif
427
 
428
       rccEnableI2C2(true);
429
       nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
430
       nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
431
 
432
+#if STM32_I2C_I2C2_USE_DMA
433
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
434
                        STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
435
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
436
                        STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
437
+
438
+      /* I2C registers pointed by the DMA.*/
439
+      dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
440
+      dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
441
+#endif
442
+
443
+      /* Reset i2c peripheral.*/
444
+      dp->CR1 = I2C_CR1_SWRST;
445
+      dp->CR1 = 0;
446
+#if STM32_I2C_I2C2_USE_DMA
447
+      dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
448
+#else
449
+      dp->CR2 = I2C_CR2_ITERREN;
450
+#endif
451
     }
452
 #endif /* STM32_I2C_USE_I2C2 */
453
 
454
 #if STM32_I2C_USE_I2C3
455
     if (&I2CD3 == i2cp) {
456
+#if STM32_I2C_I2C3_USE_DMA
457
+      i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
458
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
459
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
460
+                        STM32_DMA_CR_DIR_M2P;
461
+      i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
462
+                        STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
463
+                        STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
464
+                        STM32_DMA_CR_DIR_P2M;
465
+#endif
466
+
467
       rccResetI2C3();
468
 
469
+#if STM32_I2C_I2C3_USE_DMA
470
       i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
471
                                     STM32_I2C_I2C3_IRQ_PRIORITY,
472
                                     (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
473
@@ -615,28 +882,35 @@ void i2c_lld_start(I2CDriver *i2cp) {
474
                                     (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
475
                                     (void *)i2cp);
476
       osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
477
+#endif
478
 
479
       rccEnableI2C3(true);
480
       nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
481
       nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
482
 
483
+#if STM32_I2C_I2C3_USE_DMA
484
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
485
                        STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
486
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
487
                        STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
488
+
489
+      /* I2C registers pointed by the DMA.*/
490
+      dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
491
+      dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
492
+#endif
493
+
494
+      /* Reset i2c peripheral.*/
495
+      dp->CR1 = I2C_CR1_SWRST;
496
+      dp->CR1 = 0;
497
+#if STM32_I2C_I2C3_USE_DMA
498
+      dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
499
+#else
500
+      dp->CR2 = I2C_CR2_ITERREN;
501
+#endif
502
     }
503
 #endif /* STM32_I2C_USE_I2C3 */
504
   }
505
 
506
-  /* I2C registers pointed by the DMA.*/
507
-  dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
508
-  dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
509
-
510
-  /* Reset i2c peripheral.*/
511
-  dp->CR1 = I2C_CR1_SWRST;
512
-  dp->CR1 = 0;
513
-  dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
514
-
515
   /* Setup I2C parameters.*/
516
   i2c_lld_set_clock(i2cp);
517
   i2c_lld_set_opmode(i2cp);
518
@@ -659,13 +933,15 @@ void i2c_lld_stop(I2CDriver *i2cp) {
519
 
520
     /* I2C disable.*/
521
     i2c_lld_abort_operation(i2cp);
522
-    dmaStreamFreeI(i2cp->dmatx);
523
-    dmaStreamFreeI(i2cp->dmarx);
524
-    i2cp->dmatx = NULL;
525
-    i2cp->dmarx = NULL;
526
 
527
 #if STM32_I2C_USE_I2C1
528
     if (&I2CD1 == i2cp) {
529
+#if STM32_I2C_I2C1_USE_DMA
530
+      dmaStreamFreeI(i2cp->dmatx);
531
+      dmaStreamFreeI(i2cp->dmarx);
532
+      i2cp->dmatx = NULL;
533
+      i2cp->dmarx = NULL;
534
+#endif
535
       nvicDisableVector(I2C1_EV_IRQn);
536
       nvicDisableVector(I2C1_ER_IRQn);
537
       rccDisableI2C1();
538
@@ -674,6 +950,12 @@ void i2c_lld_stop(I2CDriver *i2cp) {
539
 
540
 #if STM32_I2C_USE_I2C2
541
     if (&I2CD2 == i2cp) {
542
+#if STM32_I2C_I2C2_USE_DMA
543
+      dmaStreamFreeI(i2cp->dmatx);
544
+      dmaStreamFreeI(i2cp->dmarx);
545
+      i2cp->dmatx = NULL;
546
+      i2cp->dmarx = NULL;
547
+#endif
548
       nvicDisableVector(I2C2_EV_IRQn);
549
       nvicDisableVector(I2C2_ER_IRQn);
550
       rccDisableI2C2();
551
@@ -682,6 +964,12 @@ void i2c_lld_stop(I2CDriver *i2cp) {
552
 
553
 #if STM32_I2C_USE_I2C3
554
     if (&I2CD3 == i2cp) {
555
+#if STM32_I2C_I2C3_USE_DMA
556
+      dmaStreamFreeI(i2cp->dmatx);
557
+      dmaStreamFreeI(i2cp->dmarx);
558
+      i2cp->dmatx = NULL;
559
+      i2cp->dmarx = NULL;
560
+#endif
561
       nvicDisableVector(I2C3_EV_IRQn);
562
       nvicDisableVector(I2C3_ER_IRQn);
563
       rccDisableI2C3();
564
@@ -732,10 +1020,43 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
565
   /* Releases the lock from high level driver.*/
566
   osalSysUnlock();
567
 
568
-  /* RX DMA setup.*/
569
-  dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
570
-  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
571
-  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
572
+  /* RX (DMA) setup.*/
573
+#if STM32_I2C_USE_I2C1
574
+  if (&I2CD1 == i2cp) {
575
+#if STM32_I2C_I2C1_USE_DMA
576
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
577
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
578
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
579
+#else
580
+    i2cp->rxbuf = rxbuf;
581
+    i2cp->rxbytes = rxbytes;
582
+#endif
583
+  }
584
+#endif
585
+#if STM32_I2C_USE_I2C2
586
+  if (&I2CD2 == i2cp) {
587
+#if STM32_I2C_I2C2_USE_DMA
588
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
589
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
590
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
591
+#else
592
+    i2cp->rxbuf = rxbuf;
593
+    i2cp->rxbytes = rxbytes;
594
+#endif
595
+  }
596
+#endif
597
+#if STM32_I2C_USE_I2C3
598
+  if (&I2CD3 == i2cp) {
599
+#if STM32_I2C_I2C3_USE_DMA
600
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
601
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
602
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
603
+#else
604
+    i2cp->rxbuf = rxbuf;
605
+    i2cp->rxbytes = rxbytes;
606
+#endif
607
+  }
608
+#endif
609
 
610
   /* Calculating the time window for the timeout on the busy bus condition.*/
611
   start = osalOsGetSystemTimeX();
612
@@ -812,15 +1133,61 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
613
   /* Releases the lock from high level driver.*/
614
   osalSysUnlock();
615
 
616
-  /* TX DMA setup.*/
617
-  dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
618
-  dmaStreamSetMemory0(i2cp->dmatx, txbuf);
619
-  dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
620
-
621
-  /* RX DMA setup.*/
622
-  dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
623
-  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
624
-  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
625
+  /* TX (DMA) and RX (DMA) setup.*/
626
+#if STM32_I2C_USE_I2C1
627
+  if (&I2CD1 == i2cp) {
628
+#if STM32_I2C_I2C1_USE_DMA
629
+    dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
630
+    dmaStreamSetMemory0(i2cp->dmatx, txbuf);
631
+    dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
632
+
633
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
634
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
635
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
636
+#else
637
+    i2cp->txbuf = txbuf;
638
+    i2cp->txbytes = txbytes;
639
+    i2cp->rxbuf = rxbuf;
640
+    i2cp->rxbytes = rxbytes;
641
+#endif
642
+  }
643
+#endif
644
+#if STM32_I2C_USE_I2C2
645
+  if (&I2CD2 == i2cp) {
646
+#if STM32_I2C_I2C2_USE_DMA
647
+    dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
648
+    dmaStreamSetMemory0(i2cp->dmatx, txbuf);
649
+    dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
650
+
651
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
652
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
653
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
654
+#else
655
+    i2cp->txbuf = txbuf;
656
+    i2cp->txbytes = txbytes;
657
+    i2cp->rxbuf = rxbuf;
658
+    i2cp->rxbytes = rxbytes;
659
+#endif
660
+  }
661
+#endif
662
+#if STM32_I2C_USE_I2C3
663
+  if (&I2CD3 == i2cp) {
664
+#if STM32_I2C_I2C3_USE_DMA
665
+    dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
666
+    dmaStreamSetMemory0(i2cp->dmatx, txbuf);
667
+    dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
668
+
669
+    dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
670
+    dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
671
+    dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
672
+#else
673
+    i2cp->txbuf = txbuf;
674
+    i2cp->txbytes = txbytes;
675
+    i2cp->rxbuf = rxbuf;
676
+    i2cp->rxbytes = rxbytes;
677
+#endif
678
+  }
679
+#endif
680
 
681
   /* Calculating the time window for the timeout on the busy bus condition.*/
682
   start = osalOsGetSystemTimeX();
717 683
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
718
index 1328d47..68f91e1 100644
719 684
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
720 685
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
721
@@ -104,6 +104,33 @@
722
 #endif

723
 
724
 /**
725
+ * @brief   I2C1 DMA enable switch.

726
+ * @details If set to @p TRUE the I2C1 driver will use DMA.

727
+ * @note    The default is @p TRUE.

728
+ */

729
+#if !defined(STM32_I2C_I2C1_USE_DMA) || defined(__DOXYGEN__)

730
+#define STM32_I2C_I2C1_USE_DMA              TRUE

731
+#endif

732
+

733
+/**

734
+ * @brief   I2C2 DMA enable switch.

735
+ * @details If set to @p TRUE the I2C2 driver will use DMA.

736
+ * @note    The default is @p TRUE.

737
+ */

738
+#if !defined(STM32_I2C_I2C2_USE_DMA) || defined(__DOXYGEN__)

739
+#define STM32_I2C_I2C2_USE_DMA              TRUE

740
+#endif

741
+

742
+/**

743
+ * @brief   I2C3 DMA enable switch.

744
+ * @details If set to @p TRUE the I2C3 driver will use DMA.

745
+ * @note    The default is @p TRUE.

746
+ */

747
+#if !defined(STM32_I2C_I2C3_USE_DMA) || defined(__DOXYGEN__)

748
+#define STM32_I2C_I2C3_USE_DMA              TRUE

749
+#endif

750
+

751
+/**

752
 * @brief   I2C1 DMA priority (0..3|lowest..highest).

753
 * @note    The priority level is used for both the TX and RX DMA streams but

754
 *          because of the streams ordering the RX stream has always priority

686
@@ -103,6 +103,33 @@
687
 #define STM32_I2C_I2C3_IRQ_PRIORITY         10
688
 #endif
689
 
690
+/**
691
+ * @brief   I2C1 DMA enable switch.
692
+ * @details If set to @p TRUE the I2C1 driver will use DMA.
693
+ * @note    The default is @p TRUE.
694
+ */
695
+#if !defined(STM32_I2C_I2C1_USE_DMA) || defined(__DOXYGEN__)
696
+#define STM32_I2C_I2C1_USE_DMA              TRUE
697
+#endif
698
+
699
+/**
700
+ * @brief   I2C2 DMA enable switch.
701
+ * @details If set to @p TRUE the I2C2 driver will use DMA.
702
+ * @note    The default is @p TRUE.
703
+ */
704
+#if !defined(STM32_I2C_I2C2_USE_DMA) || defined(__DOXYGEN__)
705
+#define STM32_I2C_I2C2_USE_DMA              TRUE
706
+#endif
707
+
708
+/**
709
+ * @brief   I2C3 DMA enable switch.
710
+ * @details If set to @p TRUE the I2C3 driver will use DMA.
711
+ * @note    The default is @p TRUE.
712
+ */
713
+#if !defined(STM32_I2C_I2C3_USE_DMA) || defined(__DOXYGEN__)
714
+#define STM32_I2C_I2C3_USE_DMA              TRUE
715
+#endif
716
+
717
 /**
718
 * @brief   I2C1 DMA priority (0..3|lowest..highest).
719
 * @note    The priority level is used for both the TX and RX DMA streams but
755 720
@@ -250,16 +277,19 @@
756
 #endif
757
 
758
 #if STM32_I2C_USE_I2C1 &&                                                   \
759
+    STM32_I2C_I2C1_USE_DMA &&                                               \
760
     !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
761
 #error "Invalid DMA priority assigned to I2C1"
762
 #endif
763
 
764
 #if STM32_I2C_USE_I2C2 &&                                                   \
765
+    STM32_I2C_I2C2_USE_DMA &&                                               \
766
     !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
767
 #error "Invalid DMA priority assigned to I2C2"
768
 #endif
769
 
770
 #if STM32_I2C_USE_I2C3 &&                                                   \
771
+    STM32_I2C_I2C3_USE_DMA &&                                               \
772
     !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
773
 #error "Invalid DMA priority assigned to I2C3"
774
 #endif
721
 #endif
722
 
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff