forked from Mirror/GodMode9
Added brightness adjustment through the volume slider, made the ARM11 finally do something rather than sit and wait for the entrypoint
This commit is contained in:
parent
ed257e9216
commit
b56ca0e8b8
2
Makefile
2
Makefile
@ -23,7 +23,7 @@ endif
|
||||
BUILD := build
|
||||
SOURCES := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/quicklz
|
||||
DATA := data
|
||||
INCLUDES := source source/common source/font source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/quicklz
|
||||
INCLUDES := common source source/common source/font source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/quicklz
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
|
68
common/cpu.h
Normal file
68
common/cpu.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Written by Wolfvak, specially sublicensed under the GPLv2
|
||||
Read LICENSE for more details
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#define asm __asm volatile
|
||||
|
||||
static inline u32 CPU_ReadCPSR(void)
|
||||
{
|
||||
u32 cpsr;
|
||||
asm("mrs %0, cpsr\n\t":"=r"(cpsr));
|
||||
return cpsr;
|
||||
}
|
||||
|
||||
static inline void CPU_WriteCPSR_c(u32 cpsr)
|
||||
{
|
||||
asm("msr cpsr_c, %0\n\t"::"r"(cpsr));
|
||||
return;
|
||||
}
|
||||
|
||||
static inline u32 CPU_ReadCR(void)
|
||||
{
|
||||
u32 cr;
|
||||
asm("mrc p15, 0, %0, c1, c0, 0\n\t":"=r"(cr));
|
||||
return cr;
|
||||
}
|
||||
|
||||
static inline void CPU_WriteCR(u32 cr)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c1, c0, 0\n\t"::"r"(cr));
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void CPU_DisableIRQ(void)
|
||||
{
|
||||
#ifdef ARM9
|
||||
CPU_WriteCPSR_c(CPU_ReadCPSR() | (0xC0));
|
||||
#else
|
||||
asm("cpsid if\n\t");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void CPU_EnableIRQ(void)
|
||||
{
|
||||
#ifdef ARM9
|
||||
CPU_WriteCPSR_c(CPU_ReadCPSR() & ~(0xC0));
|
||||
#else
|
||||
asm("cpsie if\n\t");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void CPU_EnterCritical(u32 *ss)
|
||||
{
|
||||
*ss = CPU_ReadCPSR();
|
||||
CPU_DisableIRQ();
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void CPU_LeaveCritical(u32 *ss)
|
||||
{
|
||||
CPU_WriteCPSR_c(*ss);
|
||||
return;
|
||||
}
|
101
common/pxi.h
Normal file
101
common/pxi.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
Written by Wolfvak, specially sublicensed under the GPLv2
|
||||
Read LICENSE for more details
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#ifdef ARM9
|
||||
#define PXI_BASE (0x10008000)
|
||||
#define IRQ_PXI_SYNC (12)
|
||||
#else
|
||||
#define PXI_BASE (0x10163000)
|
||||
#define IRQ_PXI_SYNC (80)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PXI_NOCMD = 0,
|
||||
PXI_SETBRIGHTNESS = 1
|
||||
};
|
||||
|
||||
#define PXI_SYNC_RECV ((volatile uint8_t*)(PXI_BASE + 0x00))
|
||||
#define PXI_SYNC_SEND ((volatile uint8_t*)(PXI_BASE + 0x01))
|
||||
#define PXI_SYNC_IRQ ((volatile uint8_t*)(PXI_BASE + 0x03))
|
||||
#define PXI_CNT ((volatile uint16_t*)(PXI_BASE + 0x04))
|
||||
#define PXI_SEND ((volatile uint32_t*)(PXI_BASE + 0x08))
|
||||
#define PXI_RECV ((volatile uint32_t*)(PXI_BASE + 0x0C))
|
||||
|
||||
#define PXI_CNT_SEND_FIFO_EMPTY (1<<0)
|
||||
#define PXI_CNT_SEND_FIFO_FULL (1<<1)
|
||||
#define PXI_CNT_SEND_FIFO_EMPTY_IRQ (1<<2)
|
||||
#define PXI_CNT_SEND_FIFO_FLUSH (1<<3)
|
||||
#define PXI_CNT_RECV_FIFO_EMPTY (1<<8)
|
||||
#define PXI_CNT_RECV_FIFO_FULL (1<<9)
|
||||
#define PXI_CNT_RECV_FIFO_NEMPTY_IRQ (1<<10)
|
||||
#define PXI_CNT_ERROR_ACK (1<<14)
|
||||
#define PXI_CNT_ENABLE_FIFO (1<<15)
|
||||
|
||||
#define PXI_SYNC_TRIGGER_MPCORE (1<<5)
|
||||
#define PXI_SYNC_TRIGGER_OLDARM (1<<6)
|
||||
#define PXI_SYNC_ENABLE_IRQ (1<<7)
|
||||
|
||||
static inline void PXI_SetRemote(u8 msg)
|
||||
{
|
||||
*PXI_SYNC_SEND = msg;
|
||||
}
|
||||
|
||||
static inline u8 PXI_GetRemote(void)
|
||||
{
|
||||
return *PXI_SYNC_RECV;
|
||||
}
|
||||
|
||||
static inline void PXI_EnableIRQ(void)
|
||||
{
|
||||
*PXI_SYNC_IRQ = PXI_SYNC_ENABLE_IRQ;
|
||||
}
|
||||
|
||||
static inline void PXI_DisableIRQ(void)
|
||||
{
|
||||
*PXI_SYNC_IRQ = 0;
|
||||
}
|
||||
|
||||
static inline void PXI_Wait(void)
|
||||
{
|
||||
while(PXI_GetRemote() != PXI_NOCMD);
|
||||
}
|
||||
|
||||
static inline void PXI_Sync(void)
|
||||
{
|
||||
#ifdef ARM9
|
||||
*PXI_SYNC_IRQ |= PXI_SYNC_TRIGGER_MPCORE;
|
||||
#else
|
||||
*PXI_SYNC_IRQ |= PXI_SYNC_TRIGGER_OLDARM;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void PXI_Reset(void)
|
||||
{
|
||||
*PXI_SYNC_SEND = 0;
|
||||
*PXI_SYNC_IRQ = 0;
|
||||
*PXI_CNT = PXI_CNT_SEND_FIFO_FLUSH | PXI_CNT_ENABLE_FIFO;
|
||||
}
|
||||
|
||||
static inline void PXI_Send(u32 w)
|
||||
{
|
||||
while(*PXI_CNT & PXI_CNT_SEND_FIFO_FULL);
|
||||
do {
|
||||
*PXI_SEND = w;
|
||||
} while(*PXI_CNT & PXI_CNT_ERROR_ACK);
|
||||
return;
|
||||
}
|
||||
|
||||
static inline u32 PXI_Recv(void)
|
||||
{
|
||||
u32 ret;
|
||||
while(*PXI_CNT & PXI_CNT_RECV_FIFO_EMPTY);
|
||||
do {
|
||||
ret = *PXI_RECV;
|
||||
} while(*PXI_CNT & PXI_CNT_ERROR_ACK);
|
||||
return ret;
|
||||
}
|
31
common/types.h
Normal file
31
common/types.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ARM9
|
||||
#ifndef ARM11
|
||||
#error "Unknown processor"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIT(x) (1<<(x))
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int64_t s8;
|
||||
typedef int64_t s16;
|
||||
typedef int64_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
|
||||
typedef volatile s8 vs8;
|
||||
typedef volatile s16 vs16;
|
||||
typedef volatile s32 vs32;
|
||||
typedef volatile s64 vs64;
|
@ -12,9 +12,11 @@ dir_source := source
|
||||
dir_build := build
|
||||
dir_out := ../$(dir_build)
|
||||
|
||||
ASFLAGS := -mcpu=mpcore -mfloat-abi=hard
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostdlib
|
||||
ASFLAGS := -mcpu=mpcore -mfloat-abi=soft
|
||||
CFLAGS := -DARM11 -Wall -Wextra -MMD -MP -marm -mno-thumb-interwork \
|
||||
$(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math \
|
||||
-I$(dir_source) -I../common
|
||||
LDFLAGS := -nostdlib -nostartfiles
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
|
@ -9,8 +9,10 @@ SECTIONS
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||
.bss : ALIGN(4) { __bss_start = .; *(.bss*); __bss_end = .; }
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__stack_top = 0x1FFFF800;
|
||||
|
||||
__irq_stack = 0x1FFFF800;
|
||||
__prg_stack = 0x1FFFF400;
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
.global __boot
|
||||
__boot:
|
||||
@ Disable interrupts and switch to Supervisor
|
||||
cpsid aif, #0x13
|
||||
@ Disable interrupts and switch to IRQ
|
||||
cpsid aif, #0x12
|
||||
|
||||
@ Writeback and invalidate caches
|
||||
mov r0, #0
|
||||
@ -14,7 +14,11 @@ __boot:
|
||||
mcr p15, 0, r0, c7, c14, 0
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
|
||||
ldr sp, =__stack_top
|
||||
ldr sp, =__irq_stack
|
||||
|
||||
@ Switch to SVC
|
||||
cpsid aif, #0x13
|
||||
ldr sp, =__prg_stack
|
||||
|
||||
@ Reset values
|
||||
ldr r0, =0x00054078
|
||||
@ -26,6 +30,14 @@ __boot:
|
||||
mcr p15, 0, r1, c1, c0, 1
|
||||
mcr p15, 0, r2, c1, c0, 2
|
||||
|
||||
ldr r0, =__bss_start
|
||||
ldr r1, =__bss_end
|
||||
mov r2, #0
|
||||
.Lclearbss:
|
||||
str r2, [r0], #4
|
||||
cmp r0, r1
|
||||
blt .Lclearbss
|
||||
|
||||
bl main
|
||||
|
||||
b __boot
|
||||
|
57
screeninit/source/gic.c
Normal file
57
screeninit/source/gic.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Written by Wolfvak, specially sublicensed under the GPLv2
|
||||
Read LICENSE for more details
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <cpu.h>
|
||||
#include <gic.h>
|
||||
|
||||
#define IRQ_BASE ((vu32*)0x1FFFFFA0)
|
||||
|
||||
irq_handler handler_table[MAX_IRQ];
|
||||
|
||||
void __attribute__((interrupt("IRQ"))) gic_irq_handler(void)
|
||||
{
|
||||
u32 xrq, ss;
|
||||
CPU_EnterCritical(&ss);
|
||||
xrq = *GIC_IRQACK;
|
||||
if (xrq < MAX_IRQ && handler_table[xrq]) {
|
||||
(handler_table[xrq])(xrq);
|
||||
}
|
||||
*GIC_IRQEND = xrq;
|
||||
CPU_LeaveCritical(&ss);
|
||||
return;
|
||||
}
|
||||
|
||||
void GIC_Configure(u32 irq_id, irq_handler hndl)
|
||||
{
|
||||
handler_table[irq_id] = hndl;
|
||||
DIC_CLRENABLE[irq_id/32] |= BIT(irq_id & 0x1F);
|
||||
DIC_SETENABLE[irq_id/32] |= BIT(irq_id & 0x1F);
|
||||
DIC_PROCTGT[irq_id] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
void GIC_Reset(void)
|
||||
{
|
||||
*GIC_CONTROL = 0;
|
||||
*GIC_PRIOMASK = ~0;
|
||||
|
||||
for (int i = 0; i < (BIT(9)-1); i++) {
|
||||
*GIC_IRQEND |= i;
|
||||
}
|
||||
|
||||
*DIC_CONTROL = 0;
|
||||
for (int i = 0; i < (0x20/4); i++) {
|
||||
DIC_CLRENABLE[i] = ~0;
|
||||
DIC_PRIORITY[i] = 0;
|
||||
}
|
||||
|
||||
*DIC_CONTROL = 1;
|
||||
*GIC_CONTROL = 1;
|
||||
|
||||
IRQ_BASE[1] = (u32)gic_irq_handler;
|
||||
IRQ_BASE[0] = 0xE51FF004;
|
||||
return;
|
||||
}
|
56
screeninit/source/gic.h
Normal file
56
screeninit/source/gic.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Written by Wolfvak, specially sublicensed under the GPLv2
|
||||
Read LICENSE for more details
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
typedef void (*irq_handler)(u32);
|
||||
|
||||
#define MAX_IRQ (0x80)
|
||||
|
||||
#define GIC_BASE (0x17E00100)
|
||||
#define DIC_BASE (0x17E01000)
|
||||
|
||||
/* Setting bit 0 enables the GIC */
|
||||
#define GIC_CONTROL ((vu32*)(GIC_BASE + 0x00))
|
||||
/* Bits [7:0] control the min priority accepted */
|
||||
#define GIC_PRIOMASK ((vu32*)(GIC_BASE + 0x04))
|
||||
/* When an IRQ occurrs, this register holds the IRQ ID */
|
||||
#define GIC_IRQACK ((vu32*)(GIC_BASE + 0x0C))
|
||||
/* Write the IRQ ID here to acknowledge it */
|
||||
#define GIC_IRQEND ((vu32*)(GIC_BASE + 0x10))
|
||||
|
||||
|
||||
/* Setting bit 0 enables the DIC */
|
||||
#define DIC_CONTROL ((vu32*)(DIC_BASE + 0x000))
|
||||
/*
|
||||
Write here to enable an IRQ ID
|
||||
The register address is DIC_SETENABLE + (N/32)*4 and its
|
||||
corresponding bit index is (N%32)
|
||||
*/
|
||||
#define DIC_SETENABLE ((vu32*)(DIC_BASE + 0x100))
|
||||
|
||||
/* same as above but disables the IRQ */
|
||||
#define DIC_CLRENABLE ((vu32*)(DIC_BASE + 0x180))
|
||||
|
||||
/* sets the IRQ priority */
|
||||
#define DIC_PRIORITY ((vu32*)(DIC_BASE + 0x400))
|
||||
|
||||
/* specifies which CPUs are allowed to be forwarded the IRQ */
|
||||
#define DIC_PROCTGT ((vu8*)(DIC_BASE + 0x800))
|
||||
|
||||
/*
|
||||
each irq has 2 bits assigned
|
||||
bit 0 = 0: uses 1-N model
|
||||
1: uses N-N model
|
||||
|
||||
bit 1 = 0: level high active
|
||||
1: rising edge sensitive
|
||||
*/
|
||||
#define DIC_CFGREG ((vu32*)(DIC_BASE + 0xC00))
|
||||
|
||||
void gic_irq_handler(void);
|
||||
void GIC_Configure(u32 irq_id, irq_handler hndl);
|
||||
void GIC_Reset(void);
|
@ -1,26 +1,33 @@
|
||||
// screeninit source taken over from https://github.com/AuroraWright/arm9loaderhax/tree/master/payload_stage2/arm11
|
||||
// check there for license info
|
||||
// thanks go to AuroraWright
|
||||
#include "types.h"
|
||||
#include <types.h>
|
||||
#include <cpu.h>
|
||||
#include <gic.h>
|
||||
#include <pxi.h>
|
||||
|
||||
// see: https://github.com/AuroraWright/Luma3DS/blob/53209b9be0c264af00fb81b32146d27f0d9498ac/source/screen.h#L32-L34
|
||||
#define PDN_GPU_CNT (*(vu8 *)0x10141200)
|
||||
#define ARESCREENSINITIALIZED (PDN_GPU_CNT != 1)
|
||||
|
||||
#define BRIGHTNESS (0xBF)
|
||||
#define BASE_BRIGHTNESS (0x1F)
|
||||
|
||||
void main(void)
|
||||
static volatile struct fb {
|
||||
u8 *top_left;
|
||||
u8 *top_right;
|
||||
u8 *bottom;
|
||||
} *const fb = (volatile struct fb *)0x23FFFE00;
|
||||
|
||||
void screen_init(void)
|
||||
{
|
||||
char do_disco = !ARESCREENSINITIALIZED;
|
||||
vu32 *arm11Entry = (vu32 *)0x1FFFFFFC;
|
||||
u32 entry;
|
||||
|
||||
*(vu32 *)0x10141200 = 0x1007F;
|
||||
*(vu32 *)0x10202014 = 0x00000001;
|
||||
*(vu32 *)0x1020200C &= 0xFFFEFFFE;
|
||||
|
||||
*(vu32 *)0x10202240 = BRIGHTNESS;
|
||||
*(vu32 *)0x10202A40 = BRIGHTNESS;
|
||||
*(vu32 *)0x10202240 = BASE_BRIGHTNESS;
|
||||
*(vu32 *)0x10202A40 = BASE_BRIGHTNESS;
|
||||
*(vu32 *)0x10202244 = 0x1023E;
|
||||
*(vu32 *)0x10202A44 = 0x1023E;
|
||||
|
||||
@ -107,21 +114,59 @@ void main(void)
|
||||
*REGs_PSC1 = (vu32 *)0x10400020;
|
||||
|
||||
REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + 0x46500) >> 3; //End address
|
||||
REGs_PSC0[2] = 0; //Fill value
|
||||
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + SCREEN_BOTTOM_FBSIZE) >> 3; //End address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + 0x38400) >> 3; //End address
|
||||
REGs_PSC1[2] = 0; //Fill value
|
||||
REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
while(!((REGs_PSC0[3] & 2) && (REGs_PSC1[3] & 2)));
|
||||
return;
|
||||
}
|
||||
|
||||
void set_brightness(u8 brightness)
|
||||
{
|
||||
*(vu32 *)0x10202240 = brightness;
|
||||
*(vu32 *)0x10202A40 = brightness;
|
||||
}
|
||||
|
||||
void pxi_interrupt_handler(__attribute__((unused)) u32 xrq_n)
|
||||
{
|
||||
u8 msg = PXI_GetRemote();
|
||||
switch(msg) {
|
||||
case PXI_NOCMD:
|
||||
break;
|
||||
case PXI_SETBRIGHTNESS:
|
||||
set_brightness(PXI_Recv());
|
||||
break;
|
||||
}
|
||||
PXI_SetRemote(PXI_NOCMD);
|
||||
return;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vu32 *arm11Entry = (vu32 *)0x1FFFFFFC;
|
||||
u32 entry;
|
||||
|
||||
PXI_Reset();
|
||||
GIC_Reset();
|
||||
screen_init();
|
||||
|
||||
// Clear ARM11 entrypoint
|
||||
*arm11Entry = 0;
|
||||
|
||||
GIC_Configure(IRQ_PXI_SYNC, pxi_interrupt_handler);
|
||||
PXI_EnableIRQ();
|
||||
CPU_EnableIRQ();
|
||||
|
||||
//Wait for the entrypoint to be set, then branch to it
|
||||
while((entry=*arm11Entry) == 0);
|
||||
|
||||
CPU_DisableIRQ();
|
||||
PXI_DisableIRQ();
|
||||
((void (*)())(entry))();
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.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;
|
||||
|
||||
#define SCREEN_TOP_WIDTH 400
|
||||
#define SCREEN_BOTTOM_WIDTH 320
|
||||
#define SCREEN_HEIGHT 240
|
||||
#define SCREEN_TOP_FBSIZE (3 * SCREEN_TOP_WIDTH * SCREEN_HEIGHT)
|
||||
#define SCREEN_BOTTOM_FBSIZE (3 * SCREEN_BOTTOM_WIDTH * SCREEN_HEIGHT)
|
||||
|
||||
static volatile struct fb {
|
||||
u8 *top_left;
|
||||
u8 *top_right;
|
||||
u8 *bottom;
|
||||
} *const fb = (volatile struct fb *)0x23FFFE00;
|
@ -7,16 +7,7 @@
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define u8 uint8_t
|
||||
#define u16 uint16_t
|
||||
#define u32 uint32_t
|
||||
#define u64 uint64_t
|
||||
|
||||
#define vu8 volatile u8
|
||||
#define vu16 volatile u16
|
||||
#define vu32 volatile u32
|
||||
#define vu64 volatile u64
|
||||
#include <types.h>
|
||||
|
||||
#define max(a,b) \
|
||||
(((a) > (b)) ? (a) : (b))
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "hid.h"
|
||||
#include "i2c.h"
|
||||
#include "timer.h"
|
||||
#include "power.h"
|
||||
|
||||
u32 InputWait(u32 timeout_sec) {
|
||||
static u64 delay = 0;
|
||||
@ -23,6 +24,7 @@ u32 InputWait(u32 timeout_sec) {
|
||||
return sd_state ? SD_INSERT : SD_EJECT;
|
||||
u8 special_key;
|
||||
if ((timer_msec(timer_mcu) >= 64) && (I2C_readRegBuf(I2C_DEV_MCU, 0x10, &special_key, 1))) {
|
||||
CheckBrightness();
|
||||
if (special_key == 0x01)
|
||||
return pad_state | BUTTON_POWER;
|
||||
else if (special_key == 0x04)
|
||||
|
@ -2,6 +2,23 @@
|
||||
#include "i2c.h"
|
||||
#include "cache.h"
|
||||
#include "timer.h"
|
||||
#include "pxi.h"
|
||||
|
||||
static const u8 br_settings[] = {0x1F, 0x3F, 0x7F, 0xBF};
|
||||
static int prev_brightness = -1;
|
||||
void CheckBrightness() {
|
||||
u8 curSlider;
|
||||
I2C_readRegBuf(I2C_DEV_MCU, 0x09, &curSlider, 1);
|
||||
curSlider >>= 4;
|
||||
if (curSlider != prev_brightness) {
|
||||
PXI_Wait();
|
||||
PXI_Send(br_settings[curSlider]);
|
||||
PXI_SetRemote(PXI_SETBRIGHTNESS);
|
||||
PXI_Sync();
|
||||
prev_brightness = curSlider;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void ScreenOn() {
|
||||
wait_msec(3); // wait 3ms (cause profi200 said so)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void CheckBrightness();
|
||||
void ScreenOn();
|
||||
void Reboot();
|
||||
void PowerOff();
|
||||
|
@ -1,14 +1,15 @@
|
||||
#include "godmode.h"
|
||||
#include "power.h"
|
||||
#include "pxi.h"
|
||||
|
||||
void main(int argc, char** argv)
|
||||
{
|
||||
(void) argc; // unused for now
|
||||
(void) argv; // unused for now
|
||||
|
||||
|
||||
// Screen on
|
||||
ScreenOn();
|
||||
|
||||
|
||||
// Run the main program
|
||||
if (GodMode() == GODMODE_EXIT_REBOOT) Reboot();
|
||||
else PowerOff();
|
||||
|
Loading…
x
Reference in New Issue
Block a user