-
Notifications
You must be signed in to change notification settings - Fork 561
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added dual emuNAND support, multi-payload loader with built-in screen…
… init (inspired by arm9select, thanks Fix94)
- Loading branch information
1 parent
8ce395c
commit dcb09a9
Showing
14 changed files
with
400 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#pragma once | ||
|
||
#include "types.h" | ||
|
||
#define HID_PAD ((~*(vu16 *)0x10146000) & 0xFFF) | ||
#define BUTTON_B (1 << 1) | ||
#define BUTTON_X (1 << 10) | ||
#define BUTTON_Y (1 << 11) | ||
#define BUTTON_SELECT (1 << 2) | ||
#define BUTTON_START (1 << 3) | ||
#define BUTTON_RIGHT (1 << 4) | ||
#define BUTTON_LEFT (1 << 5) | ||
#define BUTTON_UP (1 << 6) | ||
#define BUTTON_DOWN (1 << 7) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,4 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include <stdbool.h> | ||
|
||
//Common data types | ||
typedef uint8_t u8; | ||
typedef uint16_t u16; | ||
typedef uint32_t u32; | ||
typedef uint64_t u64; | ||
typedef volatile u8 vu8; | ||
typedef volatile u16 vu16; | ||
typedef volatile u32 vu32; | ||
typedef volatile u64 vu64; | ||
#include "../../types.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#include "i2c.h" | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
static const struct { u8 bus_id, reg_addr; } dev_data[] = { | ||
{0, 0x4A}, {0, 0x7A}, {0, 0x78}, | ||
{1, 0x4A}, {1, 0x78}, {1, 0x2C}, | ||
{1, 0x2E}, {1, 0x40}, {1, 0x44}, | ||
{2, 0xD6}, {2, 0xD0}, {2, 0xD2}, | ||
{2, 0xA4}, {2, 0x9A}, {2, 0xA0}, | ||
}; | ||
|
||
inline u8 i2cGetDeviceBusId(u8 device_id) { | ||
return dev_data[device_id].bus_id; | ||
} | ||
|
||
inline u8 i2cGetDeviceRegAddr(u8 device_id) { | ||
return dev_data[device_id].reg_addr; | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
static vu8* reg_data_addrs[] = { | ||
(vu8*)(I2C1_REG_OFF + I2C_REG_DATA), | ||
(vu8*)(I2C2_REG_OFF + I2C_REG_DATA), | ||
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA), | ||
}; | ||
|
||
inline vu8* i2cGetDataReg(u8 bus_id) { | ||
return reg_data_addrs[bus_id]; | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
static vu8* reg_cnt_addrs[] = { | ||
(vu8*)(I2C1_REG_OFF + I2C_REG_CNT), | ||
(vu8*)(I2C2_REG_OFF + I2C_REG_CNT), | ||
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT), | ||
}; | ||
|
||
inline vu8* i2cGetCntReg(u8 bus_id) { | ||
return reg_cnt_addrs[bus_id]; | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
inline void i2cWaitBusy(u8 bus_id) { | ||
while (*i2cGetCntReg(bus_id) & 0x80); | ||
} | ||
|
||
inline bool i2cGetResult(u8 bus_id) { | ||
i2cWaitBusy(bus_id); | ||
return (*i2cGetCntReg(bus_id) >> 4) & 1; | ||
} | ||
|
||
void i2cStop(u8 bus_id, u8 arg0) { | ||
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0; | ||
i2cWaitBusy(bus_id); | ||
*i2cGetCntReg(bus_id) = 0xC5; | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
bool i2cSelectDevice(u8 bus_id, u8 dev_reg) { | ||
i2cWaitBusy(bus_id); | ||
*i2cGetDataReg(bus_id) = dev_reg; | ||
*i2cGetCntReg(bus_id) = 0xC2; | ||
return i2cGetResult(bus_id); | ||
} | ||
|
||
bool i2cSelectRegister(u8 bus_id, u8 reg) { | ||
i2cWaitBusy(bus_id); | ||
*i2cGetDataReg(bus_id) = reg; | ||
*i2cGetCntReg(bus_id) = 0xC0; | ||
return i2cGetResult(bus_id); | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
|
||
u8 i2cReadRegister(u8 dev_id, u8 reg) { | ||
u8 bus_id = i2cGetDeviceBusId(dev_id); | ||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id); | ||
|
||
for (size_t i = 0; i < 8; i++) { | ||
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) { | ||
if (i2cSelectDevice(bus_id, dev_addr | 1)) { | ||
i2cWaitBusy(bus_id); | ||
i2cStop(bus_id, 1); | ||
i2cWaitBusy(bus_id); | ||
return *i2cGetDataReg(bus_id); | ||
} | ||
} | ||
*i2cGetCntReg(bus_id) = 0xC5; | ||
i2cWaitBusy(bus_id); | ||
} | ||
return 0xff; | ||
} | ||
|
||
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size) { | ||
u8 bus_id = i2cGetDeviceBusId(dev_id); | ||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id); | ||
|
||
size_t j = 0; | ||
while (!i2cSelectDevice(bus_id, dev_addr) | ||
|| !i2cSelectRegister(bus_id, reg) | ||
|| !i2cSelectDevice(bus_id, dev_addr | 1)) | ||
{ | ||
i2cWaitBusy(bus_id); | ||
*i2cGetCntReg(bus_id) = 0xC5; | ||
i2cWaitBusy(bus_id); | ||
if (++j >= 8) | ||
return false; | ||
} | ||
|
||
if (buf_size != 1) { | ||
for (size_t i = 0; i < buf_size - 1; i++) { | ||
i2cWaitBusy(bus_id); | ||
*i2cGetCntReg(bus_id) = 0xF0; | ||
i2cWaitBusy(bus_id); | ||
buffer[i] = *i2cGetDataReg(bus_id); | ||
} | ||
} | ||
|
||
i2cWaitBusy(bus_id); | ||
*i2cGetCntReg(bus_id) = 0xE1; | ||
i2cWaitBusy(bus_id); | ||
*buffer = *i2cGetDataReg(bus_id); | ||
return true; | ||
} | ||
|
||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data) { | ||
u8 bus_id = i2cGetDeviceBusId(dev_id); | ||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id); | ||
|
||
for (int i = 0; i < 8; i++) { | ||
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) { | ||
i2cWaitBusy(bus_id); | ||
*i2cGetDataReg(bus_id) = data; | ||
*i2cGetCntReg(bus_id) = 0xC1; | ||
i2cStop(bus_id, 0); | ||
if (i2cGetResult(bus_id)) | ||
return true; | ||
} | ||
*i2cGetCntReg(bus_id) = 0xC5; | ||
i2cWaitBusy(bus_id); | ||
} | ||
|
||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
#include "common.h" | ||
|
||
#define I2C1_REG_OFF 0x10161000 | ||
#define I2C2_REG_OFF 0x10144000 | ||
#define I2C3_REG_OFF 0x10148000 | ||
|
||
#define I2C_REG_DATA 0 | ||
#define I2C_REG_CNT 1 | ||
#define I2C_REG_CNTEX 2 | ||
#define I2C_REG_SCL 4 | ||
|
||
#define I2C_DEV_MCU 3 | ||
#define I2C_DEV_GYRO 10 | ||
#define I2C_DEV_IR 13 | ||
|
||
u8 i2cGetDeviceBusId(u8 device_id); | ||
u8 i2cGetDeviceRegAddr(u8 device_id); | ||
|
||
vu8* i2cGetDataReg(u8 bus_id); | ||
vu8* i2cGetCntReg(u8 bus_id); | ||
|
||
void i2cWaitBusy(u8 bus_id); | ||
bool i2cGetResult(u8 bus_id); | ||
u8 i2cGetData(u8 bus_id); | ||
void i2cStop(u8 bus_id, u8 arg0); | ||
|
||
bool i2cSelectDevice(u8 bus_id, u8 dev_reg); | ||
bool i2cSelectRegister(u8 bus_id, u8 reg); | ||
|
||
u8 i2cReadRegister(u8 dev_id, u8 reg); | ||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data); | ||
|
||
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,42 @@ | ||
#include "types.h" | ||
#include "buttons.h" | ||
#include "screeninit.h" | ||
#include "fatfs/ff.h" | ||
|
||
#define PAYLOAD_ADDRESS 0x23F00000 | ||
|
||
void main() | ||
{ | ||
FATFS fs; | ||
u32 loadPayload(const char *path){ | ||
FIL payload; | ||
unsigned int br; | ||
|
||
f_mount(&fs, "0:", 1); | ||
if(f_open(&payload, "rei/arm9payload.bin", FA_READ) == FR_OK) | ||
if(f_open(&payload, path, FA_READ) == FR_OK) | ||
{ | ||
f_read(&payload, (void *)PAYLOAD_ADDRESS, f_size(&payload), &br); | ||
f_read(&payload, (void*)PAYLOAD_ADDRESS, f_size(&payload), &br); | ||
f_close(&payload); | ||
|
||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
void main(){ | ||
FATFS fs; | ||
f_mount(&fs, "0:", 1); | ||
|
||
//Get pressed buttons | ||
u16 pressed = HID_PAD; | ||
|
||
if(((pressed & BUTTON_B) && loadPayload("/rei/payloads/b.bin")) || | ||
((pressed & BUTTON_X) && loadPayload("/rei/payloads/x.bin")) || | ||
((pressed & BUTTON_Y) && loadPayload("/rei/payloads/y.bin")) || | ||
((pressed & BUTTON_SELECT) && loadPayload("/rei/payloads/select.bin")) || | ||
((pressed & BUTTON_START) && loadPayload("/rei/payloads/start.bin")) || | ||
((pressed & BUTTON_RIGHT) && loadPayload("/rei/payloads/right.bin")) || | ||
((pressed & BUTTON_LEFT) && loadPayload("/rei/payloads/left.bin")) || | ||
((pressed & BUTTON_UP) && loadPayload("/rei/payloads/up.bin")) || | ||
((pressed & BUTTON_DOWN) && loadPayload("/rei/payloads/down.bin")) || | ||
loadPayload("/rei/payloads/default.bin")){ | ||
initLCD(); | ||
((void (*)())PAYLOAD_ADDRESS)(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#include "screeninit.h" | ||
#include "i2c.h" | ||
|
||
void initLCD() | ||
{ | ||
vu32 *const arm11 = (u32 *)0x1FFFFFF8; | ||
|
||
void __attribute__((naked)) ARM11() | ||
{ | ||
*(vu32 *)0x10141200 = 0x1007F; | ||
*(vu32 *)0x10202014 = 0x00000001; | ||
*(vu32 *)0x1020200C &= 0xFFFEFFFE; | ||
*(vu32 *)0x10202240 = 0x39; | ||
*(vu32 *)0x10202A40 = 0x39; | ||
*(vu32 *)0x10202244 = 0x1023E; | ||
*(vu32 *)0x10202A44 = 0x1023E; | ||
|
||
// Top screen | ||
*(vu32 *)0x10400400 = 0x000001c2; | ||
*(vu32 *)0x10400404 = 0x000000d1; | ||
*(vu32 *)0x10400408 = 0x000001c1; | ||
*(vu32 *)0x1040040c = 0x000001c1; | ||
*(vu32 *)0x10400410 = 0x00000000; | ||
*(vu32 *)0x10400414 = 0x000000cf; | ||
*(vu32 *)0x10400418 = 0x000000d1; | ||
*(vu32 *)0x1040041c = 0x01c501c1; | ||
*(vu32 *)0x10400420 = 0x00010000; | ||
*(vu32 *)0x10400424 = 0x0000019d; | ||
*(vu32 *)0x10400428 = 0x00000002; | ||
*(vu32 *)0x1040042c = 0x00000192; | ||
*(vu32 *)0x10400430 = 0x00000192; | ||
*(vu32 *)0x10400434 = 0x00000192; | ||
*(vu32 *)0x10400438 = 0x00000001; | ||
*(vu32 *)0x1040043c = 0x00000002; | ||
*(vu32 *)0x10400440 = 0x01960192; | ||
*(vu32 *)0x10400444 = 0x00000000; | ||
*(vu32 *)0x10400448 = 0x00000000; | ||
*(vu32 *)0x1040045C = 0x00f00190; | ||
*(vu32 *)0x10400460 = 0x01c100d1; | ||
*(vu32 *)0x10400464 = 0x01920002; | ||
*(vu32 *)0x10400468 = 0x18300000; | ||
*(vu32 *)0x10400470 = 0x80341; | ||
*(vu32 *)0x10400474 = 0x00010501; | ||
*(vu32 *)0x10400478 = 0; | ||
*(vu32 *)0x10400490 = 0x000002D0; | ||
*(vu32 *)0x1040049C = 0x00000000; | ||
|
||
// Disco register | ||
for(vu32 i = 0; i < 256; i++) | ||
*(vu32 *)0x10400484 = 0x10101 * i; | ||
|
||
// Bottom screen | ||
*(vu32 *)0x10400500 = 0x000001c2; | ||
*(vu32 *)0x10400504 = 0x000000d1; | ||
*(vu32 *)0x10400508 = 0x000001c1; | ||
*(vu32 *)0x1040050c = 0x000001c1; | ||
*(vu32 *)0x10400510 = 0x000000cd; | ||
*(vu32 *)0x10400514 = 0x000000cf; | ||
*(vu32 *)0x10400518 = 0x000000d1; | ||
*(vu32 *)0x1040051c = 0x01c501c1; | ||
*(vu32 *)0x10400520 = 0x00010000; | ||
*(vu32 *)0x10400524 = 0x0000019d; | ||
*(vu32 *)0x10400528 = 0x00000052; | ||
*(vu32 *)0x1040052c = 0x00000192; | ||
*(vu32 *)0x10400530 = 0x00000192; | ||
*(vu32 *)0x10400534 = 0x0000004f; | ||
*(vu32 *)0x10400538 = 0x00000050; | ||
*(vu32 *)0x1040053c = 0x00000052; | ||
*(vu32 *)0x10400540 = 0x01980194; | ||
*(vu32 *)0x10400544 = 0x00000000; | ||
*(vu32 *)0x10400548 = 0x00000011; | ||
*(vu32 *)0x1040055C = 0x00f00140; | ||
*(vu32 *)0x10400560 = 0x01c100d1; | ||
*(vu32 *)0x10400564 = 0x01920052; | ||
*(vu32 *)0x10400568 = 0x18300000 + 0x46500; | ||
*(vu32 *)0x10400570 = 0x80301; | ||
*(vu32 *)0x10400574 = 0x00010501; | ||
*(vu32 *)0x10400578 = 0; | ||
*(vu32 *)0x10400590 = 0x000002D0; | ||
*(vu32 *)0x1040059C = 0x00000000; | ||
|
||
// Disco register | ||
for(vu32 i = 0; i < 256; i++) | ||
*(vu32 *)0x10400584 = 0x10101 * i; | ||
|
||
// Enable backlight | ||
i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); | ||
|
||
*(vu32 *)0x10400468 = 0x18300000; | ||
*(vu32 *)0x1040046c = 0x18300000; | ||
*(vu32 *)0x10400494 = 0x18300000; | ||
*(vu32 *)0x10400498 = 0x18300000; | ||
*(vu32 *)0x10400568 = 0x18346500; | ||
*(vu32 *)0x1040056c = 0x18346500; | ||
|
||
//Clear ARM11 entry offset | ||
*arm11 = 0; | ||
|
||
//Wait for the entry to be set | ||
while(!*arm11); | ||
//Jump to it | ||
((void (*)())*arm11)(); | ||
} | ||
|
||
//Determine if screen was already inited | ||
if(*(vu8 *)0x10141200 != 0x1) return; | ||
|
||
//Set CakeBrah framebuffers | ||
*(vu32 *)0x23FFFE00 = 0x18300000; | ||
*(vu32 *)0x23FFFE04 = 0x18300000; | ||
*(vu32 *)0x23FFFE08 = 0x18346500; | ||
|
||
*arm11 = (u32)ARM11; | ||
|
||
//This delay is needed for some reason | ||
for(vu32 i = 0; i < 0x2000; ++i); | ||
while(*arm11); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
#include "types.h" | ||
|
||
void initLCD(); |
Oops, something went wrong.