diff options
author | px4dev <px4@purgatory.org> | 2013-07-05 17:39:28 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2013-07-05 17:39:28 -0700 |
commit | 6c5a15da9b611d52a70af0ffd3d97bf757b974f5 (patch) | |
tree | c66d4deb64d27919aa1da8898f236690395eeeea /src/drivers/px4io/interface_serial.cpp | |
parent | 50cae347b41b66d236c26ea0dfdeb99b65824ebb (diff) | |
download | px4-firmware-6c5a15da9b611d52a70af0ffd3d97bf757b974f5.tar.gz px4-firmware-6c5a15da9b611d52a70af0ffd3d97bf757b974f5.tar.bz2 px4-firmware-6c5a15da9b611d52a70af0ffd3d97bf757b974f5.zip |
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.
Diffstat (limited to 'src/drivers/px4io/interface_serial.cpp')
-rw-r--r-- | src/drivers/px4io/interface_serial.cpp | 75 |
1 files changed, 18 insertions, 57 deletions
diff --git a/src/drivers/px4io/interface_serial.cpp b/src/drivers/px4io/interface_serial.cpp index 814f66ea4..1af64379b 100644 --- a/src/drivers/px4io/interface_serial.cpp +++ b/src/drivers/px4io/interface_serial.cpp @@ -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] = |