convert DSi I2C and camera

This commit is contained in:
Arisotura 2023-11-04 19:42:36 +01:00
parent 7837c169a1
commit 54ebf1b1b2
12 changed files with 400 additions and 367 deletions

View File

@ -79,6 +79,8 @@ std::unique_ptr<DSi_NAND::NANDImage> NANDImage;
DSi_SDHost* SDMMC; DSi_SDHost* SDMMC;
DSi_SDHost* SDIO; DSi_SDHost* SDIO;
DSi_I2CHost* I2C;
DSi_CamModule* CamModule;
DSi_AES* AES; DSi_AES* AES;
// FIXME: these currently have no effect (and aren't stored in a savestate) // FIXME: these currently have no effect (and aren't stored in a savestate)
@ -102,8 +104,6 @@ bool Init()
NWRAM_C = new u8[NWRAMSize]; NWRAM_C = new u8[NWRAMSize];
#endif #endif
if (!DSi_I2C::Init()) return false;
if (!DSi_CamModule::Init()) return false;
if (!DSi_DSP::Init()) return false; if (!DSi_DSP::Init()) return false;
NDMAs[0] = new DSi_NDMA(0, 0); NDMAs[0] = new DSi_NDMA(0, 0);
@ -118,6 +118,8 @@ bool Init()
SDMMC = new DSi_SDHost(0); SDMMC = new DSi_SDHost(0);
SDIO = new DSi_SDHost(1); SDIO = new DSi_SDHost(1);
I2C = new DSi_I2CHost();
CamModule = new DSi_CamModule();
AES = new DSi_AES(); AES = new DSi_AES();
return true; return true;
@ -135,8 +137,6 @@ void DeInit()
NWRAM_C = nullptr; NWRAM_C = nullptr;
#endif #endif
DSi_I2C::DeInit();
DSi_CamModule::DeInit();
DSi_DSP::DeInit(); DSi_DSP::DeInit();
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -148,6 +148,8 @@ void DeInit()
delete SDMMC; SDMMC = nullptr; delete SDMMC; SDMMC = nullptr;
delete SDIO; SDIO = nullptr; delete SDIO; SDIO = nullptr;
delete I2C; I2C = nullptr;
delete CamModule; CamModule = nullptr;
delete AES; AES = nullptr; delete AES; AES = nullptr;
NANDImage = nullptr; NANDImage = nullptr;
@ -166,8 +168,8 @@ void Reset()
NDMACnt[0] = 0; NDMACnt[1] = 0; NDMACnt[0] = 0; NDMACnt[1] = 0;
for (int i = 0; i < 8; i++) NDMAs[i]->Reset(); for (int i = 0; i < 8; i++) NDMAs[i]->Reset();
DSi_I2C::Reset(); I2C->Reset();
DSi_CamModule::Reset(); CamModule->Reset();
DSi_DSP::Reset(); DSi_DSP::Reset();
SDMMC->CloseHandles(); SDMMC->CloseHandles();
@ -210,7 +212,7 @@ void Reset()
void Stop() void Stop()
{ {
DSi_CamModule::Stop(); CamModule->Stop();
} }
void DoSavestate(Savestate* file) void DoSavestate(Savestate* file)
@ -285,9 +287,9 @@ void DoSavestate(Savestate* file)
NDMAs[i]->DoSavestate(file); NDMAs[i]->DoSavestate(file);
AES->DoSavestate(file); AES->DoSavestate(file);
DSi_CamModule::DoSavestate(file); CamModule->DoSavestate(file);
DSi_DSP::DoSavestate(file); DSi_DSP::DoSavestate(file);
DSi_I2C::DoSavestate(file); I2C->DoSavestate(file);
SDMMC->DoSavestate(file); SDMMC->DoSavestate(file);
SDIO->DoSavestate(file); SDIO->DoSavestate(file);
} }
@ -581,7 +583,7 @@ void SetupDirectBoot()
ARM9Write32(0x02FFFC00, cartid); ARM9Write32(0x02FFFC00, cartid);
ARM9Write16(0x02FFFC40, 0x0001); // boot indicator ARM9Write16(0x02FFFC40, 0x0001); // boot indicator
ARM9Write8(0x02FFFDFA, DSi_BPTWL::GetBootFlag() | 0x80); ARM9Write8(0x02FFFDFA, I2C->GetBPTWL()->GetBootFlag() | 0x80);
ARM9Write8(0x02FFFDFB, 0x01); ARM9Write8(0x02FFFDFB, 0x01);
} }
@ -2302,7 +2304,7 @@ u8 ARM9IORead8(u32 addr)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return 0; if (!(SCFG_EXT[0] & (1<<17))) return 0;
return DSi_CamModule::Read8(addr); return CamModule->Read8(addr);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2337,7 +2339,7 @@ u16 ARM9IORead16(u32 addr)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return 0; if (!(SCFG_EXT[0] & (1<<17))) return 0;
return DSi_CamModule::Read16(addr); return CamModule->Read16(addr);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2402,7 +2404,7 @@ u32 ARM9IORead32(u32 addr)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return 0; if (!(SCFG_EXT[0] & (1<<17))) return 0;
return DSi_CamModule::Read32(addr); return CamModule->Read32(addr);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2472,7 +2474,7 @@ void ARM9IOWrite8(u32 addr, u8 val)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return; if (!(SCFG_EXT[0] & (1<<17))) return;
return DSi_CamModule::Write8(addr, val); return CamModule->Write8(addr, val);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2532,7 +2534,7 @@ void ARM9IOWrite16(u32 addr, u16 val)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return; if (!(SCFG_EXT[0] & (1<<17))) return;
return DSi_CamModule::Write16(addr, val); return CamModule->Write16(addr, val);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2682,7 +2684,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
if ((addr & 0xFFFFFF00) == 0x04004200) if ((addr & 0xFFFFFF00) == 0x04004200)
{ {
if (!(SCFG_EXT[0] & (1<<17))) return; if (!(SCFG_EXT[0] & (1<<17))) return;
return DSi_CamModule::Write32(addr, val); return CamModule->Write32(addr, val);
} }
if ((addr & 0xFFFFFF00) == 0x04004300) if ((addr & 0xFFFFFF00) == 0x04004300)
@ -2715,8 +2717,8 @@ u8 ARM7IORead8(u32 addr)
CASE_READ8_32BIT(0x0400405C, MBK[1][7]) CASE_READ8_32BIT(0x0400405C, MBK[1][7])
CASE_READ8_32BIT(0x04004060, MBK[1][8]) CASE_READ8_32BIT(0x04004060, MBK[1][8])
case 0x04004500: return DSi_I2C::ReadData(); case 0x04004500: return I2C->ReadData();
case 0x04004501: return DSi_I2C::Cnt; case 0x04004501: return I2C->ReadCnt();
case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() & 0xFF; case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() & 0xFF;
case 0x04004D01: if (SCFG_BIOS & (1<<10)) return 0; return (NANDImage->GetConsoleID() >> 8) & 0xFF; case 0x04004D01: if (SCFG_BIOS & (1<<10)) return 0; return (NANDImage->GetConsoleID() >> 8) & 0xFF;
@ -2899,8 +2901,8 @@ void ARM7IOWrite8(u32 addr, u8 val)
return; return;
} }
case 0x04004500: DSi_I2C::WriteData(val); return; case 0x04004500: I2C->WriteData(val); return;
case 0x04004501: DSi_I2C::WriteCnt(val); return; case 0x04004501: I2C->WriteCnt(val); return;
case 0x4004700: case 0x4004700:
DSi_DSP::WriteSNDExCnt((u16)val | (DSi_DSP::SNDExCnt & 0xFF00)); DSi_DSP::WriteSNDExCnt((u16)val | (DSi_DSP::SNDExCnt & 0xFF00));

View File

@ -22,6 +22,8 @@
#include "NDS.h" #include "NDS.h"
#include "DSi_SD.h" #include "DSi_SD.h"
class DSi_I2CHost;
class DSi_CamModule;
class DSi_AES; class DSi_AES;
namespace DSi_NAND namespace DSi_NAND
@ -58,6 +60,8 @@ extern u32 NWRAMStart[2][3];
extern u32 NWRAMEnd[2][3]; extern u32 NWRAMEnd[2][3];
extern u32 NWRAMMask[2][3]; extern u32 NWRAMMask[2][3];
extern DSi_I2CHost* I2C;
extern DSi_CamModule* CamModule;
extern DSi_AES* AES; extern DSi_AES* AES;
bool Init(); bool Init();

View File

@ -25,48 +25,27 @@
using Platform::Log; using Platform::Log;
using Platform::LogLevel; using Platform::LogLevel;
namespace DSi_CamModule
{
Camera* Camera0; // 78 / facing outside
Camera* Camera1; // 7A / selfie cam
u16 ModuleCnt;
u16 Cnt;
u32 CropStart, CropEnd;
// pixel data buffer holds a maximum of 512 words, regardless of how long scanlines are
u32 DataBuffer[512];
u32 BufferReadPos, BufferWritePos;
u32 BufferNumLines;
Camera* CurCamera;
// note on camera data/etc intervals // note on camera data/etc intervals
// on hardware those are likely affected by several factors // on hardware those are likely affected by several factors
// namely, how long cameras take to process frames // namely, how long cameras take to process frames
// camera IRQ is fired at roughly 15FPS with default config // camera IRQ is fired at roughly 15FPS with default config
const u32 kIRQInterval = 1120000; // ~30 FPS const u32 DSi_CamModule::kIRQInterval = 1120000; // ~30 FPS
const u32 kTransferStart = 60000; const u32 DSi_CamModule::kTransferStart = 60000;
bool Init() DSi_CamModule::DSi_CamModule()
{ {
NDS::RegisterEventFunc(NDS::Event_DSi_CamIRQ, 0, IRQ); NDS::RegisterEventFunc(NDS::Event_DSi_CamIRQ, 0, MemberEventFunc(DSi_CamModule, IRQ));
NDS::RegisterEventFunc(NDS::Event_DSi_CamTransfer, 0, TransferScanline); NDS::RegisterEventFunc(NDS::Event_DSi_CamTransfer, 0, MemberEventFunc(DSi_CamModule, TransferScanline));
Camera0 = new Camera(0); Camera0 = DSi::I2C->GetOuterCamera();
Camera1 = new Camera(1); Camera1 = DSi::I2C->GetInnerCamera();
return true;
} }
void DeInit() DSi_CamModule::~DSi_CamModule()
{ {
delete Camera0;
delete Camera1;
Camera0 = nullptr; Camera0 = nullptr;
Camera1 = nullptr; Camera1 = nullptr;
@ -74,11 +53,8 @@ void DeInit()
NDS::UnregisterEventFunc(NDS::Event_DSi_CamTransfer, 0); NDS::UnregisterEventFunc(NDS::Event_DSi_CamTransfer, 0);
} }
void Reset() void DSi_CamModule::Reset()
{ {
Camera0->Reset();
Camera1->Reset();
ModuleCnt = 0; // CHECKME ModuleCnt = 0; // CHECKME
Cnt = 0; Cnt = 0;
@ -94,13 +70,13 @@ void Reset()
NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, 0, 0); NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, 0, 0);
} }
void Stop() void DSi_CamModule::Stop()
{ {
Camera0->Stop(); Camera0->Stop();
Camera1->Stop(); Camera1->Stop();
} }
void DoSavestate(Savestate* file) void DSi_CamModule::DoSavestate(Savestate* file)
{ {
file->Section("CAMi"); file->Section("CAMi");
@ -110,15 +86,12 @@ void DoSavestate(Savestate* file)
/*file->VarArray(FrameBuffer, sizeof(FrameBuffer)); /*file->VarArray(FrameBuffer, sizeof(FrameBuffer));
file->Var32(&TransferPos); file->Var32(&TransferPos);
file->Var32(&FrameLength);*/ file->Var32(&FrameLength);*/
Camera0->DoSavestate(file);
Camera1->DoSavestate(file);
} }
void IRQ(u32 param) void DSi_CamModule::IRQ(u32 param)
{ {
Camera* activecam = nullptr; DSi_Camera* activecam = nullptr;
// TODO: cameras don't have any priority! // TODO: cameras don't have any priority!
// activating both together will jumble the image data together // activating both together will jumble the image data together
@ -145,7 +118,7 @@ void IRQ(u32 param)
NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, 0, 0); NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, 0, 0);
} }
void TransferScanline(u32 line) void DSi_CamModule::TransferScanline(u32 line)
{ {
u32* dstbuf = &DataBuffer[BufferWritePos]; u32* dstbuf = &DataBuffer[BufferWritePos];
int maxlen = 512 - BufferWritePos; int maxlen = 512 - BufferWritePos;
@ -252,7 +225,7 @@ void TransferScanline(u32 line)
} }
u8 Read8(u32 addr) u8 DSi_CamModule::Read8(u32 addr)
{ {
// //
@ -260,7 +233,7 @@ u8 Read8(u32 addr)
return 0; return 0;
} }
u16 Read16(u32 addr) u16 DSi_CamModule::Read16(u32 addr)
{ {
switch (addr) switch (addr)
{ {
@ -272,7 +245,7 @@ u16 Read16(u32 addr)
return 0; return 0;
} }
u32 Read32(u32 addr) u32 DSi_CamModule::Read32(u32 addr)
{ {
switch (addr) switch (addr)
{ {
@ -298,14 +271,14 @@ u32 Read32(u32 addr)
return 0; return 0;
} }
void Write8(u32 addr, u8 val) void DSi_CamModule::Write8(u32 addr, u8 val)
{ {
// //
Log(LogLevel::Debug, "unknown DSi cam write8 %08X %02X\n", addr, val); Log(LogLevel::Debug, "unknown DSi cam write8 %08X %02X\n", addr, val);
} }
void Write16(u32 addr, u16 val) void DSi_CamModule::Write16(u32 addr, u16 val)
{ {
switch (addr) switch (addr)
{ {
@ -384,7 +357,7 @@ void Write16(u32 addr, u16 val)
Log(LogLevel::Debug, "unknown DSi cam write16 %08X %04X\n", addr, val); Log(LogLevel::Debug, "unknown DSi cam write16 %08X %04X\n", addr, val);
} }
void Write32(u32 addr, u32 val) void DSi_CamModule::Write32(u32 addr, u32 val)
{ {
switch (addr) switch (addr)
{ {
@ -403,16 +376,15 @@ void Write32(u32 addr, u32 val)
Camera::Camera(u32 num) DSi_Camera::DSi_Camera(DSi_I2CHost* host, u32 num) : DSi_I2CDevice(host), Num(num)
{
Num = num;
}
Camera::~Camera()
{ {
} }
void Camera::DoSavestate(Savestate* file) DSi_Camera::~DSi_Camera()
{
}
void DSi_Camera::DoSavestate(Savestate* file)
{ {
char magic[5] = "CAMx"; char magic[5] = "CAMx";
magic[3] = '0' + Num; magic[3] = '0' + Num;
@ -433,7 +405,7 @@ void Camera::DoSavestate(Savestate* file)
file->VarArray(MCURegs, 0x8000); file->VarArray(MCURegs, 0x8000);
} }
void Camera::Reset() void DSi_Camera::Reset()
{ {
Platform::Camera_Stop(Num); Platform::Camera_Stop(Num);
@ -458,12 +430,12 @@ void Camera::Reset()
memset(FrameBuffer, 0, (640*480/2)*sizeof(u32)); memset(FrameBuffer, 0, (640*480/2)*sizeof(u32));
} }
void Camera::Stop() void DSi_Camera::Stop()
{ {
Platform::Camera_Stop(Num); Platform::Camera_Stop(Num);
} }
bool Camera::IsActivated() bool DSi_Camera::IsActivated()
{ {
if (StandbyCnt & (1<<14)) return false; // standby if (StandbyCnt & (1<<14)) return false; // standby
if (!(MiscCnt & (1<<9))) return false; // data transfer not enabled if (!(MiscCnt & (1<<9))) return false; // data transfer not enabled
@ -472,7 +444,7 @@ bool Camera::IsActivated()
} }
void Camera::StartTransfer() void DSi_Camera::StartTransfer()
{ {
TransferY = 0; TransferY = 0;
@ -502,12 +474,12 @@ void Camera::StartTransfer()
Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true); Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true);
} }
bool Camera::TransferDone() bool DSi_Camera::TransferDone()
{ {
return TransferY >= FrameHeight; return TransferY >= FrameHeight;
} }
int Camera::TransferScanline(u32* buffer, int maxlen) int DSi_Camera::TransferScanline(u32* buffer, int maxlen)
{ {
if (TransferY >= FrameHeight) if (TransferY >= FrameHeight)
return 0; return 0;
@ -560,12 +532,12 @@ int Camera::TransferScanline(u32* buffer, int maxlen)
} }
void Camera::I2C_Start() void DSi_Camera::Acquire()
{ {
DataPos = 0; DataPos = 0;
} }
u8 Camera::I2C_Read(bool last) u8 DSi_Camera::Read(bool last)
{ {
u8 ret; u8 ret;
@ -586,7 +558,7 @@ u8 Camera::I2C_Read(bool last)
return ret; return ret;
} }
void Camera::I2C_Write(u8 val, bool last) void DSi_Camera::Write(u8 val, bool last)
{ {
if (DataPos < 2) if (DataPos < 2)
{ {
@ -615,7 +587,7 @@ void Camera::I2C_Write(u8 val, bool last)
else DataPos++; else DataPos++;
} }
u16 Camera::I2C_ReadReg(u16 addr) u16 DSi_Camera::I2C_ReadReg(u16 addr)
{ {
switch (addr) switch (addr)
{ {
@ -651,7 +623,7 @@ u16 Camera::I2C_ReadReg(u16 addr)
return 0; return 0;
} }
void Camera::I2C_WriteReg(u16 addr, u16 val) void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
{ {
switch (addr) switch (addr)
{ {
@ -720,14 +692,14 @@ void Camera::I2C_WriteReg(u16 addr, u16 val)
// TODO: not sure at all what is the accessible range // TODO: not sure at all what is the accessible range
// or if there is any overlap in the address range // or if there is any overlap in the address range
u8 Camera::MCU_Read(u16 addr) u8 DSi_Camera::MCU_Read(u16 addr)
{ {
addr &= 0x7FFF; addr &= 0x7FFF;
return MCURegs[addr]; return MCURegs[addr];
} }
void Camera::MCU_Write(u16 addr, u8 val) void DSi_Camera::MCU_Write(u16 addr, u8 val)
{ {
addr &= 0x7FFF; addr &= 0x7FFF;
@ -749,7 +721,7 @@ void Camera::MCU_Write(u16 addr, u8 val)
} }
void Camera::InputFrame(u32* data, int width, int height, bool rgb) void DSi_Camera::InputFrame(u32* data, int width, int height, bool rgb)
{ {
// TODO: double-buffering? // TODO: double-buffering?
@ -820,19 +792,3 @@ void Camera::InputFrame(u32* data, int width, int height, bool rgb)
} }
} }
} }
}

View File

@ -21,38 +21,15 @@
#include "types.h" #include "types.h"
#include "Savestate.h" #include "Savestate.h"
#include "DSi_I2C.h"
namespace DSi_CamModule class DSi_CamModule;
{
class Camera; class DSi_Camera : public DSi_I2CDevice
extern Camera* Camera0;
extern Camera* Camera1;
bool Init();
void DeInit();
void Reset();
void Stop();
void DoSavestate(Savestate* file);
void IRQ(u32 param);
void TransferScanline(u32 line);
u8 Read8(u32 addr);
u16 Read16(u32 addr);
u32 Read32(u32 addr);
void Write8(u32 addr, u8 val);
void Write16(u32 addr, u16 val);
void Write32(u32 addr, u32 val);
class Camera
{ {
public: public:
Camera(u32 num); DSi_Camera(DSi_I2CHost* host, u32 num);
~Camera(); ~DSi_Camera();
void DoSavestate(Savestate* file); void DoSavestate(Savestate* file);
@ -66,9 +43,9 @@ public:
// lengths in words // lengths in words
int TransferScanline(u32* buffer, int maxlen); int TransferScanline(u32* buffer, int maxlen);
void I2C_Start(); void Acquire();
u8 I2C_Read(bool last); u8 Read(bool last);
void I2C_Write(u8 val, bool last); void Write(u8 val, bool last);
void InputFrame(u32* data, int width, int height, bool rgb); void InputFrame(u32* data, int width, int height, bool rgb);
@ -101,6 +78,47 @@ private:
u32 FrameBuffer[640*480/2]; // YUYV framebuffer, two pixels per word u32 FrameBuffer[640*480/2]; // YUYV framebuffer, two pixels per word
}; };
}
class DSi_CamModule
{
public:
DSi_CamModule();
~DSi_CamModule();
void Reset();
void Stop();
void DoSavestate(Savestate* file);
DSi_Camera* GetOuterCamera() { return Camera0; }
DSi_Camera* GetInnerCamera() { return Camera1; }
void IRQ(u32 param);
void TransferScanline(u32 line);
u8 Read8(u32 addr);
u16 Read16(u32 addr);
u32 Read32(u32 addr);
void Write8(u32 addr, u8 val);
void Write16(u32 addr, u16 val);
void Write32(u32 addr, u32 val);
private:
DSi_Camera* Camera0; // 78 / facing outside
DSi_Camera* Camera1; // 7A / selfie cam
u16 ModuleCnt;
u16 Cnt;
u32 CropStart, CropEnd;
// pixel data buffer holds a maximum of 512 words, regardless of how long scanlines are
u32 DataBuffer[512];
u32 BufferReadPos, BufferWritePos;
u32 BufferNumLines;
DSi_Camera* CurCamera;
static const u32 kIRQInterval;
static const u32 kTransferStart;
};
#endif // DSI_CAMERA_H #endif // DSI_CAMERA_H

View File

@ -29,18 +29,16 @@
using Platform::Log; using Platform::Log;
using Platform::LogLevel; using Platform::LogLevel;
namespace DSi_BPTWL
{
// TODO: These are purely approximations // TODO: These are purely approximations
const double PowerButtonShutdownTime = 0.5; const double DSi_BPTWL::PowerButtonShutdownTime = 0.5;
const double PowerButtonForcedShutdownTime = 5.0; const double DSi_BPTWL::PowerButtonForcedShutdownTime = 5.0;
const double VolumeSwitchRepeatStart = 0.5; const double DSi_BPTWL::VolumeSwitchRepeatStart = 0.5;
const double VolumeSwitchRepeatRate = 1.0 / 6; const double DSi_BPTWL::VolumeSwitchRepeatRate = 1.0 / 6;
// Could not find a pattern or a decent formula for these, // Could not find a pattern or a decent formula for these,
// regardless, they're only 64 bytes in size // regardless, they're only 64 bytes in size
const u8 VolumeDownTable[32] = const u8 DSi_BPTWL::VolumeDownTable[32] =
{ {
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03,
0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0A,
@ -48,7 +46,7 @@ const u8 VolumeDownTable[32] =
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
}; };
const u8 VolumeUpTable[32] = const u8 DSi_BPTWL::VolumeUpTable[32] =
{ {
0x02, 0x03, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x02, 0x03, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
@ -56,27 +54,16 @@ const u8 VolumeUpTable[32] =
0x1D, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1D, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
}; };
double PowerButtonTime = 0.0;
bool PowerButtonDownFlag = false;
bool PowerButtonShutdownFlag = false;
double VolumeSwitchTime = 0.0;
double VolumeSwitchRepeatTime = 0.0;
bool VolumeSwitchDownFlag = false;
u32 VolumeSwitchKeysDown = 0;
u8 Registers[0x100]; DSi_BPTWL::DSi_BPTWL(DSi_I2CHost* host) : DSi_I2CDevice(host)
u32 CurPos;
bool Init()
{
return true;
}
void DeInit()
{ {
} }
void Reset() DSi_BPTWL::~DSi_BPTWL()
{
}
void DSi_BPTWL::Reset()
{ {
CurPos = -1; CurPos = -1;
memset(Registers, 0x5A, 0x100); memset(Registers, 0x5A, 0x100);
@ -115,10 +102,11 @@ void Reset()
VolumeSwitchTime = 0.0; VolumeSwitchTime = 0.0;
VolumeSwitchRepeatTime = 0.0; VolumeSwitchRepeatTime = 0.0;
VolumeSwitchKeysDown = 0; VolumeSwitchKeysDown = 0;
VolumeSwitchDownFlag = false;
} }
void DoSavestate(Savestate* file) void DSi_BPTWL::DoSavestate(Savestate* file)
{ {
file->Section("I2BP"); file->Section("I2BP");
@ -127,21 +115,21 @@ void DoSavestate(Savestate* file)
} }
// TODO: Needs more investigation on the other bits // TODO: Needs more investigation on the other bits
inline bool GetIRQMode() inline bool DSi_BPTWL::GetIRQMode()
{ {
return Registers[0x12] & 0x01; return Registers[0x12] & 0x01;
} }
u8 GetBootFlag() { return Registers[0x70]; } u8 DSi_BPTWL::GetBootFlag() { return Registers[0x70]; }
bool GetBatteryCharging() { return Registers[0x20] >> 7; } bool DSi_BPTWL::GetBatteryCharging() { return Registers[0x20] >> 7; }
void SetBatteryCharging(bool charging) void DSi_BPTWL::SetBatteryCharging(bool charging)
{ {
Registers[0x20] = (((charging ? 0x8 : 0x0) << 4) | (Registers[0x20] & 0x0F)); Registers[0x20] = (((charging ? 0x8 : 0x0) << 4) | (Registers[0x20] & 0x0F));
} }
u8 GetBatteryLevel() { return Registers[0x20] & 0xF; } u8 DSi_BPTWL::GetBatteryLevel() { return Registers[0x20] & 0xF; }
void SetBatteryLevel(u8 batteryLevel) void DSi_BPTWL::SetBatteryLevel(u8 batteryLevel)
{ {
Registers[0x20] = ((Registers[0x20] & 0xF0) | (batteryLevel & 0x0F)); Registers[0x20] = ((Registers[0x20] & 0xF0) | (batteryLevel & 0x0F));
//SPI_Powerman::SetBatteryLevelOkay(batteryLevel > batteryLevel_Low ? true : false); //SPI_Powerman::SetBatteryLevelOkay(batteryLevel > batteryLevel_Low ? true : false);
@ -153,20 +141,20 @@ void SetBatteryLevel(u8 batteryLevel)
} }
u8 GetVolumeLevel() { return Registers[0x40]; } u8 DSi_BPTWL::GetVolumeLevel() { return Registers[0x40]; }
void SetVolumeLevel(u8 volume) void DSi_BPTWL::SetVolumeLevel(u8 volume)
{ {
Registers[0x40] = volume & 0x1F; Registers[0x40] = volume & 0x1F;
} }
u8 GetBacklightLevel() { return Registers[0x41]; } u8 DSi_BPTWL::GetBacklightLevel() { return Registers[0x41]; }
void SetBacklightLevel(u8 backlight) void DSi_BPTWL::SetBacklightLevel(u8 backlight)
{ {
Registers[0x41] = backlight > 4 ? 4 : backlight; Registers[0x41] = backlight > 4 ? 4 : backlight;
} }
void ResetButtonState() void DSi_BPTWL::ResetButtonState()
{ {
PowerButtonTime = 0.0; PowerButtonTime = 0.0;
PowerButtonDownFlag = false; PowerButtonDownFlag = false;
@ -178,7 +166,7 @@ void ResetButtonState()
VolumeSwitchRepeatTime = 0.0; VolumeSwitchRepeatTime = 0.0;
} }
void DoHardwareReset(bool direct) void DSi_BPTWL::DoHardwareReset(bool direct)
{ {
ResetButtonState(); ResetButtonState();
@ -196,14 +184,14 @@ void DoHardwareReset(bool direct)
NDS::ARM7->Halt(4); NDS::ARM7->Halt(4);
} }
void DoShutdown() void DSi_BPTWL::DoShutdown()
{ {
ResetButtonState(); ResetButtonState();
NDS::Stop(Platform::StopReason::PowerOff); NDS::Stop(Platform::StopReason::PowerOff);
} }
void SetPowerButtonHeld(double time) void DSi_BPTWL::SetPowerButtonHeld(double time)
{ {
if (!PowerButtonDownFlag) if (!PowerButtonDownFlag)
{ {
@ -230,7 +218,7 @@ void SetPowerButtonHeld(double time)
} }
} }
void SetPowerButtonReleased(double time) void DSi_BPTWL::SetPowerButtonReleased(double time)
{ {
double elapsed = time - PowerButtonTime; double elapsed = time - PowerButtonTime;
if (elapsed >= 0 && elapsed < PowerButtonShutdownTime) if (elapsed >= 0 && elapsed < PowerButtonShutdownTime)
@ -243,12 +231,12 @@ void SetPowerButtonReleased(double time)
PowerButtonShutdownFlag = false; PowerButtonShutdownFlag = false;
} }
void SetVolumeSwitchHeld(u32 key) void DSi_BPTWL::SetVolumeSwitchHeld(u32 key)
{ {
VolumeSwitchKeysDown |= (1 << key); VolumeSwitchKeysDown |= (1 << key);
} }
void SetVolumeSwitchReleased(u32 key) void DSi_BPTWL::SetVolumeSwitchReleased(u32 key)
{ {
VolumeSwitchKeysDown &= ~(1 << key); VolumeSwitchKeysDown &= ~(1 << key);
VolumeSwitchDownFlag = false; VolumeSwitchDownFlag = false;
@ -256,7 +244,7 @@ void SetVolumeSwitchReleased(u32 key)
VolumeSwitchRepeatTime = 0.0; VolumeSwitchRepeatTime = 0.0;
} }
inline bool CheckVolumeSwitchKeysValid() inline bool DSi_BPTWL::CheckVolumeSwitchKeysValid()
{ {
bool up = VolumeSwitchKeysDown & (1 << volumeKey_Up); bool up = VolumeSwitchKeysDown & (1 << volumeKey_Up);
bool down = VolumeSwitchKeysDown & (1 << volumeKey_Down); bool down = VolumeSwitchKeysDown & (1 << volumeKey_Down);
@ -264,7 +252,7 @@ inline bool CheckVolumeSwitchKeysValid()
return up != down; return up != down;
} }
s32 ProcessVolumeSwitchInput(double time) s32 DSi_BPTWL::ProcessVolumeSwitchInput(double time)
{ {
if (!CheckVolumeSwitchKeysValid()) if (!CheckVolumeSwitchKeysValid())
return -1; return -1;
@ -303,7 +291,7 @@ s32 ProcessVolumeSwitchInput(double time)
} }
void DoPowerButtonPress() void DSi_BPTWL::DoPowerButtonPress()
{ {
// Set button pressed IRQ // Set button pressed IRQ
SetIRQ(IRQ_PowerButtonPressed); SetIRQ(IRQ_PowerButtonPressed);
@ -311,7 +299,7 @@ void DoPowerButtonPress()
// There is no default hardware behavior for pressing the power button // There is no default hardware behavior for pressing the power button
} }
void DoPowerButtonReset() void DSi_BPTWL::DoPowerButtonReset()
{ {
// Reset via IRQ, handled by software // Reset via IRQ, handled by software
SetIRQ(IRQ_PowerButtonReset); SetIRQ(IRQ_PowerButtonReset);
@ -324,7 +312,7 @@ void DoPowerButtonReset()
} }
} }
void DoPowerButtonShutdown() void DSi_BPTWL::DoPowerButtonShutdown()
{ {
// Shutdown via IRQ, handled by software // Shutdown via IRQ, handled by software
if (!PowerButtonShutdownFlag) if (!PowerButtonShutdownFlag)
@ -346,12 +334,12 @@ void DoPowerButtonShutdown()
// down the power button, the DSi will still shut down // down the power button, the DSi will still shut down
} }
void DoPowerButtonForceShutdown() void DSi_BPTWL::DoPowerButtonForceShutdown()
{ {
DoShutdown(); DoShutdown();
} }
void DoVolumeSwitchPress(u32 key) void DSi_BPTWL::DoVolumeSwitchPress(u32 key)
{ {
u8 volume = Registers[0x40]; u8 volume = Registers[0x40];
@ -373,7 +361,7 @@ void DoVolumeSwitchPress(u32 key)
SetIRQ(IRQ_VolumeSwitchPressed); SetIRQ(IRQ_VolumeSwitchPressed);
} }
void SetIRQ(u8 irqFlag) void DSi_BPTWL::SetIRQ(u8 irqFlag)
{ {
Registers[0x10] |= irqFlag & IRQ_ValidMask; Registers[0x10] |= irqFlag & IRQ_ValidMask;
@ -383,12 +371,12 @@ void SetIRQ(u8 irqFlag)
} }
} }
void Start() void DSi_BPTWL::Acquire()
{ {
//printf("BPTWL: start\n"); //printf("BPTWL: start\n");
} }
u8 Read(bool last) u8 DSi_BPTWL::Read(bool last)
{ {
//printf("BPTWL: read %02X -> %02X @ %08X\n", CurPos, Registers[CurPos], NDS::GetPC(1)); //printf("BPTWL: read %02X -> %02X @ %08X\n", CurPos, Registers[CurPos], NDS::GetPC(1));
u8 ret = Registers[CurPos]; u8 ret = Registers[CurPos];
@ -409,7 +397,7 @@ u8 Read(bool last)
return ret; return ret;
} }
void Write(u8 val, bool last) void DSi_BPTWL::Write(u8 val, bool last)
{ {
if (last) if (last)
{ {
@ -460,51 +448,69 @@ void Write(u8 val, bool last)
CurPos++; // CHECKME CurPos++; // CHECKME
} }
DSi_I2CHost::DSi_I2CHost()
{
BPTWL = new DSi_BPTWL(this);
Camera0 = new DSi_Camera(this, 0);
Camera1 = new DSi_Camera(this, 1);
} }
DSi_I2CHost::~DSi_I2CHost()
namespace DSi_I2C
{ {
delete BPTWL; BPTWL = nullptr;
u8 Cnt; delete Camera0; Camera0 = nullptr;
u8 Data; delete Camera1; Camera1 = nullptr;
u32 Device;
bool Init()
{
if (!DSi_BPTWL::Init()) return false;
return true;
} }
void DeInit() void DSi_I2CHost::Reset()
{
DSi_BPTWL::DeInit();
}
void Reset()
{ {
Cnt = 0; Cnt = 0;
Data = 0; Data = 0;
Device = -1; CurDeviceID = 0;
CurDevice = nullptr;
DSi_BPTWL::Reset(); BPTWL->Reset();
Camera0->Reset();
Camera1->Reset();
} }
void DoSavestate(Savestate* file) void DSi_I2CHost::DoSavestate(Savestate* file)
{ {
file->Section("I2Ci"); file->Section("I2Ci");
file->Var8(&Cnt); file->Var8(&Cnt);
file->Var8(&Data); file->Var8(&Data);
file->Var32(&Device); file->Var8(&CurDeviceID);
DSi_BPTWL::DoSavestate(file); if (!file->Saving)
{
GetCurDevice();
}
BPTWL->DoSavestate(file);
Camera0->DoSavestate(file);
Camera1->DoSavestate(file);
} }
void WriteCnt(u8 val) void DSi_I2CHost::GetCurDevice()
{
switch (CurDeviceID)
{
case 0x4A: CurDevice = BPTWL; break;
case 0x78: CurDevice = Camera0; break;
case 0x7A: CurDevice = Camera1; break;
case 0xA0:
case 0xE0: CurDevice = nullptr; break;
default:
Log(LogLevel::Warn, "I2C: unknown device %02X\n", CurDeviceID);
CurDevice = nullptr;
break;
}
}
void DSi_I2CHost::WriteCnt(u8 val)
{ {
//printf("I2C: write CNT %02X, %02X, %08X\n", val, Data, NDS::GetPC(1)); //printf("I2C: write CNT %02X, %02X, %08X\n", val, Data, NDS::GetPC(1));
@ -522,17 +528,13 @@ void WriteCnt(u8 val)
// read // read
val &= 0xF7; val &= 0xF7;
switch (Device) if (CurDevice)
{
Data = CurDevice->Read(islast);
}
else
{ {
case 0x4A: Data = DSi_BPTWL::Read(islast); break;
case 0x78: Data = DSi_CamModule::Camera0->I2C_Read(islast); break;
case 0x7A: Data = DSi_CamModule::Camera1->I2C_Read(islast); break;
case 0xA0:
case 0xE0: Data = 0xFF; break;
default:
Log(LogLevel::Warn, "I2C: read on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, 0, islast);
Data = 0xFF; Data = 0xFF;
break;
} }
//printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); //printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
@ -545,37 +547,30 @@ void WriteCnt(u8 val)
if (val & (1<<1)) if (val & (1<<1))
{ {
Device = Data & 0xFE; CurDeviceID = Data & 0xFE;
//printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device); //printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device);
switch (Device) GetCurDevice();
if (CurDevice)
{
CurDevice->Acquire();
}
else
{ {
case 0x4A: DSi_BPTWL::Start(); break;
case 0x78: DSi_CamModule::Camera0->I2C_Start(); break;
case 0x7A: DSi_CamModule::Camera1->I2C_Start(); break;
case 0xA0:
case 0xE0: ack = false; break;
default:
Log(LogLevel::Warn, "I2C: %s start on unknown device %02X\n", (Data&0x01)?"read":"write", Device);
ack = false; ack = false;
break;
} }
} }
else else
{ {
//printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); //printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
switch (Device) if (CurDevice)
{
CurDevice->Write(Data, islast);
}
else
{ {
case 0x4A: DSi_BPTWL::Write(Data, islast); break;
case 0x78: DSi_CamModule::Camera0->I2C_Write(Data, islast); break;
case 0x7A: DSi_CamModule::Camera1->I2C_Write(Data, islast); break;
case 0xA0:
case 0xE0: ack = false; break;
default:
Log(LogLevel::Warn, "I2C: write on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
ack = false; ack = false;
break;
} }
} }
@ -588,14 +583,12 @@ void WriteCnt(u8 val)
Cnt = val; Cnt = val;
} }
u8 ReadData() u8 DSi_I2CHost::ReadData()
{ {
return Data; return Data;
} }
void WriteData(u8 val) void DSi_I2CHost::WriteData(u8 val)
{ {
Data = val; Data = val;
} }
}

View File

@ -22,59 +22,47 @@
#include "types.h" #include "types.h"
#include "Savestate.h" #include "Savestate.h"
namespace DSi_BPTWL class DSi_I2CHost;
class DSi_Camera;
class DSi_I2CDevice
{ {
public:
DSi_I2CDevice(DSi_I2CHost* host) : Host(host) {}
virtual ~DSi_I2CDevice() {}
virtual void Reset() = 0;
virtual void DoSavestate(Savestate* file) = 0;
u8 GetBootFlag(); virtual void Acquire() = 0;
virtual u8 Read(bool last) = 0;
virtual void Write(u8 val, bool last) = 0;
bool GetBatteryCharging(); protected:
void SetBatteryCharging(bool charging); DSi_I2CHost* Host;
};
enum class DSi_BPTWL : public DSi_I2CDevice
{ {
public:
enum
{
batteryLevel_Critical = 0x0, batteryLevel_Critical = 0x0,
batteryLevel_AlmostEmpty = 0x1, batteryLevel_AlmostEmpty = 0x1,
batteryLevel_Low = 0x3, batteryLevel_Low = 0x3,
batteryLevel_Half = 0x7, batteryLevel_Half = 0x7,
batteryLevel_ThreeQuarters = 0xB, batteryLevel_ThreeQuarters = 0xB,
batteryLevel_Full = 0xF batteryLevel_Full = 0xF
}; };
u8 GetBatteryLevel(); enum
void SetBatteryLevel(u8 batteryLevel); {
// 0-31
u8 GetVolumeLevel();
void SetVolumeLevel(u8 volume);
// 0-4
u8 GetBacklightLevel();
void SetBacklightLevel(u8 backlight);
void DoHardwareReset(bool direct);
void DoShutdown();
enum
{
volumeKey_Up, volumeKey_Up,
volumeKey_Down, volumeKey_Down,
}; };
// Used by hotkeys enum
void SetPowerButtonHeld(double time); {
void SetPowerButtonReleased(double time);
void SetVolumeSwitchHeld(u32 key);
void SetVolumeSwitchReleased(u32 key);
s32 ProcessVolumeSwitchInput(double time);
void DoPowerButtonPress();
void DoPowerButtonReset();
void DoPowerButtonShutdown();
void DoPowerButtonForceShutdown();
void DoVolumeSwitchPress(u32 key);
enum
{
IRQ_PowerButtonReset = 0x01, // Triggered after releasing the power button quickly IRQ_PowerButtonReset = 0x01, // Triggered after releasing the power button quickly
IRQ_PowerButtonShutdown = 0x02, // Triggered after holding the power button for less than a second IRQ_PowerButtonShutdown = 0x02, // Triggered after holding the power button for less than a second
IRQ_PowerButtonPressed = 0x08, // Triggered after pressing the power button IRQ_PowerButtonPressed = 0x08, // Triggered after pressing the power button
@ -88,29 +76,108 @@ enum
Both bits are never used by the official ARM7 libraries, but could have some undocumented hardware functionality (?). Both bits are never used by the official ARM7 libraries, but could have some undocumented hardware functionality (?).
*/ */
IRQ_ValidMask = 0x7B, IRQ_ValidMask = 0x7B,
};
DSi_BPTWL(DSi_I2CHost* host);
~DSi_BPTWL() override;
void Reset() override;
void DoSavestate(Savestate* file) override;
u8 GetBootFlag();
bool GetBatteryCharging();
void SetBatteryCharging(bool charging);
u8 GetBatteryLevel();
void SetBatteryLevel(u8 batteryLevel);
// 0-31
u8 GetVolumeLevel();
void SetVolumeLevel(u8 volume);
// 0-4
u8 GetBacklightLevel();
void SetBacklightLevel(u8 backlight);
void DoHardwareReset(bool direct);
void DoShutdown();
// Used by hotkeys
void SetPowerButtonHeld(double time);
void SetPowerButtonReleased(double time);
void SetVolumeSwitchHeld(u32 key);
void SetVolumeSwitchReleased(u32 key);
s32 ProcessVolumeSwitchInput(double time);
void DoPowerButtonPress();
void DoPowerButtonReset();
void DoPowerButtonShutdown();
void DoPowerButtonForceShutdown();
void DoVolumeSwitchPress(u32 key);
void SetIRQ(u8 irqFlag);
void Acquire() override;
u8 Read(bool last) override;
void Write(u8 val, bool last) override;
private:
static const double PowerButtonShutdownTime;
static const double PowerButtonForcedShutdownTime;
static const double VolumeSwitchRepeatStart;
static const double VolumeSwitchRepeatRate;
static const u8 VolumeDownTable[32];
static const u8 VolumeUpTable[32];
double PowerButtonTime;
bool PowerButtonDownFlag;
bool PowerButtonShutdownFlag;
double VolumeSwitchTime;
double VolumeSwitchRepeatTime;
bool VolumeSwitchDownFlag ;
u32 VolumeSwitchKeysDown;
u8 Registers[0x100];
u32 CurPos;
bool GetIRQMode();
void ResetButtonState();
bool CheckVolumeSwitchKeysValid();
}; };
void SetIRQ(u8 irqFlag);
} class DSi_I2CHost
namespace DSi_I2C
{ {
public:
DSi_I2CHost();
~DSi_I2CHost();
void Reset();
void DoSavestate(Savestate* file);
extern u8 Cnt; DSi_BPTWL* GetBPTWL() { return BPTWL; }
DSi_Camera* GetOuterCamera() { return Camera0; }
DSi_Camera* GetInnerCamera() { return Camera1; }
bool Init(); u8 ReadCnt() { return Cnt; }
void DeInit(); void WriteCnt(u8 val);
void Reset();
void DoSavestate(Savestate* file);
void WriteCnt(u8 val); u8 ReadData();
void WriteData(u8 val);
u8 ReadData(); private:
void WriteData(u8 val); u8 Cnt;
u8 Data;
//void TransferDone(u32 param); DSi_BPTWL* BPTWL; // 4A / BPTWL IC
DSi_Camera* Camera0; // 78 / facing outside
DSi_Camera* Camera1; // 7A / selfie cam
} u8 CurDeviceID;
DSi_I2CDevice* CurDevice;
void GetCurDevice();
};
#endif // DSI_I2C_H #endif // DSI_I2C_H

View File

@ -1365,8 +1365,8 @@ void CamInputFrame(int cam, u32* data, int width, int height, bool rgb)
{ {
switch (cam) switch (cam)
{ {
case 0: return DSi_CamModule::Camera0->InputFrame(data, width, height, rgb); case 0: return DSi::CamModule->GetOuterCamera()->InputFrame(data, width, height, rgb);
case 1: return DSi_CamModule::Camera1->InputFrame(data, width, height, rgb); case 1: return DSi::CamModule->GetInnerCamera()->InputFrame(data, width, height, rgb);
} }
} }
} }

View File

@ -46,9 +46,7 @@ class SPIDevice
public: public:
SPIDevice(SPIHost* host) : Host(host), Hold(false), DataPos(0) {} SPIDevice(SPIHost* host) : Host(host), Hold(false), DataPos(0) {}
virtual ~SPIDevice() {} virtual ~SPIDevice() {}
virtual void Reset() = 0; virtual void Reset() = 0;
virtual void DoSavestate(Savestate* file) = 0; virtual void DoSavestate(Savestate* file) = 0;
virtual u8 Read() { return Data; } virtual u8 Read() { return Data; }
@ -68,9 +66,7 @@ class FirmwareMem : public SPIDevice
public: public:
FirmwareMem(SPIHost* host); FirmwareMem(SPIHost* host);
~FirmwareMem() override; ~FirmwareMem() override;
void Reset() override; void Reset() override;
void DoSavestate(Savestate* file) override; void DoSavestate(Savestate* file) override;
void SetupDirectBoot(bool dsi); void SetupDirectBoot(bool dsi);
@ -100,9 +96,7 @@ class PowerMan : public SPIDevice
public: public:
PowerMan(SPIHost* host); PowerMan(SPIHost* host);
~PowerMan() override; ~PowerMan() override;
void Reset() override; void Reset() override;
void DoSavestate(Savestate* file) override; void DoSavestate(Savestate* file) override;
bool GetBatteryLevelOkay(); bool GetBatteryLevelOkay();
@ -122,9 +116,7 @@ class TSC : public SPIDevice
public: public:
TSC(SPIHost* host); TSC(SPIHost* host);
virtual ~TSC() override; virtual ~TSC() override;
virtual void Reset() override; virtual void Reset() override;
virtual void DoSavestate(Savestate* file) override; virtual void DoSavestate(Savestate* file) override;
virtual void SetTouchCoords(u16 x, u16 y); virtual void SetTouchCoords(u16 x, u16 y);
@ -149,9 +141,7 @@ class SPIHost
public: public:
SPIHost(); SPIHost();
~SPIHost(); ~SPIHost();
void Reset(); void Reset();
void DoSavestate(Savestate* file); void DoSavestate(Savestate* file);
FirmwareMem* GetFirmwareMem() { return (FirmwareMem*)Devices[SPIDevice_FirmwareMem]; } FirmwareMem* GetFirmwareMem() { return (FirmwareMem*)Devices[SPIDevice_FirmwareMem]; }

View File

@ -24,6 +24,7 @@
#include "Platform.h" #include "Platform.h"
#include "Config.h" #include "Config.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#include "DSi_I2C.h" #include "DSi_I2C.h"
#include "AudioSettingsDialog.h" #include "AudioSettingsDialog.h"
@ -126,7 +127,7 @@ void AudioSettingsDialog::onSyncVolumeLevel()
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
bool state = ui->slVolume->blockSignals(true); bool state = ui->slVolume->blockSignals(true);
ui->slVolume->setValue(DSi_BPTWL::GetVolumeLevel()); ui->slVolume->setValue(DSi::I2C->GetBPTWL()->GetVolumeLevel());
ui->slVolume->blockSignals(state); ui->slVolume->blockSignals(state);
} }
} }
@ -181,7 +182,7 @@ void AudioSettingsDialog::on_slVolume_valueChanged(int val)
{ {
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
DSi_BPTWL::SetVolumeLevel(val); DSi::I2C->GetBPTWL()->SetVolumeLevel(val);
return; return;
} }
@ -196,7 +197,7 @@ void AudioSettingsDialog::on_chkSyncDSiVolume_clicked(bool checked)
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
ui->slVolume->setMaximum(31); ui->slVolume->setMaximum(31);
ui->slVolume->setValue(DSi_BPTWL::GetVolumeLevel()); ui->slVolume->setValue(DSi::I2C->GetBPTWL()->GetVolumeLevel());
ui->slVolume->setPageStep(4); ui->slVolume->setPageStep(4);
ui->slVolume->setTickPosition(QSlider::TicksBelow); ui->slVolume->setTickPosition(QSlider::TicksBelow);
} }

View File

@ -22,6 +22,7 @@
#include "SPI.h" #include "SPI.h"
#include "DSi_I2C.h" #include "DSi_I2C.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#include "Config.h" #include "Config.h"
#include "Platform.h" #include "Platform.h"
@ -42,8 +43,8 @@ PowerManagementDialog::PowerManagementDialog(QWidget* parent) : QDialog(parent),
{ {
ui->grpDSBattery->setEnabled(false); ui->grpDSBattery->setEnabled(false);
oldDSiBatteryLevel = DSi_BPTWL::GetBatteryLevel(); oldDSiBatteryLevel = DSi::I2C->GetBPTWL()->GetBatteryLevel();
oldDSiBatteryCharging = DSi_BPTWL::GetBatteryCharging(); oldDSiBatteryCharging = DSi::I2C->GetBPTWL()->GetBatteryCharging();
} }
else else
{ {
@ -54,9 +55,9 @@ PowerManagementDialog::PowerManagementDialog(QWidget* parent) : QDialog(parent),
updateDSBatteryLevelControls(); updateDSBatteryLevelControls();
ui->cbDSiBatteryCharging->setChecked(DSi_BPTWL::GetBatteryCharging()); ui->cbDSiBatteryCharging->setChecked(DSi::I2C->GetBPTWL()->GetBatteryCharging());
int dsiBatterySliderPos; int dsiBatterySliderPos;
switch (DSi_BPTWL::GetBatteryLevel()) switch (DSi::I2C->GetBPTWL()->GetBatteryLevel())
{ {
case DSi_BPTWL::batteryLevel_AlmostEmpty: dsiBatterySliderPos = 0; break; case DSi_BPTWL::batteryLevel_AlmostEmpty: dsiBatterySliderPos = 0; break;
case DSi_BPTWL::batteryLevel_Low: dsiBatterySliderPos = 1; break; case DSi_BPTWL::batteryLevel_Low: dsiBatterySliderPos = 1; break;
@ -86,8 +87,8 @@ void PowerManagementDialog::done(int r)
{ {
if (NDS::ConsoleType == 1) if (NDS::ConsoleType == 1)
{ {
Config::DSiBatteryLevel = DSi_BPTWL::GetBatteryLevel(); Config::DSiBatteryLevel = DSi::I2C->GetBPTWL()->GetBatteryLevel();
Config::DSiBatteryCharging = DSi_BPTWL::GetBatteryCharging(); Config::DSiBatteryCharging = DSi::I2C->GetBPTWL()->GetBatteryCharging();
} }
else else
{ {
@ -98,8 +99,8 @@ void PowerManagementDialog::done(int r)
{ {
if (NDS::ConsoleType == 1) if (NDS::ConsoleType == 1)
{ {
DSi_BPTWL::SetBatteryLevel(oldDSiBatteryLevel); DSi::I2C->GetBPTWL()->SetBatteryLevel(oldDSiBatteryLevel);
DSi_BPTWL::SetBatteryCharging(oldDSiBatteryCharging); DSi::I2C->GetBPTWL()->SetBatteryCharging(oldDSiBatteryCharging);
} }
else else
{ {
@ -132,7 +133,7 @@ void PowerManagementDialog::updateDSBatteryLevelControls()
void PowerManagementDialog::on_cbDSiBatteryCharging_toggled() void PowerManagementDialog::on_cbDSiBatteryCharging_toggled()
{ {
DSi_BPTWL::SetBatteryCharging(ui->cbDSiBatteryCharging->isChecked()); DSi::I2C->GetBPTWL()->SetBatteryCharging(ui->cbDSiBatteryCharging->isChecked());
} }
void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value) void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value)
@ -142,13 +143,13 @@ void PowerManagementDialog::on_sliderDSiBatteryLevel_valueChanged(int value)
u8 newBatteryLevel; u8 newBatteryLevel;
switch (value) switch (value)
{ {
case 0: newBatteryLevel = DSi_BPTWL::batteryLevel_AlmostEmpty; break; case 0: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_AlmostEmpty; break;
case 1: newBatteryLevel = DSi_BPTWL::batteryLevel_Low; break; case 1: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Low; break;
case 2: newBatteryLevel = DSi_BPTWL::batteryLevel_Half; break; case 2: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Half; break;
case 3: newBatteryLevel = DSi_BPTWL::batteryLevel_ThreeQuarters; break; case 3: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_ThreeQuarters; break;
case 4: newBatteryLevel = DSi_BPTWL::batteryLevel_Full; break; case 4: newBatteryLevel = DSi::I2C->GetBPTWL()->batteryLevel_Full; break;
} }
DSi_BPTWL::SetBatteryLevel(newBatteryLevel); DSi::I2C->GetBPTWL()->SetBatteryLevel(newBatteryLevel);
updateDSBatteryLevelControls(); updateDSBatteryLevelControls();
} }

View File

@ -583,8 +583,8 @@ void SetBatteryLevels()
{ {
if (NDS::ConsoleType == 1) if (NDS::ConsoleType == 1)
{ {
DSi_BPTWL::SetBatteryLevel(Config::DSiBatteryLevel); DSi::I2C->GetBPTWL()->SetBatteryLevel(Config::DSiBatteryLevel);
DSi_BPTWL::SetBatteryCharging(Config::DSiBatteryCharging); DSi::I2C->GetBPTWL()->SetBatteryCharging(Config::DSiBatteryCharging);
} }
else else
{ {

View File

@ -90,8 +90,9 @@
#include "Platform.h" #include "Platform.h"
#include "LocalMP.h" #include "LocalMP.h"
#include "Config.h" #include "Config.h"
#include "DSi_I2C.h"
#include "RTC.h" #include "RTC.h"
#include "DSi.h"
#include "DSi_I2C.h"
#include "Savestate.h" #include "Savestate.h"
@ -409,33 +410,33 @@ void EmuThread::run()
// Handle power button // Handle power button
if (Input::HotkeyDown(HK_PowerButton)) if (Input::HotkeyDown(HK_PowerButton))
{ {
DSi_BPTWL::SetPowerButtonHeld(currentTime); DSi::I2C->GetBPTWL()->SetPowerButtonHeld(currentTime);
} }
else if (Input::HotkeyReleased(HK_PowerButton)) else if (Input::HotkeyReleased(HK_PowerButton))
{ {
DSi_BPTWL::SetPowerButtonReleased(currentTime); DSi::I2C->GetBPTWL()->SetPowerButtonReleased(currentTime);
} }
// Handle volume buttons // Handle volume buttons
if (Input::HotkeyDown(HK_VolumeUp)) if (Input::HotkeyDown(HK_VolumeUp))
{ {
DSi_BPTWL::SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Up); DSi::I2C->GetBPTWL()->SetVolumeSwitchHeld(DSi::I2C->GetBPTWL()->volumeKey_Up);
} }
else if (Input::HotkeyReleased(HK_VolumeUp)) else if (Input::HotkeyReleased(HK_VolumeUp))
{ {
DSi_BPTWL::SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Up); DSi::I2C->GetBPTWL()->SetVolumeSwitchReleased(DSi::I2C->GetBPTWL()->volumeKey_Up);
} }
if (Input::HotkeyDown(HK_VolumeDown)) if (Input::HotkeyDown(HK_VolumeDown))
{ {
DSi_BPTWL::SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Down); DSi::I2C->GetBPTWL()->SetVolumeSwitchHeld(DSi::I2C->GetBPTWL()->volumeKey_Down);
} }
else if (Input::HotkeyReleased(HK_VolumeDown)) else if (Input::HotkeyReleased(HK_VolumeDown))
{ {
DSi_BPTWL::SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Down); DSi::I2C->GetBPTWL()->SetVolumeSwitchReleased(DSi::I2C->GetBPTWL()->volumeKey_Down);
} }
DSi_BPTWL::ProcessVolumeSwitchInput(currentTime); DSi::I2C->GetBPTWL()->ProcessVolumeSwitchInput(currentTime);
} }
if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep) if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep)
@ -562,7 +563,7 @@ void EmuThread::run()
if (Config::DSiVolumeSync && NDS::ConsoleType == 1) if (Config::DSiVolumeSync && NDS::ConsoleType == 1)
{ {
u8 volumeLevel = DSi_BPTWL::GetVolumeLevel(); u8 volumeLevel = DSi::I2C->GetBPTWL()->GetVolumeLevel();
if (volumeLevel != dsiVolumeLevel) if (volumeLevel != dsiVolumeLevel)
{ {
dsiVolumeLevel = volumeLevel; dsiVolumeLevel = volumeLevel;