From 2abf0833508ecfb74e44c3f00e6b6cdf8081019b Mon Sep 17 00:00:00 2001 From: Bertrand SIMONNET Date: Wed, 30 Mar 2016 14:27:00 -0700 Subject: Allow setting the SPI message delay. This CL adds an interface to set the delay to wait between two SPI messages. Bug: 27923916 Change-Id: Idb1fa208b974d489414d63d67ad5fa702e8b03e4 --- daemon/peripheral_manager_client.cc | 16 ++++++++++++++++ daemon/peripheral_manager_client.h | 3 +++ daemon/spi_driver.h | 1 + daemon/spi_driver_spidev.cc | 10 +++++++++- daemon/spi_driver_spidev.h | 2 ++ daemon/spi_manager.h | 4 ++++ 6 files changed, 35 insertions(+), 1 deletion(-) (limited to 'daemon') diff --git a/daemon/peripheral_manager_client.cc b/daemon/peripheral_manager_client.cc index e821288..d279a9f 100644 --- a/daemon/peripheral_manager_client.cc +++ b/daemon/peripheral_manager_client.cc @@ -235,6 +235,22 @@ Status PeripheralManagerClient::SpiDeviceSetBitsPerWord(const std::string& name, return Status::fromServiceSpecificError(EREMOTEIO); } +Status PeripheralManagerClient::SpiDeviceSetDelay(const std::string& name, + int delay_usecs) { + if (!spi_devices_.count(name)) + return Status::fromServiceSpecificError(EPERM); + + // |delay_usecs| must be positive and fit in an unsigned 16 bit. + if (delay_usecs < 0 || delay_usecs > INT16_MAX) + return Status::fromServiceSpecificError(EINVAL); + + if (spi_devices_.find(name)->second->SetDelay( + static_cast(delay_usecs))) + return Status::ok(); + + return Status::fromServiceSpecificError(EREMOTEIO); +} + Status PeripheralManagerClient::ListLeds(std::vector* leds) { *leds = LedManager::GetLedManager()->GetLeds(); return Status::ok(); diff --git a/daemon/peripheral_manager_client.h b/daemon/peripheral_manager_client.h index 99f3999..23d15c7 100644 --- a/daemon/peripheral_manager_client.h +++ b/daemon/peripheral_manager_client.h @@ -92,6 +92,9 @@ class PeripheralManagerClient : public BnPeripheralManagerClient { virtual Status SpiDeviceSetBitsPerWord(const std::string& name, int nbits) override; + virtual Status SpiDeviceSetDelay(const std::string& name, + int delay_usecs) override; + virtual Status ListLeds(std::vector* leds) override; virtual Status OpenLed(const std::string& name) override; diff --git a/daemon/spi_driver.h b/daemon/spi_driver.h index 3f04e36..700a169 100644 --- a/daemon/spi_driver.h +++ b/daemon/spi_driver.h @@ -40,6 +40,7 @@ class SpiDriverInterface { virtual bool SetMode(SpiMode mode) = 0; virtual bool SetBitJustification(bool lsb_first) = 0; virtual bool SetBitsPerWord(uint8_t bits_per_word) = 0; + virtual bool SetDelay(uint16_t delay_usecs) = 0; }; class SpiDriverInfoBase { diff --git a/daemon/spi_driver_spidev.cc b/daemon/spi_driver_spidev.cc index 9a30b21..2ac4844 100644 --- a/daemon/spi_driver_spidev.cc +++ b/daemon/spi_driver_spidev.cc @@ -71,6 +71,9 @@ bool SpiDriverSpiDev::Init(uint32_t bus_id, uint32_t cs) { } speed_hz_ = max_freq; + // Default to 0 microseconds delay between transfers. + delay_usecs_ = 0; + // Default to 8 bits per word. bits_per_word_ = 8; @@ -85,7 +88,7 @@ bool SpiDriverSpiDev::Transfer(const void* tx_data, void* rx_data, size_t len) { msg.rx_buf = (unsigned long)rx_data; msg.speed_hz = speed_hz_; msg.bits_per_word = bits_per_word_; - msg.delay_usecs = 0; + msg.delay_usecs = delay_usecs_; msg.len = len; if (char_interface_->Ioctl(fd_, SPI_IOC_MESSAGE(1), &msg) < 0) { @@ -161,4 +164,9 @@ bool SpiDriverSpiDev::SetBitsPerWord(uint8_t bits_per_word) { return true; } +bool SpiDriverSpiDev::SetDelay(uint16_t delay_usecs) { + delay_usecs_ = delay_usecs; + return true; +} + } // namespace android diff --git a/daemon/spi_driver_spidev.h b/daemon/spi_driver_spidev.h index 1214e2b..f573fb0 100644 --- a/daemon/spi_driver_spidev.h +++ b/daemon/spi_driver_spidev.h @@ -41,6 +41,7 @@ class SpiDriverSpiDev : public SpiDriverInterface { bool SetMode(SpiMode mode) override; bool SetBitJustification(bool lsb_first) override; bool SetBitsPerWord(uint8_t bits_per_word) override; + bool SetDelay(uint16_t delay_usecs) override; private: bool GetMaxFrequency(uint32_t* max_freq); @@ -48,6 +49,7 @@ class SpiDriverSpiDev : public SpiDriverInterface { int fd_; uint32_t bits_per_word_; uint32_t speed_hz_; + uint16_t delay_usecs_; std::unique_ptr char_interface_; // Used for unit testing and is null in production. diff --git a/daemon/spi_manager.h b/daemon/spi_manager.h index 80c9d64..deec13c 100644 --- a/daemon/spi_manager.h +++ b/daemon/spi_manager.h @@ -76,6 +76,10 @@ class SpiDevice { return bus_->driver_->SetBitsPerWord(bits_per_word); } + bool SetDelay(uint16_t delay_usecs) { + return bus_->driver_->SetDelay(delay_usecs); + } + private: SpiDevBus* bus_; }; -- cgit v1.2.3