Statistics
| Branch: | Tag: | Revision:

amiro-os / patches / 0007-SMT32-add-optional-I2C-non-DMA-driver-option.patch @ 552936c8

History | View | Annotate | Download (17.143 KB)

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