diff options
author | Bertrand SIMONNET <bsimonnet@google.com> | 2016-03-07 14:28:38 -0800 |
---|---|---|
committer | Bertrand SIMONNET <bsimonnet@google.com> | 2016-03-08 16:06:01 -0800 |
commit | c46c8c208575510d2d227d40bdd0efa5fcbb5b42 (patch) | |
tree | a90063783d495c78e24d7c0346e28b34399c2e6f | |
parent | 33cd8fd3f2e0ec4db8f21f389671c766ae569b2e (diff) | |
download | peripheralmanager-c46c8c208575510d2d227d40bdd0efa5fcbb5b42.tar.gz |
Expose SPI in the developer interface.
This CL defines and implements the C API used by the developer to access
the SPI interface.
Bug: 27530022
Change-Id: Id3380191fa8d81ff749e3db9d208dff25deed3fb
-rw-r--r-- | client/Android.mk | 5 | ||||
-rw-r--r-- | client/peripheral_manager_client_impl.cc | 9 | ||||
-rw-r--r-- | client/peripheral_manager_client_impl.h | 4 | ||||
-rw-r--r-- | client/spi_device_impl.cc | 73 | ||||
-rw-r--r-- | client/spi_device_impl.h | 50 | ||||
-rw-r--r-- | client/wrapper.cc | 57 | ||||
-rw-r--r-- | include/peripheralmanager/peripheral_manager_client.h | 4 | ||||
-rw-r--r-- | include/peripheralmanager/spi_device.h | 112 |
8 files changed, 312 insertions, 2 deletions
diff --git a/client/Android.mk b/client/Android.mk index 9b92b9c..fc47b21 100644 --- a/client/Android.mk +++ b/client/Android.mk @@ -41,9 +41,10 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include LOCAL_SHARED_LIBRARIES := $(libperipheralman_CommonSharedLibraries) LOCAL_STATIC_LIBRARIES := libperipheralman_binder LOCAL_SRC_FILES := \ - wrapper.cc \ - peripheral_manager_client_impl.cc \ gpio_impl.cc \ + peripheral_manager_client_impl.cc \ + spi_device_impl.cc \ + wrapper.cc \ include $(BUILD_SHARED_LIBRARY) diff --git a/client/peripheral_manager_client_impl.cc b/client/peripheral_manager_client_impl.cc index 8be4346..2d392e2 100644 --- a/client/peripheral_manager_client_impl.cc +++ b/client/peripheral_manager_client_impl.cc @@ -39,3 +39,12 @@ int PeripheralManagerClientImpl::OpenGpio(const std::string& name, } return status.serviceSpecificErrorCode(); } + +int PeripheralManagerClientImpl::OpenSpiDevice( + const std::string& name, std::unique_ptr<SpiDeviceImpl>* device) { + Status status = client_->OpenSpiDevice(name); + if (status.serviceSpecificErrorCode() == PERIPHERAL_IO_OK) { + device->reset(new SpiDeviceImpl(name, client_)); + } + return status.serviceSpecificErrorCode(); +} diff --git a/client/peripheral_manager_client_impl.h b/client/peripheral_manager_client_impl.h index e331c7f..eb88160 100644 --- a/client/peripheral_manager_client_impl.h +++ b/client/peripheral_manager_client_impl.h @@ -21,6 +21,7 @@ #include <utils/StrongPointer.h> #include "gpio_impl.h" +#include "spi_device_impl.h" class PeripheralManagerClientImpl { public: @@ -30,6 +31,9 @@ class PeripheralManagerClientImpl { int OpenGpio(const std::string& name, std::unique_ptr<GpioImpl>* gpio); + int OpenSpiDevice(const std::string& name, + std::unique_ptr<SpiDeviceImpl>* device); + private: android::sp<android::os::IPeripheralManagerClient> client_; android::sp<android::IBinder> lifeline_; diff --git a/client/spi_device_impl.cc b/client/spi_device_impl.cc new file mode 100644 index 0000000..ff82f49 --- /dev/null +++ b/client/spi_device_impl.cc @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <vector> + +#include <peripheralmanager/spi_device.h> + +#include "spi_device_impl.h" + +using android::sp; +using android::os::IPeripheralManagerClient; + +SpiDeviceImpl::SpiDeviceImpl(const std::string& name, + sp<IPeripheralManagerClient> client) + : name_(name), client_(client) {} + +SpiDeviceImpl::~SpiDeviceImpl() {} + +int SpiDeviceImpl::WriteByte(uint8_t byte) { + return client_->SpiDeviceWriteByte(name_, byte).serviceSpecificErrorCode(); +} + +int SpiDeviceImpl::WriteBuffer(const uint8_t* data, size_t len) { + std::vector<uint8_t> v(data, data + len); + return client_->SpiDeviceWriteBuffer(name_, v).serviceSpecificErrorCode(); +} + +int SpiDeviceImpl::Transfer(const uint8_t* tx_data, + uint8_t* rx_data, + size_t len) { + std::unique_ptr<std::vector<uint8_t>> sent(nullptr); + std::unique_ptr<std::vector<uint8_t>> received( + rx_data ? new std::vector<uint8_t> : nullptr); + + if (tx_data != nullptr) + sent.reset(new std::vector<uint8_t>(tx_data, tx_data + len)); + + return client_->SpiDeviceTransfer(name_, sent, &received, len) + .serviceSpecificErrorCode(); +} + +int SpiDeviceImpl::SetFrequency(uint32_t freq_hz) { + return client_->SpiDeviceSetFrequency(name_, freq_hz) + .serviceSpecificErrorCode(); +} + +int SpiDeviceImpl::SetMode(int mode) { + return client_->SpiDeviceSetMode(name_, mode).serviceSpecificErrorCode(); +} + +int SpiDeviceImpl::SetBitJustification(int justification) { + return client_ + ->SpiDeviceSetBitJustification(name_, justification == SPI_LSB_FIRST) + .serviceSpecificErrorCode(); +} + +int SpiDeviceImpl::SetBitsPerWord(size_t bits_per_word) { + return client_->SpiDeviceSetBitsPerWord(name_, bits_per_word) + .serviceSpecificErrorCode(); +} diff --git a/client/spi_device_impl.h b/client/spi_device_impl.h new file mode 100644 index 0000000..e5beb1a --- /dev/null +++ b/client/spi_device_impl.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_IMPL_H_ +#define SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_IMPL_H_ + +#include <string> + +#include <android/os/IPeripheralManagerClient.h> +#include <utils/StrongPointer.h> + +class SpiDeviceImpl { + public: + SpiDeviceImpl(const std::string& bus, + android::sp<android::os::IPeripheralManagerClient> client); + ~SpiDeviceImpl(); + + int WriteByte(uint8_t byte); + + int WriteBuffer(const uint8_t* data, size_t len); + + int Transfer(const uint8_t* tx_data, uint8_t* rx_data, size_t len); + + int SetFrequency(uint32_t speed_hz); + + int SetMode(int mode); + + int SetBitJustification(int bit_justification); + + int SetBitsPerWord(uint32_t bits_per_word); + + private: + std::string name_; + android::sp<android::os::IPeripheralManagerClient> client_; +}; + +#endif // SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_IMPL_H_ diff --git a/client/wrapper.cc b/client/wrapper.cc index c4c5202..03f7e02 100644 --- a/client/wrapper.cc +++ b/client/wrapper.cc @@ -29,6 +29,10 @@ struct BGpio { GpioImpl* impl; }; +struct BSpiDevice { + SpiDeviceImpl* impl; +}; + BPeripheralManagerClient* BPeripheralManagerClient_new() { std::unique_ptr<PeripheralManagerClientImpl> impl( new PeripheralManagerClientImpl); @@ -95,3 +99,56 @@ void BGpio_delete(BGpio* gpio) { delete gpio->impl; delete gpio; } + +int BPeripheralManagerClient_openSpiDevice( + const BPeripheralManagerClient* client, + const char* name, + BSpiDevice** dev) { + std::unique_ptr<SpiDeviceImpl> impl; + client->impl->OpenSpiDevice(name, &impl); + + *dev = new BSpiDevice{impl.release()}; + return 0; +} + +int BSpiDevice_writeByte(const BSpiDevice* device, uint8_t val) { + return device->impl->WriteByte(val); +} + +int BSpiDevice_writeBuffer(const BSpiDevice* device, + const void* data, + size_t len) { + return device->impl->WriteBuffer(static_cast<const uint8_t*>(data), len); +} + +int BSpiDevice_transfer(const BSpiDevice* device, + const void* tx_data, + void* rx_data, + size_t len) { + return device->impl->Transfer(static_cast<const uint8_t*>(tx_data), + static_cast<uint8_t*>(rx_data), + len); +} + +int BSpiDevice_setFrequency(const BSpiDevice* device, uint32_t freq_hz) { + return device->impl->SetFrequency(freq_hz); +} + +int BSpiDevice_setMode(const BSpiDevice* device, int mode) { + return device->impl->SetMode(mode); +} + +int BSpiDevice_setBitJustification(const BSpiDevice* device, + int bit_justification) { + return device->impl->SetBitJustification(bit_justification); +} + +int BSpiDevice_setBitsPerWord(const BSpiDevice* device, + uint32_t bits_per_word) { + return device->impl->SetBitsPerWord(bits_per_word); +} + +void BSpiDevice_delete(BSpiDevice* device) { + delete device->impl; + delete device; +} diff --git a/include/peripheralmanager/peripheral_manager_client.h b/include/peripheralmanager/peripheral_manager_client.h index 48273ca..b394fb8 100644 --- a/include/peripheralmanager/peripheral_manager_client.h +++ b/include/peripheralmanager/peripheral_manager_client.h @@ -21,6 +21,7 @@ #include "peripheralmanager/errors.h" #include "peripheralmanager/gpio.h" +#include "peripheralmanager/spi_device.h" __BEGIN_DECLS @@ -66,6 +67,9 @@ int BPeripheralManagerClient_openGpio(const BPeripheralManagerClient* client, const char* name, BGpio** gpio); +int BPeripheralManagerClient_openSpiDevice( + const BPeripheralManagerClient* client, const char* name, BSpiDevice** dev); + // Creates a new client. // // Returns: diff --git a/include/peripheralmanager/spi_device.h b/include/peripheralmanager/spi_device.h new file mode 100644 index 0000000..3c65d28 --- /dev/null +++ b/include/peripheralmanager/spi_device.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ + +#include <sys/cdefs.h> +#include <sys/types.h> + +__BEGIN_DECLS + +/// @defgroup Spi Spi device interface +/// @brief Functions to control an SPI device. +/// +/// These functions can be used to control an SPI device. +/// @{ + +/// Endianness. +enum { + SPI_LSB_FIRST, /**< Least significant bits first */ + SPI_MSB_FIRST /**< Most significant bits first */ +}; + +/// SPI phase modes. +enum { + SPI_CPHA = 0x01, /**< Clock phase */ + SPI_CPOL = 0x02 /**< Clock polarity */ +}; + +/// SPI modes (similar to the Linux kernel's modes). +enum { + SPI_MODE0 = 0, /**< CPHA=0, CPOL=0 */ + SPI_MODE1 = SPI_CPHA, /**< CPHA=1, CPOL=0 */ + SPI_MODE2 = SPI_CPOL, /**< CPHA=0, CPOL=1 */ + SPI_MODE3 = SPI_CPHA + SPI_CPOL /**< CPHA=1, CPOL=1 */ +}; + +typedef struct BSpiDevice BSpiDevice; + +/// Writes a byte to the device. +/// @param device Pointer to the BSpiDevice struct. +/// @param val Value to write. +/// @return Error code. +int BSpiDevice_writeByte(const BSpiDevice* device, uint8_t val); + +/// Writes a buffer to the device. +/// @param device Pointer to the BSpiDevice struct. +/// @param data Buffer to write. +/// @param len Length of the buffer. +/// @return Error code. +int BSpiDevice_writeBuffer(const BSpiDevice* device, + const void* data, + size_t len); + +/// Transfer data to the device. +/// @param device Pointer to the BSpiDevice struct. +/// @param tx_data Buffer to write. If NULL, no data will be written. +/// @param rx_data Buffer to read data in. If NULL, no data will be read. +/// @param len Length of the buffers. +/// @return Error code. +int BSpiDevice_transfer(const BSpiDevice* device, + const void* tx_data, + void* rx_data, + size_t len); + +/// Sets the frequency in Hertz. +/// @param device Pointer to the BSpiDevice struct. +/// @param freq_hz Frequency to set. +/// @return Error code. +int BSpiDevice_setFrequency(const BSpiDevice* device, uint32_t freq_hz); + +/// Sets the SPI mode. +/// @param device Pointer to the BSpiDevice struct. +/// @param mode Mode to use. One of SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3. +/// @return Error code. +int BSpiDevice_setMode(const BSpiDevice* device, int mode); + +/// Sets the bit justification. +/// @param device Pointer to the BSpiDevice struct. +/// @param bit_justification One of SPI_LSB_FIRST OR SPI_MSB_FIRST. +/// @return Error code. +int BSpiDevice_setBitJustification(const BSpiDevice* device, + int bit_justification); + +/// Sets the number of bits per words. +/// @param device Pointer to the BSpiDevice struct. +/// @param bits_per_word Number of bits per word. +/// @return Error code. +int BSpiDevice_setBitsPerWord(const BSpiDevice* device, uint32_t bits_per_word); + +/// Destroys a BSpiDevice struct. +/// @param device Pointer to the BSpiDevice struct. +void BSpiDevice_delete(BSpiDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ |