Create Common/I2C

Currently this is a copy of the Wii Remote I2CBus, and is unused. That will change in later commits.
This commit is contained in:
Pokechu22 2022-08-30 12:42:45 -07:00
parent 1ef7d90b68
commit 5f9648417c
4 changed files with 132 additions and 0 deletions

View file

@ -79,6 +79,8 @@ add_library(common
HostDisassembler.h
HttpRequest.cpp
HttpRequest.h
I2C.cpp
I2C.h
Image.cpp
Image.h
IniFile.cpp

View file

@ -0,0 +1,53 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Common/I2C.h"
#include <algorithm>
namespace Common
{
void I2CBus::AddSlave(I2CSlave* slave)
{
m_slaves.emplace_back(slave);
}
void I2CBus::RemoveSlave(I2CSlave* slave)
{
m_slaves.erase(std::remove(m_slaves.begin(), m_slaves.end(), slave), m_slaves.end());
}
void I2CBus::Reset()
{
m_slaves.clear();
}
int I2CBus::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
{
for (auto& slave : m_slaves)
{
auto const bytes_read = slave->BusRead(slave_addr, addr, count, data_out);
// A slave responded, we are done.
if (bytes_read)
return bytes_read;
}
return 0;
}
int I2CBus::BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in)
{
for (auto& slave : m_slaves)
{
auto const bytes_written = slave->BusWrite(slave_addr, addr, count, data_in);
// A slave responded, we are done.
if (bytes_written)
return bytes_written;
}
return 0;
}
}; // namespace Common

75
Source/Core/Common/I2C.h Normal file
View file

@ -0,0 +1,75 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <algorithm>
#include <vector>
#include "Common/CommonTypes.h"
namespace Common
{
class I2CBus;
class I2CSlave
{
friend I2CBus;
protected:
virtual ~I2CSlave() = default;
virtual int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out) = 0;
virtual int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) = 0;
template <typename T>
static int RawRead(T* reg_data, u8 addr, int count, u8* data_out)
{
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
static_assert(0x100 == sizeof(T));
// TODO: addr wraps around after 0xff
u8* src = reinterpret_cast<u8*>(reg_data) + addr;
count = std::min(count, int(reinterpret_cast<u8*>(reg_data + 1) - src));
std::copy_n(src, count, data_out);
return count;
}
template <typename T>
static int RawWrite(T* reg_data, u8 addr, int count, const u8* data_in)
{
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
static_assert(0x100 == sizeof(T));
// TODO: addr wraps around after 0xff
u8* dst = reinterpret_cast<u8*>(reg_data) + addr;
count = std::min(count, int(reinterpret_cast<u8*>(reg_data + 1) - dst));
std::copy_n(data_in, count, dst);
return count;
}
};
class I2CBus
{
public:
void AddSlave(I2CSlave* slave);
void RemoveSlave(I2CSlave* slave);
void Reset();
// TODO: change int to u16 or something
int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out);
int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in);
private:
// Pointers are unowned:
std::vector<I2CSlave*> m_slaves;
};
} // namespace Common

View file

@ -120,6 +120,7 @@
<ClInclude Include="Common\HostDisassembler.h" />
<ClInclude Include="Common\HRWrap.h" />
<ClInclude Include="Common\HttpRequest.h" />
<ClInclude Include="Common\I2C.h" />
<ClInclude Include="Common\Image.h" />
<ClInclude Include="Common\IniFile.h" />
<ClInclude Include="Common\Inline.h" />
@ -812,6 +813,7 @@
<ClCompile Include="Common\HostDisassembler.cpp" />
<ClCompile Include="Common\HRWrap.cpp" />
<ClCompile Include="Common\HttpRequest.cpp" />
<ClCompile Include="Common\I2C.cpp" />
<ClCompile Include="Common\Image.cpp" />
<ClCompile Include="Common\IniFile.cpp" />
<ClCompile Include="Common\IOFile.cpp" />