diff options
author | px4dev <px4@purgatory.org> | 2013-09-12 23:56:53 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2013-09-12 23:56:53 -0700 |
commit | 19fdaf2009d41885923b586432cb2506a24ca5b3 (patch) | |
tree | e8abf0ea4859b1adf70d007bacb3a6a612d86e53 /src/drivers/device | |
parent | 379623596715d0dce47192329ae9aceabb9ded11 (diff) | |
download | px4-firmware-19fdaf2009d41885923b586432cb2506a24ca5b3.tar.gz px4-firmware-19fdaf2009d41885923b586432cb2506a24ca5b3.tar.bz2 px4-firmware-19fdaf2009d41885923b586432cb2506a24ca5b3.zip |
Use the generic device::SPI locking strategy.
Diffstat (limited to 'src/drivers/device')
-rw-r--r-- | src/drivers/device/spi.cpp | 34 | ||||
-rw-r--r-- | src/drivers/device/spi.h | 11 |
2 files changed, 40 insertions, 5 deletions
diff --git a/src/drivers/device/spi.cpp b/src/drivers/device/spi.cpp index 8fffd60cb..fa6b78d64 100644 --- a/src/drivers/device/spi.cpp +++ b/src/drivers/device/spi.cpp @@ -67,6 +67,7 @@ SPI::SPI(const char *name, CDev(name, devname, irq), // public // protected + locking_mode(LOCK_PREEMPTION), // private _bus(bus), _device(device), @@ -132,13 +133,25 @@ SPI::probe() int SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len) { + irqstate_t state; if ((send == nullptr) && (recv == nullptr)) return -EINVAL; - /* do common setup */ - if (!up_interrupt_context()) - SPI_LOCK(_dev, true); + /* lock the bus as required */ + if (!up_interrupt_context()) { + switch (locking_mode) { + default: + case LOCK_PREEMPTION: + state = irqsave(); + break; + case LOCK_THREADS: + SPI_LOCK(_dev, true); + break; + case LOCK_NONE: + break; + } + } SPI_SETFREQUENCY(_dev, _frequency); SPI_SETMODE(_dev, _mode); @@ -151,8 +164,19 @@ SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len) /* and clean up */ SPI_SELECT(_dev, _device, false); - if (!up_interrupt_context()) - SPI_LOCK(_dev, false); + if (!up_interrupt_context()) { + switch (locking_mode) { + default: + case LOCK_PREEMPTION: + irqrestore(state); + break; + case LOCK_THREADS: + SPI_LOCK(_dev, false); + break; + case LOCK_NONE: + break; + } + } return OK; } diff --git a/src/drivers/device/spi.h b/src/drivers/device/spi.h index e0122372a..9103dca2e 100644 --- a/src/drivers/device/spi.h +++ b/src/drivers/device/spi.h @@ -101,6 +101,17 @@ protected: */ int transfer(uint8_t *send, uint8_t *recv, unsigned len); + /** + * Locking modes supported by the driver. + */ + enum LockMode { + LOCK_PREEMPTION, /**< the default; lock against all forms of preemption. */ + LOCK_THREADS, /**< lock only against other threads, using SPI_LOCK */ + LOCK_NONE /**< perform no locking, only safe if the bus is entirely private */ + }; + + LockMode locking_mode; /**< selected locking mode */ + private: int _bus; enum spi_dev_e _device; |