amiro-os / kernel / patches / I2C-without-DMA.patch @ 8a93b752
History | View | Annotate | Download (28.653 KB)
1 | 22be62dc | Thomas Schöpping | 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 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
||
4 | +++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
||
5 | @@ -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) |
||
13 | @@ -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) |
||
23 | @@ -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) |
||
33 | @@ -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. */
|
||
41 | @@ -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)) |
||
62 | @@ -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; |
||
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(); |
||
717 | 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 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
720 | +++ 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 |
||
755 | @@ -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
|
||
775 | @@ -316,7 +346,10 @@
|
||
776 | #endif
|
||
777 | #endif /* STM32_ADVANCED_DMA */ |
||
778 | |||
779 | -#if !defined(STM32_DMA_REQUIRED)
|
||
780 | +#if ((STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
||
781 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
782 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA)) && \
|
||
783 | + !defined(STM32_DMA_REQUIRED)
|
||
784 | #define STM32_DMA_REQUIRED
|
||
785 | #endif
|
||
786 | |||
787 | @@ -437,21 +470,52 @@ struct I2CDriver { |
||
788 | */ |
||
789 | i2caddr_t addr; |
||
790 | /**
|
||
791 | - * @brief RX DMA mode bit mask.
|
||
792 | - */
|
||
793 | - uint32_t rxdmamode;
|
||
794 | - /**
|
||
795 | - * @brief TX DMA mode bit mask.
|
||
796 | - */
|
||
797 | - uint32_t txdmamode;
|
||
798 | - /**
|
||
799 | - * @brief Receive DMA channel.
|
||
800 | - */
|
||
801 | - const stm32_dma_stream_t *dmarx;
|
||
802 | - /**
|
||
803 | - * @brief Transmit DMA channel.
|
||
804 | + * @brief Anonymous union to store transmission related data for either DMA or non-DMA mode.
|
||
805 | */ |
||
806 | - const stm32_dma_stream_t *dmatx;
|
||
807 | + union {
|
||
808 | + /**
|
||
809 | + * @brief Anonymous struct to store data for DMA mode.
|
||
810 | + */
|
||
811 | + struct {
|
||
812 | + /**
|
||
813 | + * @brief RX DMA mode bit mask.
|
||
814 | + */
|
||
815 | + uint32_t rxdmamode;
|
||
816 | + /**
|
||
817 | + * @brief TX DMA mode bit mask.
|
||
818 | + */
|
||
819 | + uint32_t txdmamode;
|
||
820 | + /**
|
||
821 | + * @brief Receive DMA channel.
|
||
822 | + */
|
||
823 | + const stm32_dma_stream_t *dmarx;
|
||
824 | + /**
|
||
825 | + * @brief Transmit DMA channel.
|
||
826 | + */
|
||
827 | + const stm32_dma_stream_t *dmatx;
|
||
828 | + };
|
||
829 | + /**
|
||
830 | + * @brief Anonymous struct to store data for non-DMA mode.
|
||
831 | + */
|
||
832 | + struct {
|
||
833 | + /**
|
||
834 | + * @brief Receive buffer.
|
||
835 | + */
|
||
836 | + uint8_t *rxbuf;
|
||
837 | + /**
|
||
838 | + * @brief Size of the receive buffer.
|
||
839 | + */
|
||
840 | + size_t rxbytes;
|
||
841 | + /**
|
||
842 | + * @brief Transmit buffer.
|
||
843 | + */
|
||
844 | + const uint8_t *txbuf;
|
||
845 | + /**
|
||
846 | + * @brief Size of the transmit buffer.
|
||
847 | + */
|
||
848 | + size_t txbytes;
|
||
849 | + };
|
||
850 | + };
|
||
851 | /**
|
||
852 | * @brief Pointer to the I2Cx registers block.
|
||
853 | */ |