File i2c.hpp
File List > include > libhal-util > i2c.hpp
Go to the documentation of this file
// Copyright 2023 Google LLC
//
// 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.
#pragma once
#include <functional>
#include <libhal/error.hpp>
#include <libhal/i2c.hpp>
#include <libhal/units.hpp>
#include "enum.hpp"
#include "math.hpp"
namespace hal {
[[nodiscard]] constexpr auto operator==(const i2c::settings& p_lhs,
const i2c::settings& p_rhs)
{
return equals(p_lhs.clock_rate, p_rhs.clock_rate);
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t> write(
i2c& p_i2c,
hal::byte p_address,
std::span<const hal::byte> p_data_out,
timeout auto p_timeout)
{
return p_i2c.transaction(
p_address, p_data_out, std::span<hal::byte>{}, p_timeout);
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t>
write(i2c& p_i2c, hal::byte p_address, std::span<const hal::byte> p_data_out)
{
return write(p_i2c, p_address, p_data_out, hal::never_timeout());
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t> read(
i2c& p_i2c,
hal::byte p_address,
std::span<hal::byte> p_data_in,
timeout auto p_timeout)
{
return p_i2c.transaction(
p_address, std::span<hal::byte>{}, p_data_in, p_timeout);
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t>
read(i2c& p_i2c, hal::byte p_address, std::span<hal::byte> p_data_in)
{
return read(p_i2c, p_address, p_data_in, hal::never_timeout());
}
template<size_t BytesToRead>
[[nodiscard]] result<std::array<hal::byte, BytesToRead>>
read(i2c& p_i2c, hal::byte p_address, timeout auto p_timeout)
{
std::array<hal::byte, BytesToRead> buffer;
HAL_CHECK(read(p_i2c, p_address, buffer, p_timeout));
return buffer;
}
template<size_t BytesToRead>
[[nodiscard]] result<std::array<hal::byte, BytesToRead>> read(
i2c& p_i2c,
hal::byte p_address)
{
return read<BytesToRead>(p_i2c, p_address, hal::never_timeout());
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t> write_then_read(
i2c& p_i2c,
hal::byte p_address,
std::span<const hal::byte> p_data_out,
std::span<hal::byte> p_data_in,
timeout auto p_timeout = hal::never_timeout())
{
return p_i2c.transaction(p_address, p_data_out, p_data_in, p_timeout);
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t> write_then_read(
i2c& p_i2c,
hal::byte p_address,
std::span<const hal::byte> p_data_out,
std::span<hal::byte> p_data_in)
{
return write_then_read(
p_i2c, p_address, p_data_out, p_data_in, hal::never_timeout());
}
template<size_t BytesToRead>
[[nodiscard]] result<std::array<hal::byte, BytesToRead>> write_then_read(
i2c& p_i2c,
hal::byte p_address,
std::span<const hal::byte> p_data_out,
timeout auto p_timeout)
{
std::array<hal::byte, BytesToRead> buffer;
HAL_CHECK(write_then_read(p_i2c, p_address, p_data_out, buffer, p_timeout));
return buffer;
}
template<size_t BytesToRead>
[[nodiscard]] result<std::array<hal::byte, BytesToRead>> write_then_read(
i2c& p_i2c,
hal::byte p_address,
std::span<const hal::byte> p_data_out)
{
return write_then_read<BytesToRead>(
p_i2c, p_address, p_data_out, hal::never_timeout());
}
[[nodiscard]] inline hal::result<hal::i2c::transaction_t> probe(
i2c& p_i2c,
hal::byte p_address)
{
// p_data_in: empty placeholder for transcation's data_in
std::array<hal::byte, 1> data_in;
// p_timeout: no timeout placeholder for transaction's p_timeout
timeout auto timeout = hal::never_timeout();
return p_i2c.transaction(p_address, std::span<hal::byte>{}, data_in, timeout);
}
enum class i2c_operation
{
write = 0,
read = 1,
};
[[nodiscard]] inline hal::byte to_8_bit_address(
hal::byte p_address,
i2c_operation p_operation) noexcept
{
hal::byte v8bit_address = static_cast<hal::byte>(p_address << 1);
v8bit_address |= hal::value(p_operation);
return v8bit_address;
}
} // namespace hal