aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/px4io/interface_serial.cpp
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2013-07-05 17:39:28 -0700
committerpx4dev <px4@purgatory.org>2013-07-05 17:39:28 -0700
commit6c5a15da9b611d52a70af0ffd3d97bf757b974f5 (patch)
treec66d4deb64d27919aa1da8898f236690395eeeea /src/drivers/px4io/interface_serial.cpp
parent50cae347b41b66d236c26ea0dfdeb99b65824ebb (diff)
downloadpx4-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.cpp75
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] =