amiro-os / kernel / patches / I2C-without-DMA.patch @ 3f716772
History | View | Annotate | Download (27.04 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 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
||
3 | +++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
||
4 | @@ -34,6 +34,7 @@
|
||
5 | 732a4657 | Thomas Schöpping | /* 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) |
||
12 | 22be62dc | Thomas Schöpping | @@ -41,7 +42,9 @@
|
13 | 732a4657 | Thomas Schöpping | #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) |
||
22 | 22be62dc | Thomas Schöpping | @@ -49,7 +52,9 @@
|
23 | 732a4657 | Thomas Schöpping | #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) |
||
32 | 22be62dc | Thomas Schöpping | @@ -57,6 +62,7 @@
|
33 | 732a4657 | Thomas Schöpping | #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. */
|
||
40 | 22be62dc | Thomas Schöpping | @@ -72,6 +78,20 @@
|
41 | 732a4657 | Thomas Schöpping | #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)) |
||
61 | 22be62dc | Thomas Schöpping | @@ -129,8 +149,24 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) { |
62 | 732a4657 | Thomas Schöpping | 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 | 22be62dc | Thomas Schöpping | @@ -252,7 +292,7 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) { |
110 | 732a4657 | Thomas Schöpping | 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(); |
||
683 | 22be62dc | Thomas Schöpping | diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
684 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
685 | +++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
686 | 732a4657 | Thomas Schöpping | @@ -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 |
||
720 | 22be62dc | Thomas Schöpping | @@ -250,16 +277,19 @@
|
721 | 732a4657 | Thomas Schöpping | #endif
|
722 | |||
723 | #if STM32_I2C_USE_I2C1 && \ |
||
724 | + STM32_I2C_I2C1_USE_DMA && \
|
||
725 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY) |
||
726 | #error "Invalid DMA priority assigned to I2C1" |
||
727 | #endif
|
||
728 | |||
729 | #if STM32_I2C_USE_I2C2 && \ |
||
730 | + STM32_I2C_I2C2_USE_DMA && \
|
||
731 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY) |
||
732 | #error "Invalid DMA priority assigned to I2C2" |
||
733 | #endif
|
||
734 | |||
735 | #if STM32_I2C_USE_I2C3 && \ |
||
736 | + STM32_I2C_I2C3_USE_DMA && \
|
||
737 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY) |
||
738 | #error "Invalid DMA priority assigned to I2C3" |
||
739 | #endif
|
||
740 | 22be62dc | Thomas Schöpping | @@ -316,7 +346,10 @@
|
741 | 732a4657 | Thomas Schöpping | #endif
|
742 | #endif /* STM32_ADVANCED_DMA */ |
||
743 | |||
744 | -#if !defined(STM32_DMA_REQUIRED)
|
||
745 | +#if ((STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
||
746 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
747 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA)) && \
|
||
748 | + !defined(STM32_DMA_REQUIRED)
|
||
749 | #define STM32_DMA_REQUIRED
|
||
750 | #endif
|
||
751 | |||
752 | 22be62dc | Thomas Schöpping | @@ -437,21 +470,52 @@ struct I2CDriver { |
753 | 732a4657 | Thomas Schöpping | */ |
754 | i2caddr_t addr; |
||
755 | /**
|
||
756 | - * @brief RX DMA mode bit mask.
|
||
757 | - */
|
||
758 | - uint32_t rxdmamode;
|
||
759 | - /**
|
||
760 | - * @brief TX DMA mode bit mask.
|
||
761 | - */
|
||
762 | - uint32_t txdmamode;
|
||
763 | - /**
|
||
764 | - * @brief Receive DMA channel.
|
||
765 | - */
|
||
766 | - const stm32_dma_stream_t *dmarx;
|
||
767 | - /**
|
||
768 | - * @brief Transmit DMA channel.
|
||
769 | + * @brief Anonymous union to store transmission related data for either DMA or non-DMA mode.
|
||
770 | */ |
||
771 | - const stm32_dma_stream_t *dmatx;
|
||
772 | + union {
|
||
773 | + /**
|
||
774 | + * @brief Anonymous struct to store data for DMA mode.
|
||
775 | + */
|
||
776 | + struct {
|
||
777 | + /**
|
||
778 | + * @brief RX DMA mode bit mask.
|
||
779 | + */
|
||
780 | + uint32_t rxdmamode;
|
||
781 | + /**
|
||
782 | + * @brief TX DMA mode bit mask.
|
||
783 | + */
|
||
784 | + uint32_t txdmamode;
|
||
785 | + /**
|
||
786 | + * @brief Receive DMA channel.
|
||
787 | + */
|
||
788 | + const stm32_dma_stream_t *dmarx;
|
||
789 | + /**
|
||
790 | + * @brief Transmit DMA channel.
|
||
791 | + */
|
||
792 | + const stm32_dma_stream_t *dmatx;
|
||
793 | + };
|
||
794 | + /**
|
||
795 | + * @brief Anonymous struct to store data for non-DMA mode.
|
||
796 | + */
|
||
797 | + struct {
|
||
798 | + /**
|
||
799 | + * @brief Receive buffer.
|
||
800 | + */
|
||
801 | + uint8_t *rxbuf;
|
||
802 | + /**
|
||
803 | + * @brief Size of the receive buffer.
|
||
804 | + */
|
||
805 | + size_t rxbytes;
|
||
806 | + /**
|
||
807 | + * @brief Transmit buffer.
|
||
808 | + */
|
||
809 | + const uint8_t *txbuf;
|
||
810 | + /**
|
||
811 | + * @brief Size of the transmit buffer.
|
||
812 | + */
|
||
813 | + size_t txbytes;
|
||
814 | + };
|
||
815 | + };
|
||
816 | /**
|
||
817 | * @brief Pointer to the I2Cx registers block.
|
||
818 | */ |