amiro-os / kernel / patches / I2C-without-DMA.patch @ 23ec8223
History | View | Annotate | Download (29.719 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 | 7368d8da | Thomas Schöpping | @@ -75,6 +81,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 | 7368d8da | Thomas Schöpping | @@ -132,8 +152,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 | 7368d8da | Thomas Schöpping | @@ -238,14 +274,18 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) { |
89 | 732a4657 | Thomas Schöpping | 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 | 7368d8da | Thomas Schöpping | @@ -303,7 +343,146 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) { |
110 | dp->SR1 &= ~I2C_SR1_BERR; |
||
111 | } |
||
112 | 732a4657 | Thomas Schöpping | } |
113 | +#endif /* any I2CDx uses DMA mode */
|
||
114 | +
|
||
115 | +#if (STM32_I2C_USE_I2C1 && !STM32_I2C_I2C1_USE_DMA) || \
|
||
116 | + (STM32_I2C_USE_I2C2 && !STM32_I2C_I2C2_USE_DMA) || \
|
||
117 | + (STM32_I2C_USE_I2C3 && !STM32_I2C_I2C3_USE_DMA) || \
|
||
118 | + defined(__DOXYGEN__)
|
||
119 | +/**
|
||
120 | + * @brief I2C shared ISR code for non-DMA access.
|
||
121 | + *
|
||
122 | + * @param[in] i2cp pointer to the @p I2CDriver object
|
||
123 | + *
|
||
124 | + * @notapi
|
||
125 | + */
|
||
126 | +static void i2c_lld_serve_event_interrupt_isr(I2CDriver *i2cp) {
|
||
127 | + I2C_TypeDef *dp = i2cp->i2c;
|
||
128 | + uint32_t regSR2 = dp->SR2;
|
||
129 | + uint32_t event = dp->SR1;
|
||
130 | +
|
||
131 | + switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
|
||
132 | + case I2C_EV5_MASTER_MODE_SELECT:
|
||
133 | + dp->CR2 |= I2C_CR2_ITBUFEN;
|
||
134 | + dp->DR = i2cp->addr;
|
||
135 | + break;
|
||
136 | + case I2C_EV6_MASTER_TRA_MODE_SELECTED:
|
||
137 | + (void)dp->SR2; // clear ADDR flag
|
||
138 | + /* EV8_1 */
|
||
139 | + dp->DR = *(i2cp->txbuf);
|
||
140 | +
|
||
141 | + ++i2cp->txbuf;
|
||
142 | + --i2cp->txbytes;
|
||
143 | +
|
||
144 | + /* if N == 1, skip the I2C_EV8_MASTER_BYTE_TRANSMITTING event
|
||
145 | + * but enter I2C_EV8_2_MASTER_BYTE_TRANSMITTED next */
|
||
146 | + if (i2cp->txbytes == 0) {
|
||
147 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
148 | + }
|
||
149 | + break;
|
||
150 | + case I2C_EV6_MASTER_REC_MODE_SELECTED:
|
||
151 | + switch (i2cp->rxbytes) {
|
||
152 | + case 1:
|
||
153 | + dp->CR1 &= ~I2C_CR1_ACK;
|
||
154 | + (void)dp->SR2; // clear ADDR flag
|
||
155 | + dp->CR1 |= I2C_CR1_STOP;
|
||
156 | + break;
|
||
157 | + case 2:
|
||
158 | + (void)dp->SR2; // clear ADDR flag
|
||
159 | + /* EV6_1 */
|
||
160 | + dp->CR1 |= I2C_CR1_POS;
|
||
161 | + dp->CR1 &= ~I2C_CR1_ACK;
|
||
162 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
163 | + break;
|
||
164 | + case 3: /* N == 3 is a very special case, since EV7 is completely skipped */
|
||
165 | + (void)dp->SR2; // clear ADDR flag
|
||
166 | + /* Disable the I2C_EV7_MASTER_REC_BYTE_RECEIVED event
|
||
167 | + * but enter I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP next */
|
||
168 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
169 | + break;
|
||
170 | + default: /* N > 2 */
|
||
171 | + (void)dp->SR2; // clear ADDR flag
|
||
172 | + break;
|
||
173 | + }
|
||
174 | + break;
|
||
175 | + case I2C_EV7_MASTER_REC_BYTE_RECEIVED:
|
||
176 | + if (i2cp->rxbytes > 3) {
|
||
177 | + *(i2cp->rxbuf) = dp->DR;
|
||
178 | + ++i2cp->rxbuf;
|
||
179 | + --i2cp->rxbytes;
|
||
180 | + }
|
||
181 | + if (i2cp->rxbytes == 3) {
|
||
182 | + /* Disable this event for DataN-2, but force into event
|
||
183 | + * I2C_EV7_2_EV7_3_MASTER_REC_BYTE_RECEIVED_QUEUED by not reading dp->DR. */
|
||
184 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
185 | + }
|
||
186 | + break;
|
||
187 | + case I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP:
|
||
188 | + osalDbgAssert(i2cp->rxbytes == 1, "more than 1 byte to be received");
|
||
189 | + *(i2cp->rxbuf) = dp->DR;
|
||
190 | + --i2cp->rxbytes;
|
||
191 | + dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
|
||
192 | + _i2c_wakeup_isr(i2cp);
|
||
193 | + break;
|
||
194 | + case I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED:
|
||
195 | + if (i2cp->rxbytes == 3) {
|
||
196 | + /* EV7_2 (N > 2) */
|
||
197 | + dp->CR1 &= ~I2C_CR1_ACK;
|
||
198 | + *(i2cp->rxbuf) = dp->DR;
|
||
199 | + ++i2cp->rxbuf;
|
||
200 | + dp->CR1 |= I2C_CR1_STOP;
|
||
201 | + *(i2cp->rxbuf) = dp->DR;
|
||
202 | + ++i2cp->rxbuf;
|
||
203 | + i2cp->rxbytes -= 2;
|
||
204 | + /* enable I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP event */
|
||
205 | + dp->CR2 |= I2C_CR2_ITBUFEN;
|
||
206 | + } else {
|
||
207 | + /* EV7_3 (N == 2) */
|
||
208 | + dp->CR1 |= I2C_CR1_STOP;
|
||
209 | + *(i2cp->rxbuf) = dp->DR;
|
||
210 | + ++i2cp->rxbuf;
|
||
211 | + *(i2cp->rxbuf) = dp->DR;
|
||
212 | + i2cp->rxbytes -= 2;
|
||
213 | +
|
||
214 | + dp->CR1 &= ~I2C_CR1_POS;
|
||
215 | + dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
|
||
216 | +
|
||
217 | + _i2c_wakeup_isr(i2cp);
|
||
218 | + }
|
||
219 | + break;
|
||
220 | + case I2C_EV8_MASTER_BYTE_TRANSMITTING:
|
||
221 | + dp->DR = *(i2cp->txbuf);
|
||
222 | + ++i2cp->txbuf;
|
||
223 | + --i2cp->txbytes;
|
||
224 | +
|
||
225 | + /* if this was the last byte, ensure that this event is not entered again */
|
||
226 | + if (i2cp->txbytes == 0) {
|
||
227 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
228 | + }
|
||
229 | + break;
|
||
230 | + case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
|
||
231 | + if (i2cp->rxbytes > 0) {
|
||
232 | + /* start "read after write" operation (LSB of address = 1 => read) */
|
||
233 | + i2cp->addr |= 0x01;
|
||
234 | + dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
|
||
235 | + } else {
|
||
236 | + dp->CR1 |= I2C_CR1_STOP;
|
||
237 | + dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
|
||
238 | + _i2c_wakeup_isr(i2cp);
|
||
239 | + }
|
||
240 | + break;
|
||
241 | + default:
|
||
242 | + osalDbgAssert(i2cp->rxbytes != 1, "more than 1 byte to be received");
|
||
243 | + break;
|
||
244 | + }
|
||
245 | +}
|
||
246 | +#endif /* any I2CDx uses non-DMA mode */
|
||
247 | +
|
||
248 | 7368d8da | Thomas Schöpping | |
249 | 732a4657 | Thomas Schöpping | +#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
250 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
251 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) || \
|
||
252 | + defined(__DOXYGEN__)
|
||
253 | /**
|
||
254 | * @brief DMA RX end IRQ handler.
|
||
255 | * |
||
256 | 7368d8da | Thomas Schöpping | @@ -357,6 +536,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { |
257 | 732a4657 | Thomas Schöpping | of R/W transaction itself.*/ |
258 | dp->CR2 |= I2C_CR2_ITEVTEN; |
||
259 | } |
||
260 | +#endif /* any I2CDx uses DMA mode */
|
||
261 | |||
262 | /**
|
||
263 | * @brief I2C error handler.
|
||
264 | 7368d8da | Thomas Schöpping | @@ -369,8 +549,24 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { |
265 | 732a4657 | Thomas Schöpping | static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) { |
266 | |||
267 | /* Clears interrupt flags just to be safe.*/
|
||
268 | - dmaStreamDisable(i2cp->dmatx);
|
||
269 | - dmaStreamDisable(i2cp->dmarx);
|
||
270 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
271 | + if (&I2CD1 == i2cp) {
|
||
272 | + dmaStreamDisable(i2cp->dmatx);
|
||
273 | + dmaStreamDisable(i2cp->dmarx);
|
||
274 | + }
|
||
275 | +#endif
|
||
276 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
277 | + if (&I2CD2 == i2cp) {
|
||
278 | + dmaStreamDisable(i2cp->dmatx);
|
||
279 | + dmaStreamDisable(i2cp->dmarx);
|
||
280 | + }
|
||
281 | +#endif
|
||
282 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
283 | + if (&I2CD3 == i2cp) {
|
||
284 | + dmaStreamDisable(i2cp->dmatx);
|
||
285 | + dmaStreamDisable(i2cp->dmarx);
|
||
286 | + }
|
||
287 | +#endif
|
||
288 | |||
289 | i2cp->errors = I2C_NO_ERROR; |
||
290 | |||
291 | 7368d8da | Thomas Schöpping | @@ -421,7 +617,11 @@ OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
|
292 | 732a4657 | Thomas Schöpping | |
293 | OSAL_IRQ_PROLOGUE(); |
||
294 | |||
295 | - i2c_lld_serve_event_interrupt(&I2CD1);
|
||
296 | +#if STM32_I2C_I2C1_USE_DMA
|
||
297 | + i2c_lld_serve_event_interrupt_dma(&I2CD1);
|
||
298 | +#else
|
||
299 | + i2c_lld_serve_event_interrupt_isr(&I2CD1);
|
||
300 | +#endif
|
||
301 | |||
302 | OSAL_IRQ_EPILOGUE(); |
||
303 | } |
||
304 | 7368d8da | Thomas Schöpping | @@ -451,7 +651,11 @@ OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
|
305 | 732a4657 | Thomas Schöpping | |
306 | OSAL_IRQ_PROLOGUE(); |
||
307 | |||
308 | - i2c_lld_serve_event_interrupt(&I2CD2);
|
||
309 | +#if STM32_I2C_I2C2_USE_DMA
|
||
310 | + i2c_lld_serve_event_interrupt_dma(&I2CD2);
|
||
311 | +#else
|
||
312 | + i2c_lld_serve_event_interrupt_isr(&I2CD2);
|
||
313 | +#endif
|
||
314 | |||
315 | OSAL_IRQ_EPILOGUE(); |
||
316 | } |
||
317 | 7368d8da | Thomas Schöpping | @@ -483,7 +687,11 @@ OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
|
318 | 732a4657 | Thomas Schöpping | |
319 | OSAL_IRQ_PROLOGUE(); |
||
320 | |||
321 | - i2c_lld_serve_event_interrupt(&I2CD3);
|
||
322 | +#if STM32_I2C_I2C3_USE_DMA
|
||
323 | + i2c_lld_serve_event_interrupt_dma(&I2CD3);
|
||
324 | +#else
|
||
325 | + i2c_lld_serve_event_interrupt_isr(&I2CD3);
|
||
326 | +#endif
|
||
327 | |||
328 | OSAL_IRQ_EPILOGUE(); |
||
329 | } |
||
330 | 7368d8da | Thomas Schöpping | @@ -554,19 +762,22 @@ void i2c_lld_start(I2CDriver *i2cp) { |
331 | 732a4657 | Thomas Schöpping | /* If in stopped state then enables the I2C and DMA clocks.*/
|
332 | if (i2cp->state == I2C_STOP) {
|
||
333 | |||
334 | - i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
335 | - STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
336 | - STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
337 | - STM32_DMA_CR_DIR_M2P;
|
||
338 | - i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
339 | - STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
340 | - STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
341 | - STM32_DMA_CR_DIR_P2M;
|
||
342 | -
|
||
343 | #if STM32_I2C_USE_I2C1
|
||
344 | if (&I2CD1 == i2cp) {
|
||
345 | +#if STM32_I2C_I2C1_USE_DMA
|
||
346 | + i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
347 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
348 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
349 | + STM32_DMA_CR_DIR_M2P;
|
||
350 | + i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
351 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
352 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
353 | + STM32_DMA_CR_DIR_P2M;
|
||
354 | +#endif
|
||
355 | +
|
||
356 | rccResetI2C1(); |
||
357 | |||
358 | +#if STM32_I2C_I2C1_USE_DMA
|
||
359 | i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM, |
||
360 | STM32_I2C_I2C1_IRQ_PRIORITY, |
||
361 | (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
||
362 | 7368d8da | Thomas Schöpping | @@ -577,22 +788,50 @@ void i2c_lld_start(I2CDriver *i2cp) { |
363 | 732a4657 | Thomas Schöpping | (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
364 | (void *)i2cp);
|
||
365 | osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
||
366 | +#endif
|
||
367 | |||
368 | rccEnableI2C1(true);
|
||
369 | nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY); |
||
370 | nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY); |
||
371 | |||
372 | +#if STM32_I2C_I2C1_USE_DMA
|
||
373 | i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | |
||
374 | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); |
||
375 | i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) | |
||
376 | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); |
||
377 | +
|
||
378 | + /* I2C registers pointed by the DMA.*/
|
||
379 | + dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
380 | + dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
381 | +#endif
|
||
382 | +
|
||
383 | + /* Reset i2c peripheral.*/
|
||
384 | + dp->CR1 = I2C_CR1_SWRST;
|
||
385 | + dp->CR1 = 0;
|
||
386 | +#if STM32_I2C_I2C1_USE_DMA
|
||
387 | + dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
388 | +#else
|
||
389 | + dp->CR2 = I2C_CR2_ITERREN;
|
||
390 | +#endif
|
||
391 | } |
||
392 | #endif /* STM32_I2C_USE_I2C1 */ |
||
393 | |||
394 | #if STM32_I2C_USE_I2C2
|
||
395 | if (&I2CD2 == i2cp) {
|
||
396 | +#if STM32_I2C_I2C2_USE_DMA
|
||
397 | + i2cp->txdmamode = 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_M2P;
|
||
401 | + i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
402 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
403 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
404 | + STM32_DMA_CR_DIR_P2M;
|
||
405 | +#endif
|
||
406 | +
|
||
407 | rccResetI2C2(); |
||
408 | |||
409 | +#if STM32_I2C_I2C2_USE_DMA
|
||
410 | i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM, |
||
411 | STM32_I2C_I2C2_IRQ_PRIORITY, |
||
412 | (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
||
413 | 7368d8da | Thomas Schöpping | @@ -603,22 +842,50 @@ void i2c_lld_start(I2CDriver *i2cp) { |
414 | 732a4657 | Thomas Schöpping | (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
415 | (void *)i2cp);
|
||
416 | osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
||
417 | +#endif
|
||
418 | |||
419 | rccEnableI2C2(true);
|
||
420 | nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY); |
||
421 | nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY); |
||
422 | |||
423 | +#if STM32_I2C_I2C2_USE_DMA
|
||
424 | i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) | |
||
425 | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); |
||
426 | i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) | |
||
427 | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); |
||
428 | +
|
||
429 | + /* I2C registers pointed by the DMA.*/
|
||
430 | + dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
431 | + dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
432 | +#endif
|
||
433 | +
|
||
434 | + /* Reset i2c peripheral.*/
|
||
435 | + dp->CR1 = I2C_CR1_SWRST;
|
||
436 | + dp->CR1 = 0;
|
||
437 | +#if STM32_I2C_I2C2_USE_DMA
|
||
438 | + dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
439 | +#else
|
||
440 | + dp->CR2 = I2C_CR2_ITERREN;
|
||
441 | +#endif
|
||
442 | } |
||
443 | #endif /* STM32_I2C_USE_I2C2 */ |
||
444 | |||
445 | #if STM32_I2C_USE_I2C3
|
||
446 | if (&I2CD3 == i2cp) {
|
||
447 | +#if STM32_I2C_I2C3_USE_DMA
|
||
448 | + i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
449 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
450 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
451 | + STM32_DMA_CR_DIR_M2P;
|
||
452 | + i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
453 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
454 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
455 | + STM32_DMA_CR_DIR_P2M;
|
||
456 | +#endif
|
||
457 | +
|
||
458 | rccResetI2C3(); |
||
459 | |||
460 | +#if STM32_I2C_I2C3_USE_DMA
|
||
461 | i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM, |
||
462 | STM32_I2C_I2C3_IRQ_PRIORITY, |
||
463 | (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
||
464 | 7368d8da | Thomas Schöpping | @@ -629,28 +896,35 @@ void i2c_lld_start(I2CDriver *i2cp) { |
465 | 732a4657 | Thomas Schöpping | (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
466 | (void *)i2cp);
|
||
467 | osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
||
468 | +#endif
|
||
469 | |||
470 | rccEnableI2C3(true);
|
||
471 | nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY); |
||
472 | nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY); |
||
473 | |||
474 | +#if STM32_I2C_I2C3_USE_DMA
|
||
475 | i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) | |
||
476 | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); |
||
477 | i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) | |
||
478 | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); |
||
479 | +
|
||
480 | + /* I2C registers pointed by the DMA.*/
|
||
481 | + dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
482 | + dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
483 | +#endif
|
||
484 | +
|
||
485 | + /* Reset i2c peripheral.*/
|
||
486 | + dp->CR1 = I2C_CR1_SWRST;
|
||
487 | + dp->CR1 = 0;
|
||
488 | +#if STM32_I2C_I2C3_USE_DMA
|
||
489 | + dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
490 | +#else
|
||
491 | + dp->CR2 = I2C_CR2_ITERREN;
|
||
492 | +#endif
|
||
493 | } |
||
494 | #endif /* STM32_I2C_USE_I2C3 */ |
||
495 | } |
||
496 | |||
497 | - /* I2C registers pointed by the DMA.*/
|
||
498 | - dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
499 | - dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
500 | -
|
||
501 | - /* Reset i2c peripheral.*/
|
||
502 | - dp->CR1 = I2C_CR1_SWRST;
|
||
503 | - dp->CR1 = 0;
|
||
504 | - dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
505 | -
|
||
506 | /* Setup I2C parameters.*/
|
||
507 | i2c_lld_set_clock(i2cp); |
||
508 | i2c_lld_set_opmode(i2cp); |
||
509 | 7368d8da | Thomas Schöpping | @@ -673,13 +947,15 @@ void i2c_lld_stop(I2CDriver *i2cp) { |
510 | 732a4657 | Thomas Schöpping | |
511 | /* I2C disable.*/
|
||
512 | i2c_lld_abort_operation(i2cp); |
||
513 | - dmaStreamFreeI(i2cp->dmatx);
|
||
514 | - dmaStreamFreeI(i2cp->dmarx);
|
||
515 | - i2cp->dmatx = NULL;
|
||
516 | - i2cp->dmarx = NULL;
|
||
517 | |||
518 | #if STM32_I2C_USE_I2C1
|
||
519 | if (&I2CD1 == i2cp) {
|
||
520 | +#if STM32_I2C_I2C1_USE_DMA
|
||
521 | + dmaStreamFreeI(i2cp->dmatx);
|
||
522 | + dmaStreamFreeI(i2cp->dmarx);
|
||
523 | + i2cp->dmatx = NULL;
|
||
524 | + i2cp->dmarx = NULL;
|
||
525 | +#endif
|
||
526 | nvicDisableVector(I2C1_EV_IRQn); |
||
527 | nvicDisableVector(I2C1_ER_IRQn); |
||
528 | rccDisableI2C1(); |
||
529 | 7368d8da | Thomas Schöpping | @@ -688,6 +964,12 @@ void i2c_lld_stop(I2CDriver *i2cp) { |
530 | 732a4657 | Thomas Schöpping | |
531 | #if STM32_I2C_USE_I2C2
|
||
532 | if (&I2CD2 == i2cp) {
|
||
533 | +#if STM32_I2C_I2C2_USE_DMA
|
||
534 | + dmaStreamFreeI(i2cp->dmatx);
|
||
535 | + dmaStreamFreeI(i2cp->dmarx);
|
||
536 | + i2cp->dmatx = NULL;
|
||
537 | + i2cp->dmarx = NULL;
|
||
538 | +#endif
|
||
539 | nvicDisableVector(I2C2_EV_IRQn); |
||
540 | nvicDisableVector(I2C2_ER_IRQn); |
||
541 | rccDisableI2C2(); |
||
542 | 7368d8da | Thomas Schöpping | @@ -696,6 +978,12 @@ void i2c_lld_stop(I2CDriver *i2cp) { |
543 | 732a4657 | Thomas Schöpping | |
544 | #if STM32_I2C_USE_I2C3
|
||
545 | if (&I2CD3 == i2cp) {
|
||
546 | +#if STM32_I2C_I2C3_USE_DMA
|
||
547 | + dmaStreamFreeI(i2cp->dmatx);
|
||
548 | + dmaStreamFreeI(i2cp->dmarx);
|
||
549 | + i2cp->dmatx = NULL;
|
||
550 | + i2cp->dmarx = NULL;
|
||
551 | +#endif
|
||
552 | nvicDisableVector(I2C3_EV_IRQn); |
||
553 | nvicDisableVector(I2C3_ER_IRQn); |
||
554 | rccDisableI2C3(); |
||
555 | 7368d8da | Thomas Schöpping | @@ -747,10 +1035,43 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
556 | 732a4657 | Thomas Schöpping | /* Releases the lock from high level driver.*/
|
557 | osalSysUnlock(); |
||
558 | |||
559 | - /* RX DMA setup.*/
|
||
560 | - dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
561 | - dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
562 | - dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
563 | + /* RX (DMA) setup.*/
|
||
564 | +#if STM32_I2C_USE_I2C1
|
||
565 | + if (&I2CD1 == i2cp) {
|
||
566 | +#if STM32_I2C_I2C1_USE_DMA
|
||
567 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
568 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
569 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
570 | +#else
|
||
571 | + i2cp->rxbuf = rxbuf;
|
||
572 | + i2cp->rxbytes = rxbytes;
|
||
573 | +#endif
|
||
574 | + }
|
||
575 | +#endif
|
||
576 | +#if STM32_I2C_USE_I2C2
|
||
577 | + if (&I2CD2 == i2cp) {
|
||
578 | +#if STM32_I2C_I2C2_USE_DMA
|
||
579 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
580 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
581 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
582 | +#else
|
||
583 | + i2cp->rxbuf = rxbuf;
|
||
584 | + i2cp->rxbytes = rxbytes;
|
||
585 | +#endif
|
||
586 | + }
|
||
587 | +#endif
|
||
588 | +#if STM32_I2C_USE_I2C3
|
||
589 | + if (&I2CD3 == i2cp) {
|
||
590 | +#if STM32_I2C_I2C3_USE_DMA
|
||
591 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
592 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
593 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
594 | +#else
|
||
595 | + i2cp->rxbuf = rxbuf;
|
||
596 | + i2cp->rxbytes = rxbytes;
|
||
597 | +#endif
|
||
598 | + }
|
||
599 | +#endif
|
||
600 | |||
601 | /* Calculating the time window for the timeout on the busy bus condition.*/
|
||
602 | start = osalOsGetSystemTimeX(); |
||
603 | 7368d8da | Thomas Schöpping | @@ -769,7 +1090,21 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
604 | /* If the system time went outside the allowed window then a timeout
|
||
605 | condition is returned.*/ |
||
606 | if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
|
||
607 | - dmaStreamDisable(i2cp->dmarx);
|
||
608 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
609 | + if (&I2CD1 == i2cp) {
|
||
610 | + dmaStreamDisable(i2cp->dmarx);
|
||
611 | + }
|
||
612 | +#endif
|
||
613 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
614 | + if (&I2CD2 == i2cp) {
|
||
615 | + dmaStreamDisable(i2cp->dmarx);
|
||
616 | + }
|
||
617 | +#endif
|
||
618 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
619 | + if (&I2CD3 == i2cp) {
|
||
620 | + dmaStreamDisable(i2cp->dmarx);
|
||
621 | + }
|
||
622 | +#endif
|
||
623 | return MSG_TIMEOUT;
|
||
624 | } |
||
625 | |||
626 | @@ -783,7 +1118,21 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||
627 | /* Waits for the operation completion or a timeout.*/
|
||
628 | msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout); |
||
629 | if (msg != MSG_OK) {
|
||
630 | - dmaStreamDisable(i2cp->dmarx);
|
||
631 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
632 | + if (&I2CD1 == i2cp) {
|
||
633 | + dmaStreamDisable(i2cp->dmarx);
|
||
634 | + }
|
||
635 | +#endif
|
||
636 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
637 | + if (&I2CD2 == i2cp) {
|
||
638 | + dmaStreamDisable(i2cp->dmarx);
|
||
639 | + }
|
||
640 | +#endif
|
||
641 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
642 | + if (&I2CD3 == i2cp) {
|
||
643 | + dmaStreamDisable(i2cp->dmarx);
|
||
644 | + }
|
||
645 | +#endif
|
||
646 | } |
||
647 | |||
648 | return msg;
|
||
649 | @@ -835,15 +1184,61 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||
650 | 732a4657 | Thomas Schöpping | /* Releases the lock from high level driver.*/
|
651 | osalSysUnlock(); |
||
652 | |||
653 | - /* TX DMA setup.*/
|
||
654 | - dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
655 | - dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
656 | - dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
657 | -
|
||
658 | - /* RX DMA setup.*/
|
||
659 | - dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
660 | - dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
661 | - dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
662 | + /* TX (DMA) and RX (DMA) setup.*/
|
||
663 | +#if STM32_I2C_USE_I2C1
|
||
664 | + if (&I2CD1 == i2cp) {
|
||
665 | +#if STM32_I2C_I2C1_USE_DMA
|
||
666 | + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
667 | + dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
668 | + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
669 | +
|
||
670 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
671 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
672 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
673 | +#else
|
||
674 | + i2cp->txbuf = txbuf;
|
||
675 | + i2cp->txbytes = txbytes;
|
||
676 | + i2cp->rxbuf = rxbuf;
|
||
677 | + i2cp->rxbytes = rxbytes;
|
||
678 | +#endif
|
||
679 | + }
|
||
680 | +#endif
|
||
681 | +#if STM32_I2C_USE_I2C2
|
||
682 | + if (&I2CD2 == i2cp) {
|
||
683 | +#if STM32_I2C_I2C2_USE_DMA
|
||
684 | + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
685 | + dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
686 | + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
687 | +
|
||
688 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
689 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
690 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
691 | +#else
|
||
692 | + i2cp->txbuf = txbuf;
|
||
693 | + i2cp->txbytes = txbytes;
|
||
694 | + i2cp->rxbuf = rxbuf;
|
||
695 | + i2cp->rxbytes = rxbytes;
|
||
696 | +#endif
|
||
697 | + }
|
||
698 | +#endif
|
||
699 | +#if STM32_I2C_USE_I2C3
|
||
700 | + if (&I2CD3 == i2cp) {
|
||
701 | +#if STM32_I2C_I2C3_USE_DMA
|
||
702 | + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
703 | + dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
704 | + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
705 | +
|
||
706 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
707 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
708 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
709 | +#else
|
||
710 | + i2cp->txbuf = txbuf;
|
||
711 | + i2cp->txbytes = txbytes;
|
||
712 | + i2cp->rxbuf = rxbuf;
|
||
713 | + i2cp->rxbytes = rxbytes;
|
||
714 | +#endif
|
||
715 | + }
|
||
716 | +#endif
|
||
717 | |||
718 | /* Calculating the time window for the timeout on the busy bus condition.*/
|
||
719 | start = osalOsGetSystemTimeX(); |
||
720 | 7368d8da | Thomas Schöpping | @@ -862,8 +1257,24 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
721 | /* If the system time went outside the allowed window then a timeout
|
||
722 | condition is returned.*/ |
||
723 | if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
|
||
724 | - dmaStreamDisable(i2cp->dmatx);
|
||
725 | - dmaStreamDisable(i2cp->dmarx);
|
||
726 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
727 | + if (&I2CD1 == i2cp) {
|
||
728 | + dmaStreamDisable(i2cp->dmatx);
|
||
729 | + dmaStreamDisable(i2cp->dmarx);
|
||
730 | + }
|
||
731 | +#endif
|
||
732 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
733 | + if (&I2CD2 == i2cp) {
|
||
734 | + dmaStreamDisable(i2cp->dmatx);
|
||
735 | + dmaStreamDisable(i2cp->dmarx);
|
||
736 | + }
|
||
737 | +#endif
|
||
738 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
739 | + if (&I2CD3 == i2cp) {
|
||
740 | + dmaStreamDisable(i2cp->dmatx);
|
||
741 | + dmaStreamDisable(i2cp->dmarx);
|
||
742 | + }
|
||
743 | +#endif
|
||
744 | return MSG_TIMEOUT;
|
||
745 | } |
||
746 | |||
747 | @@ -877,8 +1288,24 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||
748 | /* Waits for the operation completion or a timeout.*/
|
||
749 | msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout); |
||
750 | if (msg != MSG_OK) {
|
||
751 | - dmaStreamDisable(i2cp->dmatx);
|
||
752 | - dmaStreamDisable(i2cp->dmarx);
|
||
753 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
754 | + if (&I2CD1 == i2cp) {
|
||
755 | + dmaStreamDisable(i2cp->dmatx);
|
||
756 | + dmaStreamDisable(i2cp->dmarx);
|
||
757 | + }
|
||
758 | +#endif
|
||
759 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
760 | + if (&I2CD2 == i2cp) {
|
||
761 | + dmaStreamDisable(i2cp->dmatx);
|
||
762 | + dmaStreamDisable(i2cp->dmarx);
|
||
763 | + }
|
||
764 | +#endif
|
||
765 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
766 | + if (&I2CD3 == i2cp) {
|
||
767 | + dmaStreamDisable(i2cp->dmatx);
|
||
768 | + dmaStreamDisable(i2cp->dmarx);
|
||
769 | + }
|
||
770 | +#endif
|
||
771 | } |
||
772 | |||
773 | return msg;
|
||
774 | 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
|
775 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
776 | +++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
777 | 732a4657 | Thomas Schöpping | @@ -103,6 +103,33 @@
|
778 | #define STM32_I2C_I2C3_IRQ_PRIORITY 10 |
||
779 | #endif
|
||
780 | |||
781 | +/**
|
||
782 | + * @brief I2C1 DMA enable switch.
|
||
783 | + * @details If set to @p TRUE the I2C1 driver will use DMA.
|
||
784 | + * @note The default is @p TRUE.
|
||
785 | + */
|
||
786 | +#if !defined(STM32_I2C_I2C1_USE_DMA) || defined(__DOXYGEN__)
|
||
787 | +#define STM32_I2C_I2C1_USE_DMA TRUE
|
||
788 | +#endif
|
||
789 | +
|
||
790 | +/**
|
||
791 | + * @brief I2C2 DMA enable switch.
|
||
792 | + * @details If set to @p TRUE the I2C2 driver will use DMA.
|
||
793 | + * @note The default is @p TRUE.
|
||
794 | + */
|
||
795 | +#if !defined(STM32_I2C_I2C2_USE_DMA) || defined(__DOXYGEN__)
|
||
796 | +#define STM32_I2C_I2C2_USE_DMA TRUE
|
||
797 | +#endif
|
||
798 | +
|
||
799 | +/**
|
||
800 | + * @brief I2C3 DMA enable switch.
|
||
801 | + * @details If set to @p TRUE the I2C3 driver will use DMA.
|
||
802 | + * @note The default is @p TRUE.
|
||
803 | + */
|
||
804 | +#if !defined(STM32_I2C_I2C3_USE_DMA) || defined(__DOXYGEN__)
|
||
805 | +#define STM32_I2C_I2C3_USE_DMA TRUE
|
||
806 | +#endif
|
||
807 | +
|
||
808 | /**
|
||
809 | * @brief I2C1 DMA priority (0..3|lowest..highest). |
||
810 | * @note The priority level is used for both the TX and RX DMA streams but |
||
811 | 22be62dc | Thomas Schöpping | @@ -250,16 +277,19 @@
|
812 | 732a4657 | Thomas Schöpping | #endif
|
813 | |||
814 | #if STM32_I2C_USE_I2C1 && \ |
||
815 | + STM32_I2C_I2C1_USE_DMA && \
|
||
816 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY) |
||
817 | #error "Invalid DMA priority assigned to I2C1" |
||
818 | #endif
|
||
819 | |||
820 | #if STM32_I2C_USE_I2C2 && \ |
||
821 | + STM32_I2C_I2C2_USE_DMA && \
|
||
822 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY) |
||
823 | #error "Invalid DMA priority assigned to I2C2" |
||
824 | #endif
|
||
825 | |||
826 | #if STM32_I2C_USE_I2C3 && \ |
||
827 | + STM32_I2C_I2C3_USE_DMA && \
|
||
828 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY) |
||
829 | #error "Invalid DMA priority assigned to I2C3" |
||
830 | #endif
|
||
831 | 22be62dc | Thomas Schöpping | @@ -316,7 +346,10 @@
|
832 | 732a4657 | Thomas Schöpping | #endif
|
833 | #endif /* STM32_ADVANCED_DMA */ |
||
834 | |||
835 | -#if !defined(STM32_DMA_REQUIRED)
|
||
836 | +#if ((STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
||
837 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
838 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA)) && \
|
||
839 | + !defined(STM32_DMA_REQUIRED)
|
||
840 | #define STM32_DMA_REQUIRED
|
||
841 | #endif
|
||
842 | |||
843 | 22be62dc | Thomas Schöpping | @@ -437,21 +470,52 @@ struct I2CDriver { |
844 | 732a4657 | Thomas Schöpping | */ |
845 | i2caddr_t addr; |
||
846 | /**
|
||
847 | - * @brief RX DMA mode bit mask.
|
||
848 | - */
|
||
849 | - uint32_t rxdmamode;
|
||
850 | - /**
|
||
851 | - * @brief TX DMA mode bit mask.
|
||
852 | - */
|
||
853 | - uint32_t txdmamode;
|
||
854 | - /**
|
||
855 | - * @brief Receive DMA channel.
|
||
856 | - */
|
||
857 | - const stm32_dma_stream_t *dmarx;
|
||
858 | - /**
|
||
859 | - * @brief Transmit DMA channel.
|
||
860 | + * @brief Anonymous union to store transmission related data for either DMA or non-DMA mode.
|
||
861 | */ |
||
862 | - const stm32_dma_stream_t *dmatx;
|
||
863 | + union {
|
||
864 | + /**
|
||
865 | + * @brief Anonymous struct to store data for DMA mode.
|
||
866 | + */
|
||
867 | + struct {
|
||
868 | + /**
|
||
869 | + * @brief RX DMA mode bit mask.
|
||
870 | + */
|
||
871 | + uint32_t rxdmamode;
|
||
872 | + /**
|
||
873 | + * @brief TX DMA mode bit mask.
|
||
874 | + */
|
||
875 | + uint32_t txdmamode;
|
||
876 | + /**
|
||
877 | + * @brief Receive DMA channel.
|
||
878 | + */
|
||
879 | + const stm32_dma_stream_t *dmarx;
|
||
880 | + /**
|
||
881 | + * @brief Transmit DMA channel.
|
||
882 | + */
|
||
883 | + const stm32_dma_stream_t *dmatx;
|
||
884 | + };
|
||
885 | + /**
|
||
886 | + * @brief Anonymous struct to store data for non-DMA mode.
|
||
887 | + */
|
||
888 | + struct {
|
||
889 | + /**
|
||
890 | + * @brief Receive buffer.
|
||
891 | + */
|
||
892 | + uint8_t *rxbuf;
|
||
893 | + /**
|
||
894 | + * @brief Size of the receive buffer.
|
||
895 | + */
|
||
896 | + size_t rxbytes;
|
||
897 | + /**
|
||
898 | + * @brief Transmit buffer.
|
||
899 | + */
|
||
900 | + const uint8_t *txbuf;
|
||
901 | + /**
|
||
902 | + * @brief Size of the transmit buffer.
|
||
903 | + */
|
||
904 | + size_t txbytes;
|
||
905 | + };
|
||
906 | + };
|
||
907 | /**
|
||
908 | * @brief Pointer to the I2Cx registers block.
|
||
909 | */ |