convert DSi I2C and camera
This commit is contained in:
parent
7837c169a1
commit
54ebf1b1b2
42
src/DSi.cpp
42
src/DSi.cpp
|
@ -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));
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
215
src/DSi_I2C.cpp
215
src/DSi_I2C.cpp
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
225
src/DSi_I2C.h
225
src/DSi_I2C.h
|
@ -22,95 +22,162 @@
|
||||||
#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
|
|
||||||
{
|
|
||||||
batteryLevel_Critical = 0x0,
|
|
||||||
batteryLevel_AlmostEmpty = 0x1,
|
|
||||||
batteryLevel_Low = 0x3,
|
|
||||||
batteryLevel_Half = 0x7,
|
|
||||||
batteryLevel_ThreeQuarters = 0xB,
|
|
||||||
batteryLevel_Full = 0xF
|
|
||||||
};
|
};
|
||||||
|
|
||||||
u8 GetBatteryLevel();
|
class DSi_BPTWL : public DSi_I2CDevice
|
||||||
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,
|
public:
|
||||||
volumeKey_Down,
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
batteryLevel_Critical = 0x0,
|
||||||
|
batteryLevel_AlmostEmpty = 0x1,
|
||||||
|
batteryLevel_Low = 0x3,
|
||||||
|
batteryLevel_Half = 0x7,
|
||||||
|
batteryLevel_ThreeQuarters = 0xB,
|
||||||
|
batteryLevel_Full = 0xF
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
volumeKey_Up,
|
||||||
|
volumeKey_Down,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
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_PowerButtonPressed = 0x08, // Triggered after pressing the power button
|
||||||
|
IRQ_BatteryEmpty = 0x10, //
|
||||||
|
IRQ_BatteryLow = 0x20, // Triggered when the battery level reaches 1
|
||||||
|
IRQ_VolumeSwitchPressed = 0x40, // Triggered once when the volume sliders are first pressed and repeatedly when held down
|
||||||
|
/*
|
||||||
|
Bit 2 (0x04) could be set when holding the power button for more than 5 seconds? (forced power off)
|
||||||
|
It is unknown whether it is set as the console powers off immediately.
|
||||||
|
Bit 7 (0x80) is unused?
|
||||||
|
Both bits are never used by the official ARM7 libraries, but could have some undocumented hardware functionality (?).
|
||||||
|
*/
|
||||||
|
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();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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();
|
class DSi_I2CHost
|
||||||
void DoPowerButtonReset();
|
|
||||||
void DoPowerButtonShutdown();
|
|
||||||
void DoPowerButtonForceShutdown();
|
|
||||||
void DoVolumeSwitchPress(u32 key);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
{
|
||||||
IRQ_PowerButtonReset = 0x01, // Triggered after releasing the power button quickly
|
public:
|
||||||
IRQ_PowerButtonShutdown = 0x02, // Triggered after holding the power button for less than a second
|
DSi_I2CHost();
|
||||||
IRQ_PowerButtonPressed = 0x08, // Triggered after pressing the power button
|
~DSi_I2CHost();
|
||||||
IRQ_BatteryEmpty = 0x10, //
|
void Reset();
|
||||||
IRQ_BatteryLow = 0x20, // Triggered when the battery level reaches 1
|
void DoSavestate(Savestate* file);
|
||||||
IRQ_VolumeSwitchPressed = 0x40, // Triggered once when the volume sliders are first pressed and repeatedly when held down
|
|
||||||
/*
|
DSi_BPTWL* GetBPTWL() { return BPTWL; }
|
||||||
Bit 2 (0x04) could be set when holding the power button for more than 5 seconds? (forced power off)
|
DSi_Camera* GetOuterCamera() { return Camera0; }
|
||||||
It is unknown whether it is set as the console powers off immediately.
|
DSi_Camera* GetInnerCamera() { return Camera1; }
|
||||||
Bit 7 (0x80) is unused?
|
|
||||||
Both bits are never used by the official ARM7 libraries, but could have some undocumented hardware functionality (?).
|
u8 ReadCnt() { return Cnt; }
|
||||||
*/
|
void WriteCnt(u8 val);
|
||||||
IRQ_ValidMask = 0x7B,
|
|
||||||
|
u8 ReadData();
|
||||||
|
void WriteData(u8 val);
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8 Cnt;
|
||||||
|
u8 Data;
|
||||||
|
|
||||||
|
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();
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetIRQ(u8 irqFlag);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace DSi_I2C
|
|
||||||
{
|
|
||||||
|
|
||||||
extern u8 Cnt;
|
|
||||||
|
|
||||||
bool Init();
|
|
||||||
void DeInit();
|
|
||||||
void Reset();
|
|
||||||
void DoSavestate(Savestate* file);
|
|
||||||
|
|
||||||
void WriteCnt(u8 val);
|
|
||||||
|
|
||||||
u8 ReadData();
|
|
||||||
void WriteData(u8 val);
|
|
||||||
|
|
||||||
//void TransferDone(u32 param);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DSI_I2C_H
|
#endif // DSI_I2C_H
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/SPI.h
10
src/SPI.h
|
@ -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]; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue