Having no idea what Iām doing on this low level Iāve trial-and-error reduced everything into a single < 150 LOC .h file:
inline unsigned char aBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 9)); }
inline unsigned char bBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 4)); }
inline unsigned char cBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 10)); }
inline unsigned char upBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 13)); }
inline unsigned char downBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 3)); }
inline unsigned char leftBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 25)); }
inline unsigned char rightBtn(){ return *((volatile char*)(0xA0000000 + 1*0x20 + 7)); }
inline void writePixel(int color){
volatile int *LCD = (volatile int*) (0xA0002188);
LCD[124>>2] = 1<<12;
LCD[ 0 ] = color<<3;
LCD[252>>2] = 1<<12;
}
inline void enableSysTick(){
volatile unsigned int *SysTick = (unsigned int *) 0xE000E010UL;
// SysTick[1] = 4800000-1; // OSCT = 0
SysTick[1] = 7200000-1; // OSCT = 2
SysTick[2] = 0;
SysTick[0] = 4 | 2 | 1; //CLKSOURCE=CPU clock | TICKINT | ENABLE
}
inline void enableDAC(){
volatile unsigned int *PIO1 = (volatile unsigned int *) 0x40044060;
volatile unsigned int *PIO2 = (volatile unsigned int *) 0x400440F0;
volatile unsigned int *DIR1 = (volatile unsigned int *) 0xA0002004;
volatile unsigned int *DIR2 = (volatile unsigned int *) 0xA0002008;
PIO1[28] = PIO1[29] = PIO1[30] = PIO1[31] = 1<<7;
PIO2[20] = PIO2[21] = PIO2[22] = PIO2[23] = 1<<7;
*DIR1 |= (1<<28) | (1<<29) | (1<<30) | (1<<31);
*DIR2 |= (1<<20) | (1<<21) | (1<<22) | (1<<23);
}
inline void writeDAC(unsigned char out){
volatile unsigned char *P1 = (volatile unsigned char *) 0xA0000020;
volatile unsigned char *P2 = (volatile unsigned char *) 0xA0000040;
P1[28] = out&1; out >>= 1;
P1[29] = out&1; out >>= 1;
P1[30] = out&1; out >>= 1;
P1[31] = out&1; out >>= 1;
P2[20] = out&1; out >>= 1;
P2[21] = out&1; out >>= 1;
P2[22] = out&1; out >>= 1;
P2[23] = out;
}
#define LPC_SYSPLLCTRL 0x40048008
#define LPC_GPIO_PORT_MPIN2 0xA0002188
#define LPC_GPIO_PORT_CLR0 0xA0002280
#define LPC_GPIO_PORT_CLR1 0xA0002284
#define LPC_GPIO_PORT_CLR2 0xA0002288
#define LPC_GPIO_PORT_SET0 0xA0002200
#define LPC_GPIO_PORT_SET1 0xA0002204
#define LPC_GPIO_PORT_SET2 0xA0002208
#define LCD_CD_PIN 2
#define LCD_WR_PIN 12
#define LCD_CD_SET LPC_GPIO_PORT_SET0
#define LCD_CD_CLR LPC_GPIO_PORT_CLR0
#define LCD_WR_SET LPC_GPIO_PORT_SET1
#define LCD_WR_CLR LPC_GPIO_PORT_CLR1
#define LCD_MPIN LPC_GPIO_PORT_MPIN2
extern "C"
{
extern void _vStackTop(void);
void ResetISR(void);
void voidHandler();
__attribute__ ((section(".isr_vector")))
void (* const vectors[])(void) =
{
&_vStackTop,
ResetISR,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler,
voidHandler
};
extern int main(void);
#define SET_WORD(addr,val) *((unsigned int *) addr) = val
__attribute__ ((section(".after_vectors"))) void ResetISR()
{
SET_WORD(LPC_SYSPLLCTRL,0x25);
SET_WORD(LCD_CD_CLR,1 << LCD_CD_PIN);
SET_WORD(LCD_MPIN,0x22 << 3);
SET_WORD(LCD_WR_CLR,1 << LCD_WR_PIN);
SET_WORD(LCD_WR_SET,1 << LCD_WR_PIN);
SET_WORD(LCD_CD_SET,1 << LCD_CD_PIN);
main();
}
__attribute__ ((section(".after_vectors"))) void voidHandler() {};
}
Is it possible that it can work without all that stuff Iāve removed? It compiles and works in emulator (buttons and sound too), the display is written vertically, and of course you canāt enter the loader, though I canāt try it on real HW, which might not work.