mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-16 15:00:34 +08:00
Eliminate the TD DMA callback; we don't need to know that it's completed.
Fix abort behaviour on timeouts, now we don't wedge after the first one.
This commit is contained in:
@@ -140,7 +140,6 @@ private:
|
||||
/** saved DMA status */
|
||||
static const unsigned _dma_status_inactive = 0x80000000; // low bits overlap DMA_STATUS_* values
|
||||
static const unsigned _dma_status_waiting = 0x00000000;
|
||||
volatile unsigned _tx_dma_status;
|
||||
volatile unsigned _rx_dma_status;
|
||||
|
||||
/** bus-ownership lock */
|
||||
@@ -151,16 +150,13 @@ private:
|
||||
|
||||
/**
|
||||
* Start the transaction with IO and wait for it to complete.
|
||||
*
|
||||
* @param expect_reply If true, expect a reply from IO.
|
||||
*/
|
||||
int _wait_complete(bool expect_reply, unsigned tx_length);
|
||||
int _wait_complete();
|
||||
|
||||
/**
|
||||
* DMA completion handler.
|
||||
*/
|
||||
static void _dma_callback(DMA_HANDLE handle, uint8_t status, void *arg);
|
||||
void _do_tx_dma_callback(unsigned status);
|
||||
void _do_rx_dma_callback(unsigned status);
|
||||
|
||||
/**
|
||||
@@ -197,7 +193,6 @@ PX4IO_serial::PX4IO_serial() :
|
||||
_tx_dma(nullptr),
|
||||
_rx_dma(nullptr),
|
||||
_rx_length(0),
|
||||
_tx_dma_status(_dma_status_inactive),
|
||||
_rx_dma_status(_dma_status_inactive),
|
||||
_perf_dmasetup(perf_alloc(PC_ELAPSED, "dmasetup")),
|
||||
_perf_timeouts(perf_alloc(PC_COUNT, "timeouts")),
|
||||
@@ -314,8 +309,9 @@ PX4IO_serial::test(unsigned mode)
|
||||
for (unsigned count = 0;; count++) {
|
||||
uint16_t value = count & 0xffff;
|
||||
|
||||
if (set_reg(PX4IO_PAGE_TEST, PX4IO_P_TEST_LED, &value, 1) != OK)
|
||||
return -2;
|
||||
set_reg(PX4IO_PAGE_TEST, PX4IO_P_TEST_LED, &value, 1);
|
||||
/* ignore errors */
|
||||
|
||||
if (count > 100) {
|
||||
perf_print_counter(_perf_dmasetup);
|
||||
perf_print_counter(_perf_txns);
|
||||
@@ -353,7 +349,7 @@ PX4IO_serial::set_reg(uint8_t page, uint8_t offset, const uint16_t *values, unsi
|
||||
/* XXX implement check byte */
|
||||
|
||||
/* start the transaction and wait for it to complete */
|
||||
int result = _wait_complete(false, PKT_SIZE(_dma_buffer));
|
||||
int result = _wait_complete();
|
||||
|
||||
sem_post(&_bus_semaphore);
|
||||
return result;
|
||||
@@ -372,13 +368,14 @@ PX4IO_serial::get_reg(uint8_t page, uint8_t offset, uint16_t *values, unsigned n
|
||||
_dma_buffer.offset = offset;
|
||||
|
||||
/* start the transaction and wait for it to complete */
|
||||
int result = _wait_complete(true, PKT_SIZE(_dma_buffer));
|
||||
int result = _wait_complete();
|
||||
if (result != OK)
|
||||
goto out;
|
||||
|
||||
/* compare the received count with the expected count */
|
||||
if (PKT_COUNT(_dma_buffer) != num_values) {
|
||||
return -EIO;
|
||||
result = -EIO;
|
||||
goto out;
|
||||
} else {
|
||||
/* XXX implement check byte */
|
||||
/* copy back the result */
|
||||
@@ -386,13 +383,12 @@ PX4IO_serial::get_reg(uint8_t page, uint8_t offset, uint16_t *values, unsigned n
|
||||
}
|
||||
out:
|
||||
sem_post(&_bus_semaphore);
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
PX4IO_serial::_wait_complete(bool expect_reply, unsigned tx_length)
|
||||
PX4IO_serial::_wait_complete()
|
||||
{
|
||||
|
||||
/* clear any lingering error status */
|
||||
(void)rSR;
|
||||
(void)rDR;
|
||||
@@ -418,12 +414,10 @@ PX4IO_serial::_wait_complete(bool expect_reply, unsigned tx_length)
|
||||
stm32_dmastart(_rx_dma, _dma_callback, this, false);
|
||||
rCR3 |= USART_CR3_DMAR;
|
||||
|
||||
|
||||
/* start TX DMA - no callback if we also expect a reply */
|
||||
/* DMA setup time ~3µs */
|
||||
_dma_buffer.crc = 0;
|
||||
_dma_buffer.crc = crc_packet(_dma_buffer);
|
||||
_tx_dma_status = _dma_status_waiting;
|
||||
stm32_dmasetup(
|
||||
_tx_dma,
|
||||
PX4IO_SERIAL_BASE + STM32_USART_DR_OFFSET,
|
||||
@@ -435,7 +429,7 @@ PX4IO_serial::_wait_complete(bool expect_reply, unsigned tx_length)
|
||||
DMA_SCR_MSIZE_8BITS |
|
||||
DMA_SCR_PBURST_SINGLE |
|
||||
DMA_SCR_MBURST_SINGLE);
|
||||
stm32_dmastart(_tx_dma, /*expect_reply ? nullptr :*/ _dma_callback, this, false);
|
||||
stm32_dmastart(_tx_dma, nullptr, nullptr, false);
|
||||
rCR3 |= USART_CR3_DMAT;
|
||||
|
||||
perf_end(_perf_dmasetup);
|
||||
@@ -460,11 +454,6 @@ PX4IO_serial::_wait_complete(bool expect_reply, unsigned tx_length)
|
||||
|
||||
if (ret == OK) {
|
||||
/* check for DMA errors */
|
||||
if (_tx_dma_status & DMA_STATUS_TEIF) {
|
||||
lowsyslog("DMA transmit error\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (_rx_dma_status & DMA_STATUS_TEIF) {
|
||||
lowsyslog("DMA receive error\n");
|
||||
ret = -1;
|
||||
@@ -490,7 +479,6 @@ PX4IO_serial::_wait_complete(bool expect_reply, unsigned tx_length)
|
||||
}
|
||||
|
||||
/* reset DMA status */
|
||||
_tx_dma_status = _dma_status_inactive;
|
||||
_rx_dma_status = _dma_status_inactive;
|
||||
|
||||
/* update counters */
|
||||
@@ -507,37 +495,13 @@ PX4IO_serial::_dma_callback(DMA_HANDLE handle, uint8_t status, void *arg)
|
||||
if (arg != nullptr) {
|
||||
PX4IO_serial *ps = reinterpret_cast<PX4IO_serial *>(arg);
|
||||
|
||||
if (handle == ps->_tx_dma) {
|
||||
ps->_do_tx_dma_callback(status);
|
||||
} else if (handle == ps->_rx_dma) {
|
||||
ps->_do_rx_dma_callback(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PX4IO_serial::_do_tx_dma_callback(unsigned status)
|
||||
{
|
||||
/* on completion of a no-reply transmit, wake the sender */
|
||||
if (_tx_dma_status == _dma_status_waiting) {
|
||||
|
||||
/* save TX status */
|
||||
_tx_dma_status = status;
|
||||
|
||||
/* disable UART DMA */
|
||||
rCR3 &= ~USART_CR3_DMAT;
|
||||
|
||||
/* if we aren't going on to expect a reply, complete now */
|
||||
if (_rx_dma_status != _dma_status_waiting)
|
||||
sem_post(&_completion_semaphore);
|
||||
ps->_do_rx_dma_callback(status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PX4IO_serial::_do_rx_dma_callback(unsigned status)
|
||||
{
|
||||
ASSERT(_tx_dma_status != _dma_status_waiting);
|
||||
|
||||
/* on completion of a reply, wake the waiter */
|
||||
if (_rx_dma_status == _dma_status_waiting) {
|
||||
|
||||
@@ -552,7 +516,7 @@ PX4IO_serial::_do_rx_dma_callback(unsigned status)
|
||||
_rx_dma_status = status;
|
||||
|
||||
/* disable UART DMA */
|
||||
rCR3 &= ~USART_CR3_DMAR;
|
||||
rCR3 &= ~(USART_CR3_DMAT | USART_CR3_DMAR);
|
||||
|
||||
/* DMA may have stopped short */
|
||||
_rx_length = sizeof(IOPacket) - stm32_dmaresidual(_rx_dma);
|
||||
@@ -593,6 +557,10 @@ PX4IO_serial::_do_interrupt()
|
||||
*/
|
||||
if (_rx_dma_status == _dma_status_waiting) {
|
||||
_abort_dma();
|
||||
|
||||
/* complete DMA as though in error */
|
||||
_do_rx_dma_callback(DMA_STATUS_TEIF);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -605,7 +573,7 @@ PX4IO_serial::_do_interrupt()
|
||||
if (sr & USART_SR_IDLE) {
|
||||
|
||||
/* if there was DMA transmission still going, this is an error */
|
||||
if (_tx_dma_status == _dma_status_waiting) {
|
||||
if (stm32_dmaresidual(_tx_dma) != 0) {
|
||||
|
||||
/* babble from IO */
|
||||
_abort_dma();
|
||||
@@ -636,13 +604,6 @@ PX4IO_serial::_abort_dma()
|
||||
/* stop DMA */
|
||||
stm32_dmastop(_tx_dma);
|
||||
stm32_dmastop(_rx_dma);
|
||||
|
||||
/* complete DMA as though in error */
|
||||
_do_tx_dma_callback(DMA_STATUS_TEIF);
|
||||
_do_rx_dma_callback(DMA_STATUS_TEIF);
|
||||
|
||||
_tx_dma_status = _dma_status_inactive;
|
||||
_rx_dma_status = _dma_status_inactive;
|
||||
}
|
||||
|
||||
static const uint8_t crc8_tab[256] =
|
||||
|
||||
Reference in New Issue
Block a user