We've been happily using the H7 port for a long time now with no issue, but hit an interesting one today. I got a reproducible fault when doing a 32 byte transfer on I2C on a I2C peripheral on H743 that is in STOP state. At the time it happens there is no DMA assigned to the peripheral, so it faulted when it tried to disable a NULL DMA object. When the error happens the ISR register is 0x8101, which indicates a bus error. The device had NAKed the 32 byte read after 30 bytes, and the ArduPilot I2C driver issues a retry. The device again NAKed after 30 bytes, and then ChibiOS faulted when it gave up and released the DMA, then the ISR arrived.
I attach a patch that fixes it. I decided to add the check on I2Cv1 and I2Cv2 as well, just in case the same thing can happen.
Note that we use DMA sharing extensively in ArduPilot, so when an I2C peripheral is in STOP state it may not have a DMA channel. We need this even on H7 where the DMA is really flexible as we just have so many peripherals we're using.
I am wondering if a better fix is to protect dmaStreamDisable() everywhere against a NULL value for the stream pointer. Could there be other similar assumptions lurking in other peripheral drivers that aren't true when using DMA sharing?
- (1.19 KiB) Downloaded 16 times