Revision 7368d8da kernel/patches/I2C-without-DMA.patch
kernel/patches/I2C-without-DMA.patch | ||
---|---|---|
37 | 37 |
|
38 | 38 |
/*===========================================================================*/ |
39 | 39 |
/* Driver constants. */ |
40 |
@@ -72,6 +78,20 @@
|
|
40 |
@@ -75,6 +81,20 @@
|
|
41 | 41 |
#define I2C_EV6_MASTER_REC_MODE_SELECTED \ |
42 | 42 |
((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR)) |
43 | 43 |
|
... | ... | |
58 | 58 |
#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED \ |
59 | 59 |
((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | \ |
60 | 60 |
I2C_SR1_BTF | I2C_SR1_TXE)) |
61 |
@@ -129,8 +149,24 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
|
|
61 |
@@ -132,8 +152,24 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
|
|
62 | 62 |
dp->SR1 = 0; |
63 | 63 |
|
64 | 64 |
/* Stops the associated DMA streams.*/ |
... | ... | |
85 | 85 |
} |
86 | 86 |
|
87 | 87 |
/** |
88 |
@@ -235,14 +271,18 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) {
|
|
88 |
@@ -238,14 +274,18 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) {
|
|
89 | 89 |
dp->CR1 = regCR1; |
90 | 90 |
} |
91 | 91 |
|
... | ... | |
106 | 106 |
I2C_TypeDef *dp = i2cp->i2c; |
107 | 107 |
uint32_t regSR2 = dp->SR2; |
108 | 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,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; |
|
109 |
@@ -303,7 +343,146 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) { |
|
110 |
dp->SR1 &= ~I2C_SR1_BERR; |
|
111 |
} |
|
121 | 112 |
} |
122 | 113 |
+#endif /* any I2CDx uses DMA mode */ |
123 | 114 |
+ |
... | ... | |
253 | 244 |
+ } |
254 | 245 |
+} |
255 | 246 |
+#endif /* any I2CDx uses non-DMA mode */ |
256 |
|
|
257 | 247 |
+ |
248 |
|
|
258 | 249 |
+#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \ |
259 | 250 |
+ (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \ |
260 | 251 |
+ (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) || \ |
... | ... | |
262 | 253 |
/** |
263 | 254 |
* @brief DMA RX end IRQ handler. |
264 | 255 |
* |
265 |
@@ -347,6 +526,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
|
256 |
@@ -357,6 +536,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
|
266 | 257 |
of R/W transaction itself.*/ |
267 | 258 |
dp->CR2 |= I2C_CR2_ITEVTEN; |
268 | 259 |
} |
... | ... | |
270 | 261 |
|
271 | 262 |
/** |
272 | 263 |
* @brief I2C error handler. |
273 |
@@ -359,8 +539,24 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
|
264 |
@@ -369,8 +549,24 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
|
274 | 265 |
static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) { |
275 | 266 |
|
276 | 267 |
/* Clears interrupt flags just to be safe.*/ |
... | ... | |
297 | 288 |
|
298 | 289 |
i2cp->errors = I2C_NO_ERROR; |
299 | 290 |
|
300 |
@@ -407,7 +603,11 @@ OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
|
|
291 |
@@ -421,7 +617,11 @@ OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
|
|
301 | 292 |
|
302 | 293 |
OSAL_IRQ_PROLOGUE(); |
303 | 294 |
|
... | ... | |
310 | 301 |
|
311 | 302 |
OSAL_IRQ_EPILOGUE(); |
312 | 303 |
} |
313 |
@@ -437,7 +637,11 @@ OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
|
|
304 |
@@ -451,7 +651,11 @@ OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
|
|
314 | 305 |
|
315 | 306 |
OSAL_IRQ_PROLOGUE(); |
316 | 307 |
|
... | ... | |
323 | 314 |
|
324 | 315 |
OSAL_IRQ_EPILOGUE(); |
325 | 316 |
} |
326 |
@@ -469,7 +673,11 @@ OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
|
|
317 |
@@ -483,7 +687,11 @@ OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
|
|
327 | 318 |
|
328 | 319 |
OSAL_IRQ_PROLOGUE(); |
329 | 320 |
|
... | ... | |
336 | 327 |
|
337 | 328 |
OSAL_IRQ_EPILOGUE(); |
338 | 329 |
} |
339 |
@@ -540,19 +748,22 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
330 |
@@ -554,19 +762,22 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
340 | 331 |
/* If in stopped state then enables the I2C and DMA clocks.*/ |
341 | 332 |
if (i2cp->state == I2C_STOP) { |
342 | 333 |
|
... | ... | |
368 | 359 |
i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM, |
369 | 360 |
STM32_I2C_I2C1_IRQ_PRIORITY, |
370 | 361 |
(stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
371 |
@@ -563,22 +774,50 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
362 |
@@ -577,22 +788,50 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
372 | 363 |
(stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
373 | 364 |
(void *)i2cp); |
374 | 365 |
osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
... | ... | |
419 | 410 |
i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM, |
420 | 411 |
STM32_I2C_I2C2_IRQ_PRIORITY, |
421 | 412 |
(stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
422 |
@@ -589,22 +828,50 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
413 |
@@ -603,22 +842,50 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
423 | 414 |
(stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
424 | 415 |
(void *)i2cp); |
425 | 416 |
osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
... | ... | |
470 | 461 |
i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM, |
471 | 462 |
STM32_I2C_I2C3_IRQ_PRIORITY, |
472 | 463 |
(stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
473 |
@@ -615,28 +882,35 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
464 |
@@ -629,28 +896,35 @@ void i2c_lld_start(I2CDriver *i2cp) {
|
|
474 | 465 |
(stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
475 | 466 |
(void *)i2cp); |
476 | 467 |
osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
... | ... | |
515 | 506 |
/* Setup I2C parameters.*/ |
516 | 507 |
i2c_lld_set_clock(i2cp); |
517 | 508 |
i2c_lld_set_opmode(i2cp); |
518 |
@@ -659,13 +933,15 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
|
509 |
@@ -673,13 +947,15 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
|
519 | 510 |
|
520 | 511 |
/* I2C disable.*/ |
521 | 512 |
i2c_lld_abort_operation(i2cp); |
... | ... | |
535 | 526 |
nvicDisableVector(I2C1_EV_IRQn); |
536 | 527 |
nvicDisableVector(I2C1_ER_IRQn); |
537 | 528 |
rccDisableI2C1(); |
538 |
@@ -674,6 +950,12 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
|
529 |
@@ -688,6 +964,12 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
|
539 | 530 |
|
540 | 531 |
#if STM32_I2C_USE_I2C2 |
541 | 532 |
if (&I2CD2 == i2cp) { |
... | ... | |
548 | 539 |
nvicDisableVector(I2C2_EV_IRQn); |
549 | 540 |
nvicDisableVector(I2C2_ER_IRQn); |
550 | 541 |
rccDisableI2C2(); |
551 |
@@ -682,6 +964,12 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
|
542 |
@@ -696,6 +978,12 @@ void i2c_lld_stop(I2CDriver *i2cp) {
|
|
552 | 543 |
|
553 | 544 |
#if STM32_I2C_USE_I2C3 |
554 | 545 |
if (&I2CD3 == i2cp) { |
... | ... | |
561 | 552 |
nvicDisableVector(I2C3_EV_IRQn); |
562 | 553 |
nvicDisableVector(I2C3_ER_IRQn); |
563 | 554 |
rccDisableI2C3(); |
564 |
@@ -732,10 +1020,43 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
|
555 |
@@ -747,10 +1035,43 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
|
565 | 556 |
/* Releases the lock from high level driver.*/ |
566 | 557 |
osalSysUnlock(); |
567 | 558 |
|
... | ... | |
609 | 600 |
|
610 | 601 |
/* Calculating the time window for the timeout on the busy bus condition.*/ |
611 | 602 |
start = osalOsGetSystemTimeX(); |
612 |
@@ -812,15 +1133,61 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, |
|
603 |
@@ -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, |
|
613 | 650 |
/* Releases the lock from high level driver.*/ |
614 | 651 |
osalSysUnlock(); |
615 | 652 |
|
... | ... | |
680 | 717 |
|
681 | 718 |
/* Calculating the time window for the timeout on the busy bus condition.*/ |
682 | 719 |
start = osalOsGetSystemTimeX(); |
720 |
@@ -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; |
|
683 | 774 |
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 | 775 |
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h |
685 | 776 |
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h |
Also available in: Unified diff