-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
375 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Leka - LekaOS | ||
# Copyright 2022 APF France handicap | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
add_library(CoreDACTouch STATIC) | ||
|
||
target_include_directories(CoreDACTouch | ||
PUBLIC | ||
include | ||
) | ||
|
||
target_sources(CoreDACTouch | ||
PRIVATE | ||
source/CoreDACTouch.cpp | ||
) | ||
|
||
target_link_libraries(CoreDACTouch | ||
mbed-os | ||
CoreI2C | ||
) | ||
|
||
if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") | ||
|
||
leka_unit_tests_sources( | ||
tests/CoreDACTouch_test.cpp | ||
) | ||
|
||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include <array> | ||
|
||
#include "external/MCP4728.h" | ||
#include "interface/drivers/DACTouch.h" | ||
#include "interface/drivers/I2C.h" | ||
|
||
namespace leka { | ||
|
||
class CoreDACTouchMCP4728 : public interface::DACTouch | ||
{ | ||
public: | ||
CoreDACTouchMCP4728(interface::I2C &i2c, uint8_t address) : _i2c(i2c), _address(address) {}; | ||
|
||
void writeToAllInputRegister(std::array<uint8_t, 2> value) final; | ||
void writeToSpecificInputRegister(uint8_t channel, std::array<uint8_t, 2> value) final; | ||
void writeToMemoryRegisterUntilChannelD(uint8_t starting_channel, std::array<uint8_t, 2> value) final; | ||
void writeToSpecificMemoryRegister(uint8_t channel, std::array<uint8_t, 2> value) final; | ||
|
||
void writeVoltageReference(uint8_t voltageReference) final; | ||
void writePowerMode(uint8_t powerMode) final; | ||
void writeGain(uint8_t gain) final; | ||
|
||
void readMemory(std::array<uint8_t, mcp4728::command::readMemory::size> &value) final; | ||
|
||
private: | ||
interface::I2C &_i2c; | ||
uint8_t _address; | ||
}; | ||
|
||
} // namespace leka |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include "cstdint" | ||
|
||
namespace leka::mcp4728 { | ||
|
||
namespace command { | ||
|
||
namespace mask { | ||
inline constexpr auto writeFastMode = uint8_t {0xC0}; | ||
inline constexpr auto writeInputAndMemoryRegisters = uint8_t {0xF8}; | ||
inline constexpr auto writeSelectionBits = uint8_t {0xF0}; | ||
|
||
} // namespace mask | ||
|
||
inline constexpr auto writeAllInputRegister = uint8_t {0x00}; | ||
inline constexpr auto writeSpecificInputRegister = uint8_t {0x40}; | ||
inline constexpr auto writeMemoryRegisterUntilChannelD = uint8_t {0x50}; | ||
inline constexpr auto writeSpecificMemoryRegister = uint8_t {0x60}; | ||
inline constexpr auto writeVoltageReference = uint8_t {0x80}; | ||
inline constexpr auto writePowerMode = uint8_t {0xA0}; | ||
inline constexpr auto writeGain = uint8_t {0xC0}; | ||
|
||
namespace readMemory { | ||
|
||
inline constexpr auto size = uint8_t {24}; | ||
} | ||
|
||
} // namespace command | ||
|
||
namespace channel { | ||
|
||
inline constexpr auto A = uint8_t {0x00}; | ||
inline constexpr auto B = uint8_t {0x01}; | ||
inline constexpr auto C = uint8_t {0x02}; | ||
inline constexpr auto D = uint8_t {0x03}; | ||
|
||
} // namespace channel | ||
|
||
namespace data { | ||
|
||
namespace voltage_reference { | ||
|
||
inline constexpr auto Vdd = uint8_t {0x00}; | ||
namespace internal { | ||
inline constexpr auto channel_A = uint8_t {0x08}; | ||
inline constexpr auto channel_B = uint8_t {0x04}; | ||
inline constexpr auto channel_C = uint8_t {0x02}; | ||
inline constexpr auto channel_D = uint8_t {0x01}; | ||
inline constexpr auto all_channel = uint8_t {0x0f}; | ||
|
||
} // namespace internal | ||
|
||
} // namespace voltage_reference | ||
|
||
namespace power_mode { | ||
|
||
inline constexpr auto normal = uint8_t {0x00}; | ||
|
||
namespace channel_a { | ||
inline constexpr auto normal = uint8_t {0x00}; | ||
inline constexpr auto powerDown1K = uint8_t {0x40}; | ||
inline constexpr auto powerDown100K = uint8_t {0x80}; | ||
inline constexpr auto powerDown500K = uint8_t {0xC0}; | ||
} // namespace channel_a | ||
|
||
namespace channel_b { | ||
inline constexpr auto normal = uint8_t {0x00}; | ||
inline constexpr auto powerDown1K = uint8_t {0x10}; | ||
inline constexpr auto powerDown100K = uint8_t {0x20}; | ||
inline constexpr auto powerDown500K = uint8_t {0x30}; | ||
} // namespace channel_b | ||
|
||
namespace channel_c { | ||
inline constexpr auto normal = uint8_t {0x00}; | ||
inline constexpr auto powerDown1K = uint8_t {0x04}; | ||
inline constexpr auto powerDown100K = uint8_t {0x08}; | ||
inline constexpr auto powerDown500K = uint8_t {0x0C}; | ||
} // namespace channel_c | ||
|
||
namespace channel_d { | ||
inline constexpr auto normal = uint8_t {0x00}; | ||
inline constexpr auto powerDown1K = uint8_t {0x01}; | ||
inline constexpr auto powerDown100K = uint8_t {0x02}; | ||
inline constexpr auto powerDown500K = uint8_t {0x03}; | ||
} // namespace channel_d | ||
|
||
} // namespace power_mode | ||
|
||
namespace gain { | ||
|
||
namespace x1 { | ||
inline constexpr auto all = uint8_t {0x00}; | ||
} | ||
|
||
namespace x2 { | ||
inline constexpr auto channel_A = uint8_t {0x08}; | ||
inline constexpr auto channel_B = uint8_t {0x04}; | ||
inline constexpr auto channel_C = uint8_t {0x02}; | ||
inline constexpr auto channel_D = uint8_t {0x01}; | ||
inline constexpr auto all = uint8_t {0x0f}; | ||
} // namespace x2 | ||
|
||
} // namespace gain | ||
|
||
} // namespace data | ||
|
||
} // namespace leka::mcp4728 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "CoreDACTouch.h" | ||
#include <array> | ||
|
||
#include "MemoryUtils.h" | ||
|
||
using namespace leka; | ||
|
||
void CoreDACTouchMCP4728::writeToAllInputRegister(std::array<uint8_t, 2> value) | ||
{ | ||
auto command = std::array<uint8_t, 2> {}; | ||
command.at(0) = | ||
static_cast<uint8_t>((mcp4728::command::mask::writeFastMode & mcp4728::command::writeAllInputRegister) | | ||
(~mcp4728::command::mask::writeFastMode & value.at(0))); | ||
command.at(1) = value.at(1); | ||
_i2c.write(_address, command.data(), command.size(), false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::writeToSpecificInputRegister(uint8_t channel, std::array<uint8_t, 2> value) | ||
{ | ||
auto command = std::array<uint8_t, 3> {}; | ||
command.at(0) = static_cast<uint8_t>( | ||
(mcp4728::command::mask::writeInputAndMemoryRegisters & mcp4728::command::writeSpecificInputRegister) | | ||
(~mcp4728::command::mask::writeInputAndMemoryRegisters & ((0x03 & channel) << 1))); | ||
std::copy(value.begin(), value.end(), command.begin() + 1); | ||
_i2c.write(_address, command.data(), command.size(), false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::writeToMemoryRegisterUntilChannelD(uint8_t starting_channel, std::array<uint8_t, 2> value) | ||
{ | ||
auto command = std::array<uint8_t, 3> {}; | ||
command.at(0) = static_cast<uint8_t>( | ||
(mcp4728::command::mask::writeInputAndMemoryRegisters & mcp4728::command::writeMemoryRegisterUntilChannelD) | | ||
(~mcp4728::command::mask::writeInputAndMemoryRegisters & ((0x03 & starting_channel) << 1))); | ||
std::copy(value.begin(), value.end(), command.begin() + 1); | ||
_i2c.write(_address, command.data(), command.size(), false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::writeToSpecificMemoryRegister(uint8_t channel, std::array<uint8_t, 2> value) | ||
{ | ||
auto command = std::array<uint8_t, 3> {}; | ||
command.at(0) = static_cast<uint8_t>( | ||
(mcp4728::command::mask::writeInputAndMemoryRegisters & mcp4728::command::writeSpecificMemoryRegister) | | ||
(~mcp4728::command::mask::writeInputAndMemoryRegisters & ((0x03 & channel) << 1))); | ||
std::copy(value.begin(), value.end(), command.begin() + 1); | ||
|
||
_i2c.write(_address, command.data(), command.size(), false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::writeVoltageReference(uint8_t voltageReference) | ||
{ | ||
auto command = | ||
static_cast<uint8_t>((mcp4728::command::mask::writeSelectionBits & mcp4728::command::writeVoltageReference) | | ||
(~mcp4728::command::mask::writeSelectionBits & voltageReference)); | ||
_i2c.write(_address, &command, 1, false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::writePowerMode(uint8_t powerMode) | ||
{ | ||
auto command = std::array<uint8_t, 2> {}; | ||
command.at(0) = | ||
static_cast<uint8_t>((mcp4728::command::mask::writeSelectionBits & mcp4728::command::writePowerMode) | | ||
(~mcp4728::command::mask::writeSelectionBits & (0xF0 & powerMode) >> 4)); | ||
command.at(1) = static_cast<uint8_t>((0x0F & powerMode) << 4); | ||
|
||
_i2c.write(_address, command.data(), command.size(), false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::writeGain(uint8_t gain) | ||
{ | ||
auto command = static_cast<uint8_t>((mcp4728::command::mask::writeSelectionBits & mcp4728::command::writeGain) | | ||
(utils::memory::getLowByte(gain))); | ||
_i2c.write(_address, &command, 1, false); | ||
} | ||
|
||
void CoreDACTouchMCP4728::readMemory(std::array<uint8_t, mcp4728::command::readMemory::size> &value) | ||
{ | ||
_i2c.read(_address, value.data(), value.size(), false); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "CoreDACTouch.h" | ||
|
||
#include "gmock/gmock.h" | ||
#include "gtest/gtest.h" | ||
#include "mocks/leka/CoreI2C.h" | ||
|
||
using namespace leka; | ||
|
||
using ::testing::Args; | ||
using ::testing::DoAll; | ||
using ::testing::ElementsAre; | ||
using ::testing::Return; | ||
using ::testing::SetArrayArgument; | ||
|
||
class CoreDACTouchTest : public ::testing::Test | ||
|
||
{ | ||
protected: | ||
// void SetUp() override {} | ||
// void TearDown() override {} | ||
|
||
const uint8_t i2c_address {0xC0}; | ||
mock::CoreI2C mocki2c; | ||
CoreDACTouchMCP4728 dac {mocki2c, i2c_address}; | ||
}; | ||
|
||
TEST_F(CoreDACTouchTest, initializationDefault) | ||
{ | ||
auto new_dac = CoreDACTouchMCP4728 {mocki2c, i2c_address}; | ||
ASSERT_NE(&new_dac, nullptr); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writeToAllInputRegister) | ||
{ | ||
auto value_to_write = std::array<uint8_t, 2> {0x0F, 0xA8}; | ||
|
||
const auto data = ElementsAre(0x0F, 0xA8); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writeToAllInputRegister(value_to_write); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writeToSpecificInputRegister) | ||
{ | ||
auto value_to_write = std::array<uint8_t, 2> {0x0F, 0xA8}; | ||
|
||
const auto data = ElementsAre(0x46, 0x0F, 0xA8); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writeToSpecificInputRegister(mcp4728::channel::D, value_to_write); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writeToMemoryRegisterUntilChannelD) | ||
{ | ||
auto value_to_write = std::array<uint8_t, 2> {0xFF, 0xAA}; | ||
|
||
const auto data = ElementsAre(0x50, 0xFF, 0xAA); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writeToMemoryRegisterUntilChannelD(mcp4728::channel::A, value_to_write); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writeToSpecificMemoryRegister) | ||
{ | ||
auto value_to_write = std::array<uint8_t, 2> {0xFF, 0xAA}; | ||
|
||
const auto data = ElementsAre(0x62, 0xFF, 0xAA); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writeToSpecificMemoryRegister(mcp4728::channel::B, value_to_write); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, readMemory) | ||
{ | ||
auto data = std::array<uint8_t, 24> {}; | ||
auto expected_data = std::array<uint8_t, 24> {0x01, 0x02, 0x03, 0x04}; | ||
|
||
EXPECT_CALL(mocki2c, read) | ||
.WillOnce(DoAll(SetArrayArgument<1>(begin(expected_data), end(expected_data)), Return(0))); | ||
|
||
dac.readMemory(data); | ||
|
||
ASSERT_EQ(data, expected_data); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writeVoltageReference) | ||
{ | ||
const auto data = ElementsAre(0x80); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writeVoltageReference(mcp4728::data::voltage_reference::Vdd); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writePowerMode) | ||
{ | ||
const auto data = ElementsAre(0xAC, 0x40); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writePowerMode(mcp4728::data::power_mode::channel_a::powerDown500K | | ||
mcp4728::data::power_mode::channel_c::powerDown1K); | ||
} | ||
|
||
TEST_F(CoreDACTouchTest, writeGain) | ||
{ | ||
const auto data = ElementsAre(0xCF); | ||
EXPECT_CALL(mocki2c, write).With(Args<1, 2>(data)); | ||
|
||
dac.writeGain(mcp4728::data::gain::x2::all); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters