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
|