mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-20 19:44:57 +00:00
Temp, doesn't build
This commit is contained in:
parent
89a5108e46
commit
206b6337af
14 changed files with 71 additions and 219 deletions
|
@ -51,11 +51,7 @@ int I2CBusSimple::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
|
|||
{
|
||||
// TODO: Does this make sense? The transmitter can't NACK a read... it's the receiver that
|
||||
// does that
|
||||
auto byte = slave->ReadByte(addr + i);
|
||||
if (byte.has_value())
|
||||
data_out[i] = byte.value();
|
||||
else
|
||||
return i;
|
||||
data_out[i] = slave->ReadByte(addr + i);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
@ -207,18 +203,7 @@ void I2CBus::SCLRisingEdge(const bool sda)
|
|||
ASSERT_MSG(WII_IPC, slave != nullptr,
|
||||
"Expected device with ID {:02x} to be on the I2C bus as it was earlier",
|
||||
i2c_address.value());
|
||||
std::optional<u8> byte = slave->ReadByte(device_address.value());
|
||||
if (!byte.has_value())
|
||||
{
|
||||
WARN_LOG_FMT(WII_IPC, "Failed to read from device {:02x} at address {:02x}",
|
||||
i2c_address.value(), device_address.value());
|
||||
// TODO
|
||||
current_byte = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_byte = byte.value();
|
||||
}
|
||||
current_byte = slave->ReadByte(device_address.value());
|
||||
// INFO_LOG_FMT(WII_IPC, "AVE: Read from {:02x} ({}) -> {:02x}", device_address.value(),
|
||||
// IOS::GetAVERegisterName(device_address.value()), current_byte);
|
||||
}
|
||||
|
|
|
@ -17,30 +17,27 @@ class I2CSlave
|
|||
{
|
||||
public:
|
||||
virtual bool Matches(u8 slave_addr) = 0;
|
||||
virtual std::optional<u8> ReadByte(u8 addr) = 0;
|
||||
virtual u8 ReadByte(u8 addr) = 0;
|
||||
virtual bool WriteByte(u8 addr, u8 value) = 0;
|
||||
};
|
||||
|
||||
template <u8 slave_addr_val, typename T>
|
||||
class I2CSlaveSimple : I2CSlave
|
||||
{
|
||||
public:
|
||||
bool Matches(u8 slave_addr) override { return slave_addr == slave_addr_val; }
|
||||
std::optional<u8> ReadByte(u8 addr) { return data_bytes[addr]; }
|
||||
bool WriteByte(u8 addr, u8 value)
|
||||
protected:
|
||||
~I2CSlave() = default;
|
||||
|
||||
template<typename T>
|
||||
static u8 RawRead(T* reg_data, u8 addr)
|
||||
{
|
||||
data_bytes[addr] = value;
|
||||
return true;
|
||||
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
|
||||
static_assert(sizeof(T) == 0x100);
|
||||
return reinterpret_cast<u8*>(reg_data)[addr];
|
||||
}
|
||||
|
||||
union
|
||||
template <typename T>
|
||||
static void RawWrite(T* reg_data, u8 addr, u8 value)
|
||||
{
|
||||
T data;
|
||||
std::array<u8, 0x100> data_bytes;
|
||||
};
|
||||
|
||||
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
|
||||
static_assert(sizeof(T) == 0x100);
|
||||
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
|
||||
static_assert(sizeof(T) == 0x100);
|
||||
reinterpret_cast<u8*>(reg_data)[addr] = value;
|
||||
}
|
||||
};
|
||||
|
||||
class I2CBusBase
|
||||
|
|
|
@ -29,26 +29,20 @@ void CameraLogic::DoState(PointerWrap& p)
|
|||
// FYI: m_is_enabled is handled elsewhere.
|
||||
}
|
||||
|
||||
int CameraLogic::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
|
||||
bool CameraLogic::Matches(u8 slave_addr)
|
||||
{
|
||||
if (I2C_ADDR != slave_addr)
|
||||
return 0;
|
||||
|
||||
if (!m_is_enabled)
|
||||
return 0;
|
||||
|
||||
return RawRead(&m_reg_data, addr, count, data_out);
|
||||
return I2C_ADDR == slave_addr && m_is_enabled;
|
||||
}
|
||||
|
||||
int CameraLogic::BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in)
|
||||
u8 CameraLogic::ReadByte(u8 addr)
|
||||
{
|
||||
if (I2C_ADDR != slave_addr)
|
||||
return 0;
|
||||
return RawRead(&m_reg_data, addr);
|
||||
}
|
||||
|
||||
if (!m_is_enabled)
|
||||
return 0;
|
||||
|
||||
return RawWrite(&m_reg_data, addr, count, data_in);
|
||||
bool CameraLogic::WriteByte(u8 addr, u8 value)
|
||||
{
|
||||
RawWrite(&m_reg_data, addr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::array<CameraPoint, CameraLogic::NUM_POINTS>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/I2C.h"
|
||||
#include "Core/HW/WiimoteEmu/Dynamics.h"
|
||||
#include "Core/HW/WiimoteEmu/I2CBus.h"
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/Cursor.h"
|
||||
|
||||
namespace Common
|
||||
|
@ -101,7 +101,7 @@ struct IRFull : IRExtended
|
|||
};
|
||||
static_assert(sizeof(IRFull) == 9, "Wrong size");
|
||||
|
||||
class CameraLogic : public I2CSlave
|
||||
class CameraLogic : public Common::I2CSlave
|
||||
{
|
||||
public:
|
||||
// OEM sensor bar distance between LED clusters in meters.
|
||||
|
@ -175,9 +175,9 @@ public:
|
|||
// The real wiimote reads camera data from the i2c bus at offset 0x37:
|
||||
static const u8 REPORT_DATA_OFFSET = offsetof(Register, camera_data);
|
||||
|
||||
private:
|
||||
int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out) override;
|
||||
int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) override;
|
||||
bool Matches(u8 slave_addr) override;
|
||||
u8 ReadByte(u8 addr) override;
|
||||
bool WriteByte(u8 addr, u8 value) override;
|
||||
|
||||
Register m_reg_data{};
|
||||
|
||||
|
|
|
@ -71,14 +71,19 @@ void None::DoState(PointerWrap& p)
|
|||
// Nothing needed.
|
||||
}
|
||||
|
||||
int None::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
|
||||
bool None::Matches(u8 slave_addr)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int None::BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in)
|
||||
std::optional<u8> None::ReadByte(u8 addr)
|
||||
{
|
||||
return 0;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool None::WriteByte(u8 addr, u8 value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EncryptedExtension::ReadDeviceDetectPin() const
|
||||
|
|
|
@ -10,15 +10,15 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/I2C.h"
|
||||
#include "Core/HW/WiimoteEmu/Encryption.h"
|
||||
#include "Core/HW/WiimoteEmu/I2CBus.h"
|
||||
#include "InputCommon/ControllerEmu/ControllerEmu.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
struct DesiredExtensionState;
|
||||
|
||||
class Extension : public ControllerEmu::EmulatedController, public I2CSlave
|
||||
class Extension : public ControllerEmu::EmulatedController, public Common::I2CSlave
|
||||
{
|
||||
public:
|
||||
explicit Extension(const char* name);
|
||||
|
@ -56,8 +56,9 @@ private:
|
|||
void Reset() override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out) override;
|
||||
int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) override;
|
||||
bool Matches(u8 slave_addr) override;
|
||||
std::optional<u8> ReadByte(u8 addr) override;
|
||||
bool WriteByte(u8 addr, u8 value) override;
|
||||
};
|
||||
|
||||
// This class provides the encryption and initialization behavior of most extensions.
|
||||
|
|
|
@ -3,11 +3,9 @@
|
|||
|
||||
#include "Core/HW/WiimoteEmu/ExtensionPort.h"
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
ExtensionPort::ExtensionPort(I2CBus* i2c_bus) : m_i2c_bus(*i2c_bus)
|
||||
ExtensionPort::ExtensionPort(Common::I2CBusBase* i2c_bus) : m_i2c_bus(*i2c_bus)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/I2C.h"
|
||||
#include "Core/HW/WiimoteEmu/Extension/Extension.h"
|
||||
#include "Core/HW/WiimoteEmu/I2CBus.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
@ -35,14 +34,14 @@ public:
|
|||
static constexpr u8 REPORT_I2C_SLAVE = 0x52;
|
||||
static constexpr u8 REPORT_I2C_ADDR = 0x00;
|
||||
|
||||
explicit ExtensionPort(I2CBus* i2c_bus);
|
||||
explicit ExtensionPort(Common::I2CBusBase* i2c_bus);
|
||||
|
||||
bool IsDeviceConnected() const;
|
||||
void AttachExtension(Extension* dev);
|
||||
|
||||
private:
|
||||
Extension* m_extension = nullptr;
|
||||
I2CBus& m_i2c_bus;
|
||||
Common::I2CBusBase& m_i2c_bus;
|
||||
};
|
||||
|
||||
} // namespace WiimoteEmu
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright 2019 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "Core/HW/WiimoteEmu/I2CBus.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
void I2CBus::AddSlave(I2CSlave* slave)
|
||||
{
|
||||
m_slaves.emplace_back(slave);
|
||||
}
|
||||
|
||||
void I2CBus::RemoveSlave(I2CSlave* slave)
|
||||
{
|
||||
std::erase(m_slaves, slave);
|
||||
}
|
||||
|
||||
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 WiimoteEmu
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright 2019 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
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 WiimoteEmu
|
|
@ -248,8 +248,9 @@ private:
|
|||
ActivationStatus GetActivationStatus() const;
|
||||
PassthroughMode GetPassthroughMode() const;
|
||||
|
||||
int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out) override;
|
||||
int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) override;
|
||||
bool Matches(u8 slave_addr) override;
|
||||
u8 ReadByte(u8 addr) override;
|
||||
bool WriteByte(u8 addr, u8 value) override;
|
||||
|
||||
bool ReadDeviceDetectPin() const override;
|
||||
|
||||
|
@ -259,7 +260,7 @@ private:
|
|||
u8 m_progress_timer = {};
|
||||
|
||||
// The port on the end of the motion plus:
|
||||
I2CBus m_i2c_bus;
|
||||
Common::I2CBusSimple m_i2c_bus;
|
||||
ExtensionPort m_extension_port{&m_i2c_bus};
|
||||
};
|
||||
} // namespace WiimoteEmu
|
||||
|
|
|
@ -153,30 +153,29 @@ void SpeakerLogic::SetSpeakerEnabled(bool enabled)
|
|||
m_speaker_enabled = enabled;
|
||||
}
|
||||
|
||||
int SpeakerLogic::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
|
||||
bool SpeakerLogic::Matches(u8 slave_addr)
|
||||
{
|
||||
if (I2C_ADDR != slave_addr)
|
||||
return 0;
|
||||
|
||||
return RawRead(®_data, addr, count, data_out);
|
||||
return I2C_ADDR == slave_addr;
|
||||
}
|
||||
|
||||
int SpeakerLogic::BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in)
|
||||
u8 SpeakerLogic::ReadByte(u8 addr)
|
||||
{
|
||||
if (I2C_ADDR != slave_addr)
|
||||
return 0;
|
||||
return RawRead(®_data, addr);
|
||||
}
|
||||
|
||||
bool SpeakerLogic::WriteByte(u8 addr, u8 value)
|
||||
{
|
||||
if (0x00 == addr)
|
||||
{
|
||||
SpeakerData(data_in, count, m_speaker_pan_setting.GetValue() / 100);
|
||||
return count;
|
||||
// TODO: Does writing immediately change the decoder config even when active
|
||||
// or does a write to 0x08 activate the new configuration or something?
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Does writing immediately change the decoder config even when active
|
||||
// or does a write to 0x08 activate the new configuration or something?
|
||||
return RawWrite(®_data, addr, count, data_in);
|
||||
RawWrite(®_data, addr, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace WiimoteEmu
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/HW/WiimoteEmu/I2CBus.h"
|
||||
#include "Common/I2C.h"
|
||||
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
|
@ -17,7 +17,7 @@ struct ADPCMState
|
|||
|
||||
class Wiimote;
|
||||
|
||||
class SpeakerLogic : public I2CSlave
|
||||
class SpeakerLogic : public Common::I2CSlave
|
||||
{
|
||||
friend class Wiimote;
|
||||
|
||||
|
@ -63,8 +63,9 @@ private:
|
|||
|
||||
static_assert(0x100 == sizeof(Register));
|
||||
|
||||
int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out) override;
|
||||
int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) override;
|
||||
bool Matches(u8 slave_addr) override;
|
||||
u8 ReadByte(u8 addr) override;
|
||||
bool WriteByte(u8 addr, u8 value) override;
|
||||
|
||||
Register reg_data{};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/I2C.h"
|
||||
|
||||
#include "Core/HW/WiimoteCommon/WiimoteReport.h"
|
||||
|
||||
|
@ -17,7 +18,6 @@
|
|||
#include "Core/HW/WiimoteEmu/Dynamics.h"
|
||||
#include "Core/HW/WiimoteEmu/Encryption.h"
|
||||
#include "Core/HW/WiimoteEmu/ExtensionPort.h"
|
||||
#include "Core/HW/WiimoteEmu/I2CBus.h"
|
||||
#include "Core/HW/WiimoteEmu/MotionPlus.h"
|
||||
#include "Core/HW/WiimoteEmu/Speaker.h"
|
||||
|
||||
|
@ -316,7 +316,7 @@ private:
|
|||
MotionPlus m_motion_plus;
|
||||
CameraLogic m_camera_logic;
|
||||
|
||||
I2CBus m_i2c_bus;
|
||||
Common::I2CBusSimple m_i2c_bus;
|
||||
|
||||
ExtensionPort m_extension_port{&m_i2c_bus};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue