@@ -113,9 +113,33 @@ modm::platform::SpiMaster{{ id }}_Dma<DmaChannelRx, DmaChannelTx>::waitCompleted
113113
114114template <class DmaChannelRx, class DmaChannelTx>
115115modm::ResumableResult<void>
116- modm::platform::SpiMaster{{ id }}_Dma<DmaChannelRx, DmaChannelTx>::transfer(const uint8_t *tx,
117- uint8_t *rx, std::size_t length)
116+ modm::platform::SpiMaster{{ id }}_Dma<DmaChannelRx, DmaChannelTx>::transfer(
117+ const uint8_t *tx, uint8_t *rx, std::size_t length)
118118{
119+ %% if use_fiber
120+ if ((!rx and !tx) or length == 0) return;
121+ if constexpr (Dma::RxChannel::mask == 0) rx = nullptr;
122+
123+ startTransfer(tx, rx, length);
124+
125+ while (Dma::TxChannel::isBusy() or (rx and Dma::RxChannel::isBusy()))
126+ modm::fiber::yield();
127+
128+ while (!txFifoEmpty() or (rx and !rxFifoEmpty()) or isBusy())
129+ modm::fiber::yield();
130+
131+ if (!rx) {
132+ // Drain RX FIFO, then wait for shifting to finish (which
133+ // may be *after* TX FIFO drains), then drain RX FIFO again
134+ while (!rxFifoEmpty()) read();
135+ while (isBusy()) modm::fiber::yield();
136+
137+ // Don't leave overrun flag set
138+ spi{{ id }}_hw->icr = SPI_SSPICR_RORIC_BITS;
139+ }
140+
141+ disableDreq(Dma::DreqTx | Dma::DreqRx);
142+ %% else
119143 if ( (!rx && !tx) || length == 0) {
120144 return {modm::rf::Stop};
121145 }
@@ -137,19 +161,16 @@ modm::platform::SpiMaster{{ id }}_Dma<DmaChannelRx, DmaChannelTx>::transfer(cons
137161 [[fallthrough]];
138162
139163 default:
140- while (true) {
141- if (Dma::TxChannel::isBusy() or (rx && Dma::RxChannel::isBusy()))
142- return { modm::rf::Running };
143- if (!txFifoEmpty() or (rx && !rxFifoEmpty()) or isBusy())
144- return { modm::rf::Running };
145- break;
146- }
164+ if (Dma::TxChannel::isBusy() or (rx && Dma::RxChannel::isBusy()))
165+ return { modm::rf::Running };
166+ if (!txFifoEmpty() or (rx && !rxFifoEmpty()) or isBusy())
167+ return { modm::rf::Running };
147168 if (!rx) {
148169 // Drain RX FIFO, then wait for shifting to finish (which may be *after*
149170 // TX FIFO drains), then drain RX FIFO again
150171 while (!rxFifoEmpty())
151172 (void)read();
152- while (isBusy())
173+ if (isBusy())
153174 return { modm::rf::Running };
154175
155176 // Don't leave overrun flag set
@@ -162,4 +183,5 @@ modm::platform::SpiMaster{{ id }}_Dma<DmaChannelRx, DmaChannelTx>::transfer(cons
162183 state &= ~Bit1;
163184 return {modm::rf::Stop};
164185 }
186+ %% endif
165187}
0 commit comments