blob: cc8a3fba3b994ecfda787a99b196771cd42fa1fa [file] [log] [blame]
/*
* 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);
}