| /* |
| * 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 <memory> |
| |
| #include <binderwrapper/binder_test_base.h> |
| #include <binderwrapper/stub_binder_wrapper.h> |
| #include <gtest/gtest.h> |
| |
| #include "fake_devices.h" |
| #include "peripheral_manager.h" |
| #include "peripheralmanager/peripheral_manager_client.h" |
| #include "peripheralmanager/spi_device.h" |
| #include "spi_driver_spidev.h" |
| |
| using android::CharDeviceFactory; |
| using android::FakeDeviceFactory; |
| using android::SpiDriverInfo; |
| using android::SpiDriverInfoBase; |
| using android::SpiDriverSpiDev; |
| using android::SpiManager; |
| using android::PeripheralManager; |
| |
| // Base class used to test the Spi C API. |
| // As we rely on static, global managers, we cannot run this tests in parallel. |
| // Please use -j1 when running theses tests or you may see false negatives. |
| class SpiTest : public android::BinderTestBase { |
| public: |
| void SetUp() { |
| android::sp<PeripheralManager> pman(new PeripheralManager); |
| android::String8 interface_desc(pman->getInterfaceDescriptor()); |
| binder_wrapper()->SetBinderForService(interface_desc.string(), pman); |
| |
| SpiManager* man = SpiManager::GetSpiManager(); |
| |
| man->GetSpiDevBuses(); |
| man->RegisterDriver(std::unique_ptr<SpiDriverInfoBase>( |
| new SpiDriverInfo<SpiDriverSpiDev, CharDeviceFactory*>( |
| &device_factory_))); |
| |
| man->RegisterSpiDevBus("SPI_A", 1, 0); |
| man->RegisterSpiDevBus("SPI_B", 1, 1); |
| } |
| |
| void TearDown() { SpiManager::ResetSpiManager(); } |
| |
| private: |
| FakeDeviceFactory device_factory_; |
| }; |
| |
| // Test that we can list the available devices. |
| TEST_F(SpiTest, ListSpiDevices) { |
| BPeripheralManagerClient* client = BPeripheralManagerClient_new(); |
| |
| int ndev = -1; |
| char** devices = BPeripheralManagerClient_listSpiBuses(client, &ndev); |
| |
| ASSERT_EQ(2, ndev); |
| EXPECT_EQ("SPI_A", std::string(devices[0])); |
| EXPECT_EQ("SPI_B", std::string(devices[1])); |
| |
| for (int i = 0; i < ndev; i++) { |
| free(devices[i]); |
| } |
| free(devices); |
| |
| BPeripheralManagerClient_delete(client); |
| } |
| |
| // Test that we can open a device and use the basic functions. |
| TEST_F(SpiTest, OpenSpiDevice) { |
| BPeripheralManagerClient* client = BPeripheralManagerClient_new(); |
| |
| BSpiDevice* device = nullptr; |
| ASSERT_EQ(0, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device)); |
| ASSERT_NE(nullptr, device); |
| |
| EXPECT_EQ(0, BSpiDevice_writeByte(device, 0x10)); |
| |
| std::vector<uint8_t> v = {1, 2, 3, 4}; |
| EXPECT_EQ(0, BSpiDevice_writeBuffer(device, v.data(), v.size())); |
| |
| BSpiDevice_delete(device); |
| BPeripheralManagerClient_delete(client); |
| } |
| |
| // Test that the transfer function behave correctly. |
| TEST_F(SpiTest, Transfer) { |
| BPeripheralManagerClient* client = BPeripheralManagerClient_new(); |
| |
| BSpiDevice* device = nullptr; |
| ASSERT_EQ(0, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device)); |
| ASSERT_NE(nullptr, device); |
| |
| // Passing an empty return pointer is valid. |
| std::vector<uint8_t> v = {0, 0, 0, 0}; |
| uint8_t received[4]; |
| EXPECT_EQ(0, BSpiDevice_transfer(device, v.data(), nullptr, v.size())); |
| |
| // Passing an empty send pointer is invalid. |
| EXPECT_EQ(EINVAL, BSpiDevice_transfer(device, nullptr, &received, 4)); |
| |
| BSpiDevice_delete(device); |
| BPeripheralManagerClient_delete(client); |
| } |
| |
| // Test that we can configure the device correctly and that we fail cleanly if |
| // the configuration is incorrect. |
| TEST_F(SpiTest, SetConfiguration) { |
| BPeripheralManagerClient* client = BPeripheralManagerClient_new(); |
| |
| BSpiDevice* device = nullptr; |
| ASSERT_EQ(0, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device)); |
| ASSERT_NE(nullptr, device); |
| |
| // We can set the mode and detect an invalid mode. |
| EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE0)); |
| EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE1)); |
| EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE2)); |
| EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE3)); |
| EXPECT_EQ(EINVAL, BSpiDevice_setMode(device, SPI_MODE3 + 1)); |
| |
| // We can set the bit justification and detect an invalid justification. |
| EXPECT_EQ(0, BSpiDevice_setBitJustification(device, SPI_LSB_FIRST)); |
| EXPECT_EQ(0, BSpiDevice_setBitJustification(device, SPI_MSB_FIRST)); |
| EXPECT_EQ(EINVAL, BSpiDevice_setBitJustification(device, SPI_MSB_FIRST + 1)); |
| |
| // We can set the frequency. |
| EXPECT_EQ(0, BSpiDevice_setFrequency(device, 100000)); |
| |
| // We can set the number of bits per word. |
| EXPECT_EQ(0, BSpiDevice_setBitsPerWord(device, 16)); |
| |
| // We can set the delay between transfers. |
| EXPECT_EQ(0, BSpiDevice_setDelay(device, 100)); |
| |
| BSpiDevice_delete(device); |
| BPeripheralManagerClient_delete(client); |
| } |
| |
| // Test that we fail when trying to open the same device twice. |
| TEST_F(SpiTest, CantOpenDeviceTwice) { |
| BPeripheralManagerClient* client = BPeripheralManagerClient_new(); |
| |
| BSpiDevice* device1 = nullptr; |
| BSpiDevice* device2 = nullptr; |
| BSpiDevice* device3 = nullptr; |
| |
| // Can open SPI_A once. |
| ASSERT_EQ(0, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device1)); |
| ASSERT_NE(nullptr, device1); |
| |
| // The device can't be opened a second time because it is busy. |
| ASSERT_EQ(EBUSY, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device2)); |
| ASSERT_EQ(nullptr, device2); |
| |
| // Can open another device. |
| ASSERT_EQ(0, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_B", &device3)); |
| |
| // Once released, we can re-open the device. |
| BSpiDevice_delete(device1); |
| ASSERT_EQ(0, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device2)); |
| |
| BSpiDevice_delete(device2); |
| BSpiDevice_delete(device3); |
| BPeripheralManagerClient_delete(client); |
| } |
| |
| // Test that we fail when trying to open an unknown device. |
| TEST_F(SpiTest, CantOpenUnknownDevice) { |
| BPeripheralManagerClient* client = BPeripheralManagerClient_new(); |
| |
| BSpiDevice* device = nullptr; |
| ASSERT_EQ( |
| ENODEV, |
| BPeripheralManagerClient_openSpiDevice(client, "SPI_UNKOWN", &device)); |
| ASSERT_EQ(nullptr, device); |
| |
| BPeripheralManagerClient_delete(client); |
| } |