aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2012-08-25 13:14:01 -0700
committerpx4dev <px4@purgatory.org>2012-08-25 13:15:23 -0700
commite5e2d7216c215acd8d59d76abfd55de5ea625019 (patch)
treec6c008b96bb398c8fd90b83c23f607790f00cf81
parent380d1364830fb495021d9d07e6280c18386b8668 (diff)
downloadpx4-firmware-e5e2d7216c215acd8d59d76abfd55de5ea625019.tar.gz
px4-firmware-e5e2d7216c215acd8d59d76abfd55de5ea625019.tar.bz2
px4-firmware-e5e2d7216c215acd8d59d76abfd55de5ea625019.zip
Make it non-fatal to perform SPI transfers from interrupt context.
-rw-r--r--apps/drivers/device/spi.cpp14
-rw-r--r--apps/drivers/device/spi.h6
2 files changed, 18 insertions, 2 deletions
diff --git a/apps/drivers/device/spi.cpp b/apps/drivers/device/spi.cpp
index 3ccdaae36..f56f5433a 100644
--- a/apps/drivers/device/spi.cpp
+++ b/apps/drivers/device/spi.cpp
@@ -35,8 +35,16 @@
* @file Base class for devices connected via SPI.
*
* @todo Work out if caching the mode/frequency would save any time.
+ *
+ * @todo A separate bus/device abstraction would allow for mixed interrupt-mode
+ * and non-interrupt-mode clients to arbitrate for the bus. As things stand,
+ * a bus shared between clients of both kinds is vulnerable to races between
+ * the two, where an interrupt-mode client will ignore the lock held by the
+ * non-interrupt-mode client.
*/
+#include <nuttx/arch.h>
+
#include "spi.h"
#ifndef CONFIG_SPI_EXCHANGE
@@ -124,7 +132,8 @@ SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len)
return -EINVAL;
/* do common setup */
- SPI_LOCK(_dev, true);
+ if (!up_interrupt_context())
+ SPI_LOCK(_dev, true);
SPI_SETFREQUENCY(_dev, _frequency);
SPI_SETMODE(_dev, _mode);
SPI_SETBITS(_dev, 8);
@@ -135,7 +144,8 @@ SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len)
/* and clean up */
SPI_SELECT(_dev, _device, false);
- SPI_LOCK(_dev, false);
+ if (!up_interrupt_context())
+ SPI_LOCK(_dev, false);
return OK;
}
diff --git a/apps/drivers/device/spi.h b/apps/drivers/device/spi.h
index ef382b03c..b2a111562 100644
--- a/apps/drivers/device/spi.h
+++ b/apps/drivers/device/spi.h
@@ -81,6 +81,12 @@ protected:
/**
* Perform a SPI transfer.
*
+ * If called from interrupt context, this interface does not lock
+ * the bus and may interfere with non-interrupt-context callers.
+ *
+ * Clients in a mixed interrupt/non-interrupt configuration must
+ * ensure appropriate interlocking.
+ *
* At least one of send or recv must be non-null.
*
* @param send Bytes to send to the device, or nullptr if