From 62a605cd9223e63ebeacc6f1270f98447592ebe8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 6 Aug 2019 02:27:54 +0200 Subject: lay base for camera shito --- src/DSi_Camera.cpp | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/DSi_Camera.cpp (limited to 'src/DSi_Camera.cpp') diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp new file mode 100644 index 0000000..66d08cb --- /dev/null +++ b/src/DSi_Camera.cpp @@ -0,0 +1,143 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include "DSi_Camera.h" + + +DSi_Camera* DSi_Camera0; // 78 / facing outside +DSi_Camera* DSi_Camera1; // 7A / selfie cam + + +bool DSi_Camera::Init() +{ + DSi_Camera0 = new DSi_Camera(0); + DSi_Camera1 = new DSi_Camera(1); + + return true; +} + +void DSi_Camera::DeInit() +{ + delete DSi_Camera0; + delete DSi_Camera1; +} + +void DSi_Camera::Reset() +{ + DSi_Camera0->ResetCam(); + DSi_Camera1->ResetCam(); +} + + +DSi_Camera::DSi_Camera(u32 num) +{ + Num = num; +} + +DSi_Camera::~DSi_Camera() +{ + // +} + +void DSi_Camera::ResetCam() +{ + DataPos = 0; + RegAddr = 0; + RegData = 0; +} + + +void DSi_Camera::Start() +{ +} + +u8 DSi_Camera::Read(bool last) +{ + u8 ret; + + if (DataPos < 2) + { + printf("DSi_Camera: WHAT??\n"); + ret = 0; + } + else + { + if (DataPos & 0x1) + { + ret = RegData & 0xFF; + RegAddr += 2; // checkme + } + else + { + RegData = ReadReg(RegAddr); + ret = RegData >> 8; + } + } + + if (last) DataPos = 0; + else DataPos++; + + return ret; +} + +void DSi_Camera::Write(u8 val, bool last) +{ + if (DataPos < 2) + { + if (DataPos == 0) + RegAddr = val << 8; + else + RegAddr |= val; + + if (RegAddr & 0x1) printf("DSi_Camera: !! UNALIGNED REG ADDRESS %04X\n", RegAddr); + } + else + { + if (DataPos & 0x1) + { + RegData |= val; + WriteReg(RegAddr, RegData); + RegAddr += 2; // checkme + } + else + { + RegData = val << 8; + } + } + + if (last) DataPos = 0; + else DataPos++; +} + +u16 DSi_Camera::ReadReg(u16 addr) +{ + switch (addr) + { + case 0x301A: return 0x0002; // HAX + } + + printf("DSi_Camera%d: unknown read %04X\n", Num, addr); + return 0; +} + +void DSi_Camera::WriteReg(u16 addr, u16 val) +{ + printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val); +} -- cgit v1.2.3 From 28a9c7d9d1c44066e91664101362eab69ab12f4d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 6 Aug 2019 13:06:14 +0200 Subject: camera: enough stub to pass firmware init --- src/DSi_Camera.cpp | 25 ++++++++++++++++++++++++- src/DSi_Camera.h | 3 +++ src/DSi_I2C.cpp | 14 +++++++------- 3 files changed, 34 insertions(+), 8 deletions(-) (limited to 'src/DSi_Camera.cpp') diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp index 66d08cb..45061b2 100644 --- a/src/DSi_Camera.cpp +++ b/src/DSi_Camera.cpp @@ -61,6 +61,9 @@ void DSi_Camera::ResetCam() DataPos = 0; RegAddr = 0; RegData = 0; + + PLLCnt = 0; + StandbyCnt = 0x4029; // checkme } @@ -130,7 +133,11 @@ u16 DSi_Camera::ReadReg(u16 addr) { switch (addr) { - case 0x301A: return 0x0002; // HAX + case 0x0000: return 0x2280; // chip ID + case 0x0014: return PLLCnt; + case 0x0018: return StandbyCnt; + + case 0x301A: return ((~StandbyCnt) & 0x4000) >> 12; } printf("DSi_Camera%d: unknown read %04X\n", Num, addr); @@ -139,5 +146,21 @@ u16 DSi_Camera::ReadReg(u16 addr) void DSi_Camera::WriteReg(u16 addr, u16 val) { + switch (addr) + { + case 0x0014: + // shouldn't be instant either? + val &= 0x7FFF; + val |= ((val & 0x0002) << 14); + PLLCnt = val; + return; + case 0x0018: + // TODO: this shouldn't be instant, but uh + val &= 0x003F; + val |= ((val & 0x0001) << 14); + StandbyCnt = val; + return; + } + printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val); } diff --git a/src/DSi_Camera.h b/src/DSi_Camera.h index eba35cb..78629b5 100644 --- a/src/DSi_Camera.h +++ b/src/DSi_Camera.h @@ -46,6 +46,9 @@ private: u16 ReadReg(u16 addr); void WriteReg(u16 addr, u16 val); + + u16 PLLCnt; + u16 StandbyCnt; }; diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index 907d0ef..ffb724f 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -156,7 +156,7 @@ void Reset() void WriteCnt(u8 val) { - //printf("I2C: write CNT %02X\n", val); + //printf("I2C: write CNT %02X, %08X\n", val, NDS::GetPC(1)); // TODO: check ACK flag // TODO: transfer delay @@ -179,11 +179,11 @@ void WriteCnt(u8 val) case 0x7A: Data = DSi_Camera1->Read(islast); break; default: printf("I2C: read on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, 0, islast); - Data = 0; + 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); } else { @@ -194,7 +194,7 @@ void WriteCnt(u8 val) if (val & (1<<1)) { Device = 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) { @@ -203,13 +203,13 @@ void WriteCnt(u8 val) case 0x7A: DSi_Camera1->Start(); break; default: printf("I2C: %s start on unknown device %02X\n", (Data&0x01)?"read":"write", Device); - ack = false; + //ack = false; break; } } 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) { @@ -218,7 +218,7 @@ void WriteCnt(u8 val) case 0x7A: DSi_Camera1->Write(Data, islast); break; default: printf("I2C: write on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); - ack = false; + //ack = false; break; } } -- cgit v1.2.3