added 3ds11. untested. Porbably won#t work

This commit is contained in:
Morten Delenk 2017-04-29 17:04:39 +00:00
parent d994c70468
commit 65d9d93c24
12 changed files with 420 additions and 1 deletions

View file

@ -0,0 +1,3 @@
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include")
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")

View file

@ -0,0 +1,36 @@
ENTRY(_start)
SECTIONS {
. = 0x20000000;
kernel_start = .;
.text : {
KEEP(*(.text.boot));
*(.text)
}
.data : {
start_ctors = .;
KEEP(*(.init_array));
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)));
KEEP(*(.ctors));
end_ctors = .;
start_dtors = .;
KEEP(*(.fini_array));
KEEP(*(.fini_array.*));
KEEP(*(.dtors));
end_dtors = .;
start_eh_frame = .;
KEEP(*(.eh_frame));
KEEP(*(.eh_frame.*));
QUAD(0);
KEEP(*(.gcc_except_table));
KEEP(*(.gcc_except_table.*));
*(.data)
}
.rodata : {
*(.rodata)
}
.bss : {
*(.bss)
*(COMMON)
}
kernel_end = .;
}

View file

@ -0,0 +1,11 @@
#include "../../../hw/3ds11/picafb/picafb.hpp"
#include <base.hpp>
#include <config.h>
PICAfb term;
void main();
extern "C" void start() { main(); }
void drivers_init() {
setMainTTY(&term);
--term;
}

View file

@ -0,0 +1,25 @@
.arm
.arch armv6k
.fpu vfpv2
.align 4
.global _start
.extern start
.section .text.boot
_start:
CPSID aif //Disable interrupts
ldr sp, =kernel_stack
//Enable FPU
mov r0, #0
mov r1, #0xF00000
mcr p15, 0, r1, c1, c0, 2
mcr p15, 0, r0, c7, c5, 4
mov r1, #0x40000000
mov r2, #0x3C00000
fmxr fpexc, r1
fmxr fpscr, r2
//Start MTGos
blx start
.section .bss
.space 16384
kernel_stack:

View file

@ -0,0 +1,3 @@
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/include")
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")

View file

@ -3,4 +3,10 @@ config["ENABLE_I2C"] = get_yes_no("Enable i2c driver", True)
if config["ENABLE_I2C"]: if config["ENABLE_I2C"]:
config["PROTECT_MCU"] = get_yes_no("Prevent writes to MCU firmware (Device 3, Register 5)", True) config["PROTECT_MCU"] = get_yes_no("Prevent writes to MCU firmware (Device 3, Register 5)", True)
config["ENABLE_SCREENINIT"] = get_yes_no("Enable screeninit.", True) config["ENABLE_SCREENINIT"] = get_yes_no("Enable screeninit.", True)
add_driver(False, "i2c")
if config["ENABLE_SCREENINIT"]:
add_driver(False, "mcu")
add_driver(True, "framebuffer")
add_driver(False, "picafb")
print("Enable complete Unicode font: NO (because of the size)")
config["ENABLE_FRAMEBUFFER_UNICODE"] = False

View file

@ -0,0 +1,66 @@
#include "i2c.hpp"
struct I2CBus {
volatile uint8_t data;
volatile uint8_t ctl;
uint16_t cntex;
uint16_t scl;
} __attribute__((packed));
I2CBus *buses[] = {(I2CBus *)0x10161000, (I2CBus *)0x10144000, (I2CBus *)0x10148000};
I2C::I2C() {}
I2C::~I2C() {}
auto I2C::waitBusy() -> void {
while (buses[busID]->ctl & 0x80)
;
}
auto I2C::getResult() -> bool {
waitBusy();
return buses[busID]->ctl & 0x10;
}
auto I2C::stop() -> bool {
buses[busID]->ctl = 0xC0;
waitBusy();
buses[busID]->ctl = 0xC5;
}
auto I2C::selectDev(int dev) -> bool {
static int buss[] = {1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 1, 3};
static int addr[] = {0x4a, 0x7a, 0x78, 0x4a, 0x78, 0x2C, 0x2E, 0x40, 0x44,
0xA6, 0xD0, 0xD2, 0xA4, 0x9A, 0xA0, 0xEE, 0x40, 0x54};
currDev = dev;
busID = buss[dev];
waitBusy();
buses[busID]->data = addr[dev];
buses[busID]->ctl = 0xC2;
return getResult();
}
auto I2C::selectReg(int reg) -> bool {
#ifdef PROTECT_MCU
if ((currReg == 3) && (reg == 5)) return false;
#endif
currReg = reg;
waitBusy();
buses[busID]->data = (uint8_t)reg;
buses[busID]->ctl = 0xC0;
return getResult();
}
auto I2C::write(uint8_t data) -> bool {
for (int i = 0; i < 10; i++) {
waitBusy();
buses[busID]->data = data;
buses[busID]->ctl = 0xC1;
if (getResult()) { return true; }
stop();
selectDev(currDev);
selectReg(currReg);
}
return false;
}
auto I2C::read() -> uint8_t {
waitBusy();
buses[busID]->ctl = 0xE1;
waitBusy();
uint8_t data = buses[busID]->data;
buses[busID]->ctl |= 0x10;
getResult();
stop();
return data;
}

View file

@ -0,0 +1,20 @@
#pragma once
#include <config.h>
#include <stdint.h>
class I2C {
private:
int currDev;
int currReg;
int busID;
public:
I2C();
~I2C();
auto waitBusy() -> void;
auto getResult() -> bool;
auto stop() -> bool;
auto selectDev(int dev) -> bool;
auto selectReg(int reg) -> bool;
auto write(uint8_t data) -> bool;
auto read() -> uint8_t;
};

View file

@ -0,0 +1,62 @@
#include "mcu.hpp"
namespace MCU {
I2C access;
uint8_t HIDStatus;
static auto read(int reg) -> unsigned char {
access.selectDev(3);
access.selectReg(reg);
return access.read();
}
static auto write(int reg, uint8_t value) -> void {
access.selectDev(3);
access.selectReg(reg);
access.write(value);
}
auto getVersionLo() -> unsigned char { return read(0); }
auto getVersionHi() -> unsigned char { return read(1); }
auto getLCDFlickerTop() -> unsigned char { return read(3); }
auto setLCDFlickerTop(unsigned char val) -> void { write(3, val); }
auto getLCDFlickerBottom() -> unsigned char { return read(4); }
auto setLCDFlickerBottom(unsigned char val) -> void { write(4, val); }
auto get3DSlider() -> unsigned char { return read(8); }
auto getVolume() -> unsigned char { return read(9); }
auto getBatteryPercent() -> unsigned char { return read(11); }
auto getSystemVoltage() -> unsigned char { return read(13); }
auto isCharging() -> bool { return read(15) & 0x10; }
auto isOpen() -> bool { return read(15) & 0x2; }
auto updateHIDStatus() -> void { HIDStatus = read(16); }
auto powerButtonPressed() -> bool { return HIDStatus & 0x1; }
auto powerButtonLongPressed() -> bool { return HIDStatus & 0x2; }
auto homeButtonPressed() -> bool { return HIDStatus & 0x4; }
auto homeButtonReleased() -> bool { return HIDStatus & 0x8; }
auto wifiEnabled() -> bool { return HIDStatus & 0x10; }
auto closed() -> bool { return HIDStatus & 0x20; }
auto opened() -> bool { return HIDStatus & 0x40; }
auto poweroff() -> void { write(32, 1); }
auto reboot() -> void { write(32, 4); }
auto enableTopLCD() -> void { write(34, 0b100010); }
auto disableTopLCD() -> void { write(34, 0b010010); }
auto enableBottomLCD() -> void { write(34, 0b1010); }
auto disableBottomLCD() -> void { write(34, 0b0110); }
auto setWifiLED(char val) -> void { write(0x2A, (unsigned char)val); }
auto setCameraLED(char val) -> void { write(0x2B, (unsigned char)val); }
auto set3DLED(char val) -> void { write(0x2C, (unsigned char)val); }
auto getRTC(RTC_date *date) -> void {
auto bcdToVal = [](unsigned char c) -> unsigned char { return (c & 0xF) + (10 * (c >> 4)); };
date->seconds = bcdToVal(read(0x30));
date->minutes = bcdToVal(read(0x31));
date->hours = bcdToVal(read(0x32));
date->days = bcdToVal(read(0x34));
date->months = bcdToVal(read(0x35));
date->years = bcdToVal(read(0x36));
}
auto setRTC(RTC_date *date) -> void {
auto valToBCD = [](unsigned char c) -> unsigned char { return (c % 10) + (c / 10) << 4; };
write(0x30, valToBCD(date->seconds));
write(0x31, valToBCD(date->minutes));
write(0x32, valToBCD(date->hours));
write(0x34, valToBCD(date->days));
write(0x35, valToBCD(date->months));
write(0x36, valToBCD(date->years));
}
}

View file

@ -0,0 +1,45 @@
#pragma once
#include "../i2c/i2c.hpp"
namespace MCU {
extern I2C access;
auto getVersionLo() -> unsigned char;
auto getVersionHi() -> unsigned char;
auto getLCDFlickerTop() -> unsigned char;
auto setLCDFlickerTop(unsigned char) -> void;
auto getLCDFlickerBottom() -> unsigned char;
auto setLCDFlickerTop(unsigned char) -> void;
auto get3DSlider() -> unsigned char;
auto getVolume() -> unsigned char;
auto getBatteryPercent() -> unsigned char;
auto getSystemVoltage() -> unsigned char;
auto isCharging() -> bool;
auto isOpen() -> bool;
extern uint8_t HIDStatus;
auto updateHIDStatus() -> void;
auto powerButtonPressed() -> bool;
auto powerButtonLongPressed() -> bool;
auto homeButtonPressed() -> bool;
auto homeButtonReleased() -> bool;
auto wifiEnabled() -> bool;
auto closed() -> bool;
auto opened() -> bool;
auto poweroff() -> void;
auto reboot() -> void;
auto enableTopLCD() -> void;
auto disableTopLCD() -> void;
auto enableBottomLCD() -> void;
auto disableBottomLCD() -> void;
auto setWifiLED(char val) -> void;
auto setCameraLED(char val) -> void;
auto set3DLED(char val) -> void;
struct RTC_date {
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
unsigned char days;
unsigned char months;
unsigned char years;
};
auto getRTC(RTC_date *) -> void;
auto setRTC(RTC_date *) -> void;
}

View file

@ -0,0 +1,132 @@
#include "picafb.hpp"
#include <config.h>
#ifdef ENABLE_SCREENINIT
#include "../mcu/mcu.hpp"
#endif
#define GL_RGBA8_OES 0
#define GL_RGB8_OES 1
#define GL_RGB565_OES 2
#define GL_RGB5_A1_OES 3
#define GL_RGBA4_OES 4
union FBFormat {
int val;
struct {
char format : 3;
char unused1 : 2;
bool enable3D : 1;
bool mainScreen : 1;
bool unused2 : 1;
char noRainbowStrip : 2;
char unused3 : 22;
} contents;
};
struct PDC {
int unused1[0x17];
int size;
int unused2[2];
void *leftFB[2];
int format;
int unused3;
int fbselect;
int unused4[2];
int rainbow;
int unused5[2];
int stride;
void *rightFB[2];
int padding[2];
} __attribute__((packed));
PICAfb::PICAfb() : Framebuffer(25, 30) {
#ifdef ENABLE_SCREENINIT
MCU::enableTopLCD();
MCU::enableBottomLCD();
*((uint32_t *)0x10141200) = 0x1007F; // Enable Backlights and GPU IO region
*((uint32_t *)0x10202014) = 1;
*((uint32_t *)0x1020200C) &= 0xFFFEFFFE;
*((uint32_t *)0x10202240) = 0x3F; // Top screen brightness
*((uint32_t *)0x10202A40) = 0x3F; // Bottom screen brightness
*((uint32_t *)0x10202244) = 0x1023E;
*((uint32_t *)0x10202A44) = 0x1023E;
PDC *top = (PDC *)0x10400400, *bottom = (PDC *)0x10400500;
top->unused1[0] = 0x000001c2;
top->unused1[1] = 0x000000d1;
top->unused1[2] = 0x000001c1;
top->unused1[3] = 0x000001c1;
top->unused1[4] = 0x00000000;
top->unused1[5] = 0x000000cf;
top->unused1[6] = 0x000000d1;
top->unused1[7] = 0x01c501c1;
top->unused1[8] = 0x00010000;
top->unused1[9] = 0x0000019d;
top->unused1[10] = 0x00000002;
top->unused1[11] = 0x00000192;
top->unused1[12] = 0x00000192;
top->unused1[13] = 0x00000192;
top->unused1[14] = 0x00000001;
top->unused1[15] = 0x00000002;
top->unused1[16] = 0x01960192;
top->unused1[17] = 0x00000000;
top->unused1[18] = 0x00000000;
top->size = 0x00f00190; // 400*240
top->unused2[0] = 0x01c100d1;
top->unused2[1] = 0x01920002;
top->leftFB[0] = (void *)0x18300000; // Beginning of VRAM
FBFormat a;
a.val = 0;
a.contents.format = GL_RGB8_OES;
a.contents.mainScreen = true;
a.contents.noRainbowStrip = 3;
a.val |= 0x80000;
top->format = a.val;
top->unused3 = 0x00010501;
top->fbselect = 0;
top->stride = 0x000002D0;
top->padding[1] = 0x00000000;
// Rainbow register
for (uint32_t i = 0; i < 256; i++) top->rainbow = 0x10101 * i;
bottom->unused1[0] = 0x000001c2;
bottom->unused1[1] = 0x000000d1;
bottom->unused1[2] = 0x000001c1;
bottom->unused1[3] = 0x000001c1;
bottom->unused1[4] = 0x000000cd;
bottom->unused1[5] = 0x000000cf;
bottom->unused1[6] = 0x000000d1;
bottom->unused1[7] = 0x01c501c1;
bottom->unused1[8] = 0x00010000;
bottom->unused1[9] = 0x0000019d;
bottom->unused1[10] = 0x00000052;
bottom->unused1[11] = 0x00000192;
bottom->unused1[12] = 0x00000192;
bottom->unused1[13] = 0x0000004f;
bottom->unused1[14] = 0x00000050;
bottom->unused1[15] = 0x00000052;
bottom->unused1[16] = 0x01980194;
bottom->unused1[17] = 0x00000000;
bottom->unused1[18] = 0x00000011;
bottom->size = 0x00f00140; // 320*240
bottom->unused2[0] = 0x01c100d1;
bottom->unused2[1] = 0x01920052;
bottom->leftFB[0] = (void *)(0x18300000 + 0x46500); // Directly at the beginning of top FB
bottom->format = a.val;
bottom->unused3 = 0x00010501;
bottom->fbselect = 0;
bottom->stride = 0x2D0;
bottom->padding[0] = 0;
// Rainbow register
for (uint32_t i = 0; i < 256; i++) top->rainbow = 0x10101 * i;
#endif
}
PICAfb::~PICAfb() {}
auto PICAfb::plotPixel(int x, int y, int col) -> void {
unsigned char *lfb = (unsigned char *)0x18300000;
// XXX I know it's rotated. But I need more vertical space than horizonal space.
int off = y * 240 + x;
for (int i = 0; i < 3; i++) {
lfb[off++] = col;
col >>= 8;
}
}

View file

@ -0,0 +1,10 @@
#pragma once
#include "../../framebuffer/framebuffer.hpp"
class PICAfb : public Framebuffer {
protected:
virtual auto plotPixel(int x, int y, int col) -> void;
public:
PICAfb();
virtual ~PICAfb();
};