Statistics
| Branch: | Tag: | Revision:

amiro-os / kernel / patches / Introduced-I2C-without-DMA.patch @ e545e620

History | View | Annotate | Download (16.389 KB)

1 e545e620 Thomas Schöpping
From 736d3be25b7389b6130e0c372328aa56e2532250 Mon Sep 17 00:00:00 2001
2
From: =?UTF-8?q?Thomas=20Sch=C3=B6pping?= <tschoepp@cit-ec.uni-bielefeld.de>
3
Date: Mon, 12 Jun 2017 17:28:49 +0200
4
Subject: [PATCH] Introduced I2C without DMA (I2Cv1 only).
5 58fe0e0b Thomas Schöpping
6
---
7 e545e620 Thomas Schöpping
 os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c | 181 ++++++++++++++++++++++++++++-
8
 os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h |  30 +++++
9
 2 files changed, 210 insertions(+), 1 deletion(-)
10
11
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
12
index 20b8cf8..b2cfb59 100644
13
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
14
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
15
@@ -34,6 +34,7 @@
16
 /* Driver local definitions.                                                 */
17
 /*===========================================================================*/
18
 
19
+#if STM32_I2C_USE_DMA
20
 #define I2C1_RX_DMA_CHANNEL                                                 \
21
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM,                        \
22
                        STM32_I2C1_RX_DMA_CHN)
23
@@ -57,6 +58,7 @@
24
 #define I2C3_TX_DMA_CHANNEL                                                 \
25
   STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM,                        \
26
                        STM32_I2C3_TX_DMA_CHN)
27
+#endif /* STM32_I2C_USE_DMA */
28
 
29
 /*===========================================================================*/
30
 /* Driver constants.                                                         */
31
@@ -72,6 +74,20 @@
32
 #define I2C_EV6_MASTER_REC_MODE_SELECTED                                    \
33
   ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR))
34
 
35
+#define I2C_EV7_MASTER_REC_BYTE_RECEIVED                                    \
36
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_RXNE))
37
+
38
+#define I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP                               \
39
+  ((uint32_t)(                                      I2C_SR1_RXNE))
40
+
41
+#define I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED                              \
42
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) |                         \
43
+              I2C_SR1_BTF | I2C_SR1_RXNE))
44
+
45
+#define I2C_EV8_MASTER_BYTE_TRANSMITTING                                    \
46
+  ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA)<< 16) |           \
47
+              I2C_SR1_TXE))
48
+
49
 #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED                                   \
50
   ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) |          \
51
               I2C_SR1_BTF | I2C_SR1_TXE))
52
@@ -128,9 +144,11 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
53
   dp->CR2 = 0;
54
   dp->SR1 = 0;
55
 
56
+#if STM32_I2C_USE_DMA
57
   /* Stops the associated DMA streams.*/
58
   dmaStreamDisable(i2cp->dmatx);
59
   dmaStreamDisable(i2cp->dmarx);
60
+#endif /* STM32_I2C_USE_DMA */
61
 }
62
 
63
 /**
64
@@ -247,12 +265,13 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
65
   uint32_t regSR2 = dp->SR2;
66
   uint32_t event = dp->SR1;
67
 
68
+#if STM32_I2C_USE_DMA
69
   /* Interrupts are disabled just before dmaStreamEnable() because there
70
      is no need of interrupts until next transaction begin. All the work is
71
      done by the DMA.*/
72
   switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
73
   case I2C_EV5_MASTER_MODE_SELECT:
74
-    if ((i2cp->addr >> 8) > 0) { 
75
+    if ((i2cp->addr >> 8) > 0) {
76
       /* 10-bit address: 1 1 1 1 0 X X R/W */
77
       dp->DR = 0xF0 | (0x6 & (i2cp->addr >> 8)) | (0x1 & i2cp->addr);
78
     } else {
79
@@ -292,8 +311,125 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
80
   /* Clear ADDR flag. */
81
   if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
82
     (void)dp->SR2;
83
+#else
84
+  switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
85
+  case I2C_EV5_MASTER_MODE_SELECT:
86
+    dp->CR2 |= I2C_CR2_ITBUFEN;
87
+    dp->DR = i2cp->addr;
88
+    break;
89
+  case I2C_EV6_MASTER_TRA_MODE_SELECTED:
90
+    (void)dp->SR2; // clear ADDR flag
91
+    /* EV8_1 */
92
+    dp->DR = *(i2cp->txbuf);
93
+
94
+    ++i2cp->txbuf;
95
+    --i2cp->txbytes;
96
+
97
+    /* if N == 1, skip the I2C_EV8_MASTER_BYTE_TRANSMITTING event
98
+     * but enter I2C_EV8_2_MASTER_BYTE_TRANSMITTED next */
99
+    if (i2cp->txbytes == 0) {
100
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
101
+    }
102
+    break;
103
+  case I2C_EV6_MASTER_REC_MODE_SELECTED:
104
+    switch (i2cp->rxbytes) {
105
+    case 1:
106
+      dp->CR1 &= ~I2C_CR1_ACK;
107
+      (void)dp->SR2; // clear ADDR flag
108
+      dp->CR1 |= I2C_CR1_STOP;
109
+      break;
110
+    case 2:
111
+      (void)dp->SR2; // clear ADDR flag
112
+      /* EV6_1 */
113
+      dp->CR1 |= I2C_CR1_POS;
114
+      dp->CR1 &= ~I2C_CR1_ACK;
115
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
116
+      break;
117
+    case 3: /* N == 3 is a very special case, since EV7 is completely skipped */
118
+      (void)dp->SR2; // clear ADDR flag
119
+      /* Disable the I2C_EV7_MASTER_REC_BYTE_RECEIVED event
120
+       * but enter I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP next */
121
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
122
+      break;
123
+    default: /* N > 2 */
124
+      (void)dp->SR2; // clear ADDR flag
125
+      break;
126
+    }
127
+    break;
128
+  case I2C_EV7_MASTER_REC_BYTE_RECEIVED:
129
+    if (i2cp->rxbytes > 3) {
130
+      *(i2cp->rxbuf) = dp->DR;
131
+      ++i2cp->rxbuf;
132
+      --i2cp->rxbytes;
133
+    }
134
+    if (i2cp->rxbytes == 3) {
135
+      /* Disable this event for DataN-2, but force into event
136
+       * I2C_EV7_2_EV7_3_MASTER_REC_BYTE_RECEIVED_QUEUED by not reading dp->DR. */
137
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
138
+    }
139
+    break;
140
+  case I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP:
141
+    osalDbgAssert(i2cp->rxbytes == 1, "more than 1 byte to be received");
142
+    *(i2cp->rxbuf) = dp->DR;
143
+    --i2cp->rxbytes;
144
+    dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
145
+    _i2c_wakeup_isr(i2cp);
146
+    break;
147
+  case I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED:
148
+    if (i2cp->rxbytes == 3) {
149
+      /* EV7_2 (N > 2) */
150
+      dp->CR1 &= ~I2C_CR1_ACK;
151
+      *(i2cp->rxbuf) = dp->DR;
152
+      ++i2cp->rxbuf;
153
+      dp->CR1 |= I2C_CR1_STOP;
154
+      *(i2cp->rxbuf) = dp->DR;
155
+      ++i2cp->rxbuf;
156
+      i2cp->rxbytes -= 2;
157
+      /* enable I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP event */
158
+      dp->CR2 |= I2C_CR2_ITBUFEN;
159
+    } else {
160
+      /* EV7_3 (N == 2) */
161
+      dp->CR1 |= I2C_CR1_STOP;
162
+      *(i2cp->rxbuf) = dp->DR;
163
+      ++i2cp->rxbuf;
164
+      *(i2cp->rxbuf) = dp->DR;
165
+      i2cp->rxbytes -= 2;
166
+
167
+      dp->CR1 &= ~I2C_CR1_POS;
168
+      dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
169
+
170
+      _i2c_wakeup_isr(i2cp);
171
+    }
172
+    break;
173
+  case I2C_EV8_MASTER_BYTE_TRANSMITTING:
174
+    dp->DR = *(i2cp->txbuf);
175
+    ++i2cp->txbuf;
176
+    --i2cp->txbytes;
177
+
178
+    /* if this was the last byte, ensure that this event is not entered again */
179
+    if (i2cp->txbytes == 0) {
180
+      dp->CR2 &= ~I2C_CR2_ITBUFEN;
181
+    }
182
+    break;
183
+  case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
184
+    if (i2cp->rxbytes > 0) {
185
+      /* start "read after write" operation (LSB of address = 1 => read) */
186
+      i2cp->addr |= 0x01;
187
+      dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
188
+    } else {
189
+      dp->CR1 |= I2C_CR1_STOP;
190
+      dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
191
+      _i2c_wakeup_isr(i2cp);
192
+    }
193
+    break;
194
+  default:
195
+    osalDbgAssert(i2cp->rxbytes != 1, "more than 1 byte to be received");
196
+    break;
197
+  }
198
+#endif /* STM32_I2C_USE_DMA */
199
 }
200
 
201
+#if STM32_I2C_USE_DMA
202
 /**
203
  * @brief   DMA RX end IRQ handler.
204
  *
205
@@ -347,6 +483,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
206
      of R/W transaction itself.*/
207
   dp->CR2 |= I2C_CR2_ITEVTEN;
208
 }
209
+#endif /* STM32_I2C_USE_DMA */
210
 
211
 /**
212
  * @brief   I2C error handler.
213
@@ -358,9 +495,11 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
214
  */
215
 static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) {
216
 
217
+#if STM32_I2C_USE_DMA
218
   /* Clears interrupt flags just to be safe.*/
219
   dmaStreamDisable(i2cp->dmatx);
220
   dmaStreamDisable(i2cp->dmarx);
221
+#endif /* STM32_I2C_USE_DMA */
222
 
223
   i2cp->errors = I2C_NO_ERROR;
224
 
225
@@ -506,24 +645,30 @@ void i2c_lld_init(void) {
226
   i2cObjectInit(&I2CD1);
227
   I2CD1.thread = NULL;
228
   I2CD1.i2c    = I2C1;
229
+#if STM32_I2C_USE_DMA
230
   I2CD1.dmarx  = STM32_DMA_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM);
231
   I2CD1.dmatx  = STM32_DMA_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM);
232
+#endif /* STM32_I2C_USE_DMA */
233
 #endif /* STM32_I2C_USE_I2C1 */
234
 
235
 #if STM32_I2C_USE_I2C2
236
   i2cObjectInit(&I2CD2);
237
   I2CD2.thread = NULL;
238
   I2CD2.i2c    = I2C2;
239
+#if STM32_I2C_USE_DMA
240
   I2CD2.dmarx  = STM32_DMA_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM);
241
   I2CD2.dmatx  = STM32_DMA_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM);
242
+#endif /* STM32_I2C_USE_DMA */
243
 #endif /* STM32_I2C_USE_I2C2 */
244
 
245
 #if STM32_I2C_USE_I2C3
246
   i2cObjectInit(&I2CD3);
247
   I2CD3.thread = NULL;
248
   I2CD3.i2c    = I2C3;
249
+#if STM32_I2C_USE_DMA
250
   I2CD3.dmarx  = STM32_DMA_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM);
251
   I2CD3.dmatx  = STM32_DMA_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM);
252
+#endif /* STM32_I2C_USE_DMA */
253
 #endif /* STM32_I2C_USE_I2C3 */
254
 }
255
 
256
@@ -540,6 +685,7 @@ void i2c_lld_start(I2CDriver *i2cp) {
257
   /* If in stopped state then enables the I2C and DMA clocks.*/
258
   if (i2cp->state == I2C_STOP) {
259
 
260
+#if STM32_I2C_USE_DMA
261
     i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
262
                       STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
263
                       STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
264
@@ -548,9 +694,11 @@ void i2c_lld_start(I2CDriver *i2cp) {
265
                       STM32_DMA_CR_MINC       | STM32_DMA_CR_DMEIE |
266
                       STM32_DMA_CR_TEIE       | STM32_DMA_CR_TCIE |
267
                       STM32_DMA_CR_DIR_P2M;
268
+#endif /* STM32_I2C_USE_DMA */
269
 
270
 #if STM32_I2C_USE_I2C1
271
     if (&I2CD1 == i2cp) {
272
+#if STM32_I2C_USE_DMA
273
       bool b;
274
 
275
       rccResetI2C1();
276
@@ -564,19 +712,23 @@ void i2c_lld_start(I2CDriver *i2cp) {
277
                             (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
278
                             (void *)i2cp);
279
       osalDbgAssert(!b, "stream already allocated");
280
+#endif /* STM32_I2C_USE_DMA */
281
       rccEnableI2C1(FALSE);
282
       nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
283
       nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
284
 
285
+#if STM32_I2C_USE_DMA
286
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
287
                        STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
288
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
289
                        STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
290
+#endif /* STM32_I2C_USE_DMA */
291
     }
292
 #endif /* STM32_I2C_USE_I2C1 */
293
 
294
 #if STM32_I2C_USE_I2C2
295
     if (&I2CD2 == i2cp) {
296
+#if STM32_I2C_USE_DMA
297
       bool b;
298
 
299
       rccResetI2C2();
300
@@ -590,19 +742,23 @@ void i2c_lld_start(I2CDriver *i2cp) {
301
                             (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
302
                             (void *)i2cp);
303
       osalDbgAssert(!b, "stream already allocated");
304
+#endif /* STM32_I2C_USE_DMA */
305
       rccEnableI2C2(FALSE);
306
       nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
307
       nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
308
 
309
+#if STM32_I2C_USE_DMA
310
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
311
                        STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
312
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
313
                        STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
314
+#endif /* STM32_I2C_USE_DMA */
315
     }
316
 #endif /* STM32_I2C_USE_I2C2 */
317
 
318
 #if STM32_I2C_USE_I2C3
319
     if (&I2CD3 == i2cp) {
320
+#if STM32_I2C_USE_DMA
321
       bool b;
322
 
323
       rccResetI2C3();
324
@@ -616,26 +772,35 @@ void i2c_lld_start(I2CDriver *i2cp) {
325
                             (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
326
                             (void *)i2cp);
327
       osalDbgAssert(!b, "stream already allocated");
328
+#endif /* STM32_I2C_USE_DMA */
329
       rccEnableI2C3(FALSE);
330
       nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
331
       nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
332
 
333
+#if STM32_I2C_USE_DMA
334
       i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
335
                        STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
336
       i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
337
                        STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
338
+#endif /* STM32_I2C_USE_DMA */
339
     }
340
 #endif /* STM32_I2C_USE_I2C3 */
341
   }
342
 
343
+#if STM32_I2C_USE_DMA
344
   /* I2C registers pointed by the DMA.*/
345
   dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
346
   dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
347
+#endif /* STM32_I2C_USE_DMA */
348
 
349
   /* Reset i2c peripheral.*/
350
   dp->CR1 = I2C_CR1_SWRST;
351
   dp->CR1 = 0;
352
+#if STM32_I2C_USE_DMA
353
   dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
354
+#else
355
+  dp->CR2 = I2C_CR2_ITERREN;
356
+#endif /* STM32_I2C_USE_DMA */
357
 
358
   /* Setup I2C parameters.*/
359
   i2c_lld_set_clock(i2cp);
360
@@ -659,8 +824,10 @@ void i2c_lld_stop(I2CDriver *i2cp) {
361
 
362
     /* I2C disable.*/
363
     i2c_lld_abort_operation(i2cp);
364
+#if STM32_I2C_USE_DMA
365
     dmaStreamRelease(i2cp->dmatx);
366
     dmaStreamRelease(i2cp->dmarx);
367
+#endif /* STM32_I2C_USE_DMA */
368
 
369
 #if STM32_I2C_USE_I2C1
370
     if (&I2CD1 == i2cp) {
371
@@ -730,10 +897,15 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
372
   /* Releases the lock from high level driver.*/
373
   osalSysUnlock();
374
 
375
+#if STM32_I2C_USE_DMA
376
   /* RX DMA setup.*/
377
   dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
378
   dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
379
   dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
380
+#else
381
+  i2cp->rxbuf = rxbuf;
382
+  i2cp->rxbytes = rxbytes;
383
+#endif /* STM32_I2C_USE_DMA */
384
 
385
   /* Calculating the time window for the timeout on the busy bus condition.*/
386
   start = osalOsGetSystemTimeX();
387
@@ -810,6 +982,7 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
388
   /* Releases the lock from high level driver.*/
389
   osalSysUnlock();
390
 
391
+#if STM32_I2C_USE_DMA
392
   /* TX DMA setup.*/
393
   dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
394
   dmaStreamSetMemory0(i2cp->dmatx, txbuf);
395
@@ -819,6 +992,12 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
396
   dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
397
   dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
398
   dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
399
+#else
400
+  i2cp->txbuf = txbuf;
401
+  i2cp->txbytes = txbytes;
402
+  i2cp->rxbuf = rxbuf;
403
+  i2cp->rxbytes = rxbytes;
404
+#endif /* STM32_I2C_USE_DMA */
405
 
406
   /* Calculating the time window for the timeout on the busy bus condition.*/
407
   start = osalOsGetSystemTimeX();
408
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
409
index a812ceb..127c708 100644
410
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
411
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
412 58fe0e0b Thomas Schöpping
@@ -76,6 +76,15 @@
413 e545e620 Thomas Schöpping
 #endif
414
 
415
 /**
416
+ * @brief   I2C data transfer use dma switch.
417
+ * @details If set to @p TRUE the support for I2C DMA is included.
418
+ * @note    The default is @p FALSE.
419
+ */
420
+#if !defined(STM32_I2C_USE_DMA) || defined(__DOXYGEN__)
421
+#define STM32_I2C_USE_DMA                   TRUE
422
+#endif
423
+
424
+/**
425
  * @brief   I2C timeout on busy condition in milliseconds.
426
  */
427
 #if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
428
@@ -249,6 +258,7 @@
429
 #error "Invalid IRQ priority assigned to I2C3"
430
 #endif
431
 
432
+#if STM32_I2C_USE_DMA
433
 #if STM32_I2C_USE_I2C1 &&                                                   \
434
     !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
435
 #error "Invalid DMA priority assigned to I2C1"
436
@@ -319,6 +329,7 @@
437
 #if !defined(STM32_DMA_REQUIRED)
438
 #define STM32_DMA_REQUIRED
439
 #endif
440
+#endif /* STM32_I2C_USE_DMA */
441
 
442
 /* Check clock range. */
443
 #if defined(STM32F4XX)
444
@@ -436,6 +447,7 @@ struct I2CDriver {
445
    * @brief     Current slave address without R/W bit.
446
    */
447
   i2caddr_t                 addr;
448
+#if STM32_I2C_USE_DMA
449
   /**
450
    * @brief RX DMA mode bit mask.
451
    */
452
@@ -452,6 +464,24 @@ struct I2CDriver {
453
    * @brief     Transmit DMA channel.
454
    */
455
   const stm32_dma_stream_t  *dmatx;
456
+#else
457
+  /**
458
+   * @brief     Receive buffer.
459
+   */
460
+  uint8_t                   *rxbuf;
461
+  /**
462
+   * @brief     Receive buffer size.
463
+   */
464
+  size_t                    rxbytes;
465
+  /**
466
+   * @brief     Transmit buffer.
467
+   */
468
+  const uint8_t             *txbuf;
469
+  /**
470
+   * @brief     Transmit buffer size.
471
+   */
472
+  size_t                    txbytes;
473
+#endif /* STM32_I2C_USE_DMA */
474
   /**
475
    * @brief     Pointer to the I2Cx registers block.
476
    */
477
-- 
478
2.7.4