1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-26 01:35:41 +03:00

[4.4.2] If CS is asserted between transfers then consider bus to be busy for … (#12784)

If CS is asserted between transfers then consider bus to be busy for all but owning device (#12604)

* If CS is asserted between transfers then consider bus to be busy for all but owning device

* Track if MAX7456 is mid DMA transfer, not simply that the SPI bus is busy

* Enable SPI DMA TX/RX together

Co-authored-by: Steve Evans <SteveCEvans@users.noreply.github.com>
This commit is contained in:
Mark Haslinghuis 2023-05-12 23:39:00 +02:00 committed by GitHub
parent 5a737a47e0
commit 167bd0f3d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 10 deletions

View file

@ -156,6 +156,10 @@ bool spiInit(SPIDevice device)
// Return true if DMA engine is busy
bool spiIsBusy(const extDevice_t *dev)
{
if (dev->bus->csLockDevice && (dev->bus->csLockDevice != dev)) {
// If CS is still asserted, but not by the current device, the bus is busy
return true;
}
return (dev->bus->curSegment != (busSegment_t *)BUS_SPI_FREE);
}
@ -163,7 +167,7 @@ bool spiIsBusy(const extDevice_t *dev)
void spiWait(const extDevice_t *dev)
{
// Wait for completion
while (dev->bus->curSegment != (busSegment_t *)BUS_SPI_FREE);
while (spiIsBusy(dev));
}
// Wait for bus to become free, then read/write block of data
@ -419,6 +423,11 @@ FAST_IRQ_HANDLER static void spiIrqHandler(const extDevice_t *dev)
spiSequenceStart(nextDev);
} else {
// The end of the segment list has been reached, so mark transactions as complete
if (bus->curSegment->negateCS) {
bus->csLockDevice = (extDevice_t *)NULL;
} else {
bus->csLockDevice = (extDevice_t *)dev;
}
bus->curSegment = (busSegment_t *)BUS_SPI_FREE;
}
} else {
@ -729,6 +738,11 @@ void spiSequence(const extDevice_t *dev, busSegment_t *segments)
// Safe to discard the volatile qualifier as we're in an atomic block
busSegment_t *endCmpSegment = (busSegment_t *)bus->curSegment;
/* It is possible that the endCmpSegment may be NULL as the bus is held busy by csLockDevice.
* If this is the case this transfer will be silently dropped. Therefore holding CS low after a transfer,
* as is done with the SD card, MUST not be done on a bus where interrupts may trigger a transfer
* on an idle bus, such as would be the case with a gyro. This would be result in skipped gyro transfers.
*/
if (endCmpSegment) {
while (true) {
// Find the last segment of the current transfer
@ -750,11 +764,11 @@ void spiSequence(const extDevice_t *dev, busSegment_t *segments)
endCmpSegment = (busSegment_t *)endCmpSegment->u.link.segments;
}
}
}
// Record the dev and segments parameters in the terminating segment entry
endCmpSegment->u.link.dev = dev;
endCmpSegment->u.link.segments = segments;
// Record the dev and segments parameters in the terminating segment entry
endCmpSegment->u.link.dev = dev;
endCmpSegment->u.link.segments = segments;
}
return;
} else {