Browse Source

Initial checkin. Basic build and runtime environment, prior to first

test on actual hardware.
master
Gavan Fantom 13 years ago
commit
f5159013b3
  1. 38
      Makefile
  2. 187
      crt0.s
  3. 47
      lpc2103_flash.ld
  4. 18
      main.c

38
Makefile

@ -0,0 +1,38 @@
# Makefile
NAME=quad
OBJS=crt0.o main.o
CFLAGS=-march=armv4t -msoft-float
LDSCRIPT=lpc2103_flash.ld
CC=arm-elf-gcc
OBJCOPY=arm-elf-objcopy
CLEANOBJS=$(OBJS) $(NAME).hex $(NAME).elf $(NAME).bin $(NAME).map
all: $(NAME).bin
# In theory, nothing below here needs touching for as long as all of the
# sources are in a single directory.
.SUFFIXES: .elf .hex .bin
$(NAME).elf: $(OBJS)
$(CC) $(CFLAGS) -nostdlib -nostartfiles -T $(LDSCRIPT) -Wl,-Map -Wl,$(NAME).map -o $(NAME).elf $(OBJS) -lgcc
run: $(NAME).hex
$(FLASHER) -hex -term -control $(NAME).hex $(PORT) $(SPEED) $(OSC)
.elf.hex:
$(OBJCOPY) -O ihex ${.IMPSRC} ${.TARGET}
.hex.bin:
$(OBJCOPY) -I ihex -O binary ${.IMPSRC} ${.TARGET}
clean:
rm -rf $(CLEANOBJS)

187
crt0.s

@ -0,0 +1,187 @@
# Runtime support
# Configurable parameters
# Set PLL ratios - M=4, P=2, 58.9824 MHz clock
.equ PLL_M, 4
.equ PLL_P, 2
.equ FLASHCLOCKS, 3 /* 40-60MHz clock */
.equ APB_DIVIDER, 4 /* 1, 2 or 4 */
.equ UND_STACK_SIZE, 0x0004
.equ SVC_STACK_SIZE, 0x0004
.equ ABT_STACK_SIZE, 0x0004
.equ FIQ_STACK_SIZE, 0x0004
.equ IRQ_STACK_SIZE, 0x0080
.equ USR_STACK_SIZE, 0x0400
# Processor definitions
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1b
.equ Mode_SYS, 0x1f
.equ I_Bit, 0x80
.equ F_Bit, 0x40
# Register definitions
.equ MAM_BASE, 0xE01FC000
.equ MAMCR, 0
.equ MAMTIM, 4
.equ PLL_BASE, 0xE01FC080
.equ PLLCON, 0x00
.equ PLLCFG, 0x04
.equ PLLSTAT, 0x08
.equ PLLFEED, 0x0c
.equ PLLCON_PLLE, (1<<0)
.equ PLLCON_PLLC, (1<<1)
.equ PLLCFG_MSEL, (0x1F<<0)
.equ PLLCFG_PSEL, (0x03<<5)
.equ PLLSTAT_PLOCK, (1<<10)
.equ APBDIV_BASE, 0xE01FC100
.equ APBDIV, 0
# True is -1 so we subtract values together.
.equ PLL_LOG_P, (0-(PLL_P>1)-(PLL_P>2)-(PLL_P>4))
.equ PLLCFG_VAL, (PLL_M-1) | (PLL_LOG_P << 5)
# 1 => 1, 2 => 2, 4 => 0
.equ APB_VAL, (APB_DIVIDER & 3)
.text
.global _startup
.func _startup
_startup:
vectors:
b reset_handler
b undefined_handler
b swi_handler
b prefetch_abort_handler
b data_abort_handler
nop /* reserved */
b irq_handler
b fiq_handler
reset_handler:
# MAM and PLL setup
ldr r1, =MAM_BASE
ldr r2, =PLL_BASE
mov r3, #0xAA
mov r4, #0x55
# Configure and Enable PLL
mov r0, #PLLCFG_VAL
str r0, [r2, #PLLCFG]
mov r0, #PLLCON_PLLE
str r0, [r2, #PLLCON]
str r3, [r2, #PLLFEED]
str r4, [r2, #PLLFEED]
# Disable MAM until we turn on the PLL
mov r0, #0 /* MAM disabled */
str r0, [r1, #MAMCR]
# Wait until PLL Locked
lockwait:
ldr r0, [r2, #PLLSTAT]
ands r0, r0, #PLLSTAT_PLOCK
beq lockwait
# Switch to PLL Clock
mov r0, #(PLLCON_PLLE | PLLCON_PLLC)
str r0, [r2, #PLLCON]
str r3, [r2, #PLLFEED]
str r4, [r2, #PLLFEED]
# Enable MAM and set up flash timing
mov r0, #FLASHCLOCKS
str r0, [r1, #MAMTIM]
mov r0, #2 /* MAM fully enabled */
str r0, [r1, #MAMCR]
# Set APB divider
ldr r1, =APBDIV_BASE
mov r0, #APB_DIVIDER
str r0, [r1, #APBDIV]
# Relocate .data section (Copy from ROM to RAM)
ldr r1, =_etext
ldr r2, =_data
ldr r3, =_edata
lrel:
cmp r2, r3
ldrlo r0, [r1], #4
strlo r0, [r2], #4
blo lrel
# Clear .bss section (Zero init)
mov r0, #0
ldr r1, =_bss_start
ldr r2, =_bss_end
lzi:
cmp r1, r2
strlo r0, [r1], #4
blo lzi
# Set up stacks
ldr r0, =_stack_end
msr CPSR_c, #Mode_UND|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #Mode_ABT|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #Mode_FIQ|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #Mode_IRQ|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #Mode_SVC|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #Mode_USR
mov sp, r0
# Stack Limit (only when compiled with "-mapcs-stack-check")
sub sl, sp, #USR_STACK_SIZE
# Prepare to go!
mov r0, #0
mov r1, #0
adr lr, __back
b main
# Undefined handlers can just spin for now
undefined_handler:
swi_handler:
prefetch_abort_handler:
data_abort_handler:
irq_handler:
fiq_handler:
__back:
b __back
.endfunc
.end

47
lpc2103_flash.ld

@ -0,0 +1,47 @@
ENTRY(_startup)
MEMORY
{
flash : ORIGIN = 0, LENGTH = 32K
ram_isp_low(A) : ORIGIN = 0x40000040, LENGTH = 224
ram : ORIGIN = 0x40000120, LENGTH = 7872
ram_isp_high(A) : ORIGIN = 0x40001FE0, LENGTH = 32
}
_stack_end = 0x40001FDC;
SECTIONS
{
. = 0;
/* startup : { *(.startup)} >flash */
.text :
{
*crt0.o (.text)
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
_etext = .;
} >flash
.data :
{
_data = .;
*(.data)
_edata = .;
} >ram AT >flash
.bss :
{
_bss_start = .;
*(.bss)
} >ram
. = ALIGN(4);
_bss_end = . ;
}
_end = .;

18
main.c

@ -0,0 +1,18 @@
#define U0THR (*((volatile unsigned char *) 0xE000C000)) /* UART0 transmitter holding register */
#define U0LSR (*((volatile unsigned char *) 0xE000C014)) /* UART0 line status register */
#define U0THRE ((U0LSR & (1<<5))) /* UART0 transmitter holding register is empty */
void putch(char c) {
while (!U0THRE);
U0THR = c;
}
void putstr(char *s) {
while (*s) putch(*s++);
}
int main(void) {
putstr("Your entire life has been a mathematical error... a mathematical error I'm about to correct!\n");
return 0;
}
Loading…
Cancel
Save