mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-14 20:10:18 +03:00
Implement queuing of SPI request segments
This commit is contained in:
parent
5ef34f79d5
commit
44e45ddc84
1 changed files with 7 additions and 17 deletions
|
@ -706,14 +706,13 @@ uint8_t spiGetExtDeviceCount(const extDevice_t *dev)
|
||||||
void spiSequence(const extDevice_t *dev, busSegment_t *segments)
|
void spiSequence(const extDevice_t *dev, busSegment_t *segments)
|
||||||
{
|
{
|
||||||
busDevice_t *bus = dev->bus;
|
busDevice_t *bus = dev->bus;
|
||||||
busSegment_t *queuedEndSegments[NUM_QUEUE_SEGS];
|
|
||||||
uint8_t queuedEndSegmentsIndex = 0;
|
|
||||||
|
|
||||||
ATOMIC_BLOCK(NVIC_PRIO_MAX) {
|
ATOMIC_BLOCK(NVIC_PRIO_MAX) {
|
||||||
if (spiIsBusy(dev)) {
|
if (spiIsBusy(dev)) {
|
||||||
busSegment_t *endSegment;
|
busSegment_t *endSegment;
|
||||||
|
|
||||||
// Defer this transfer to be triggered upon completion of the current transfer
|
// Defer this transfer to be triggered upon completion of the current transfer
|
||||||
|
|
||||||
// Find the last segment of the current transfer
|
// Find the last segment of the current transfer
|
||||||
for (endSegment = segments; endSegment->len; endSegment++);
|
for (endSegment = segments; endSegment->len; endSegment++);
|
||||||
|
|
||||||
|
@ -725,27 +724,18 @@ void spiSequence(const extDevice_t *dev, busSegment_t *segments)
|
||||||
for (; endCmpSegment->len; endCmpSegment++);
|
for (; endCmpSegment->len; endCmpSegment++);
|
||||||
|
|
||||||
if (endCmpSegment == endSegment) {
|
if (endCmpSegment == endSegment) {
|
||||||
// Attempt to use the new segment list twice in the same queue. Abort.
|
/* Attempt to use the new segment list twice in the same queue. Abort.
|
||||||
return;
|
* Note that this can only happen with non-blocking transfers so drivers must take
|
||||||
}
|
* care to avoid this.
|
||||||
|
* */
|
||||||
for (uint8_t n = 0; n < queuedEndSegmentsIndex; n++) {
|
|
||||||
if (endCmpSegment == queuedEndSegments[n]) {
|
|
||||||
// Attempt to use the same segment list twice in the same queue. Abort.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
queuedEndSegments[queuedEndSegmentsIndex++] = endCmpSegment;
|
|
||||||
|
|
||||||
if (queuedEndSegmentsIndex == NUM_QUEUE_SEGS) {
|
|
||||||
// Queue is too long. Abort.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endCmpSegment->txData == NULL) {
|
if (endCmpSegment->txData == NULL) {
|
||||||
|
// End of the segment list queue reached
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
// Follow the link to the next queued segment list
|
||||||
endCmpSegment = (busSegment_t *)endCmpSegment->rxData;
|
endCmpSegment = (busSegment_t *)endCmpSegment->rxData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue