adding blinker04, this uses the ARM timer
This commit is contained in:
31
blinker04/Makefile
Normal file
31
blinker04/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
ARMGNU ?= arm-none-eabi
|
||||
|
||||
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
|
||||
|
||||
all : blinker04.hex blinker04.bin
|
||||
|
||||
clean :
|
||||
rm -f *.o
|
||||
rm -f *.bin
|
||||
rm -f *.hex
|
||||
rm -f *.elf
|
||||
rm -f *.list
|
||||
rm -f *.img
|
||||
|
||||
novectors.o : novectors.s
|
||||
$(ARMGNU)-as novectors.s -o novectors.o
|
||||
|
||||
blinker04.o : blinker04.c
|
||||
$(ARMGNU)-gcc $(COPS) -c blinker04.c -o blinker04.o
|
||||
|
||||
blinker04.elf : memmap novectors.o blinker04.o
|
||||
$(ARMGNU)-ld novectors.o blinker04.o -T memmap -o blinker04.elf
|
||||
$(ARMGNU)-objdump -D blinker04.elf > blinker04.list
|
||||
|
||||
blinker04.bin : blinker04.elf
|
||||
$(ARMGNU)-objcopy blinker04.elf -O binary blinker04.bin
|
||||
|
||||
blinker04.hex : blinker04.elf
|
||||
$(ARMGNU)-objcopy blinker04.elf -O ihex blinker04.hex
|
||||
|
||||
32
blinker04/README
Normal file
32
blinker04/README
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
See the top level README for information on where to find the
|
||||
schematic and programmers reference manual for the ARM processor
|
||||
on the raspberry pi. Also find information on how to load and run
|
||||
these programs.
|
||||
|
||||
This example uses the ARM timer, not the free running ARM timer which
|
||||
counts up (see blinker03) but the other timer that counts down.
|
||||
|
||||
A few more typos in the datasheet. It is an SP804 not AP804 (page 196).
|
||||
Page 197, bit 1 32 bit counter not 23 bit counter. Page 198 neither
|
||||
the raw nor masked IRQ registers are at address 0x40C.
|
||||
|
||||
So if you want to poll an arbitrary time with a free running timer you
|
||||
take a reference count, and then take a sample, wait for the difference
|
||||
between the sample and reference count. You have to know if it is an
|
||||
up or down counter. You can turn this timer into a free running timer
|
||||
by setting the load registers to all ones. What you can also do with
|
||||
this kind of timer that you cannot with a free runing timer is set the
|
||||
load registers to some number of ticks (minus 1) and it will roll over
|
||||
the counter at that rate. Often these kinds of timers have an interrupt
|
||||
as does this one. And you can poll the interrupt bit without havingt to
|
||||
actually configure an interrupt. This example sets the prescaler to
|
||||
divide by 250. The clock as running here is 250Mhz, so this takes it
|
||||
down to 1Mhz, 1000000 clocks per second. Now if we set the load registers
|
||||
to 4 million counts (minus 1) then every 4 million counts at 1 million
|
||||
per second is 4 seconds. Every 4 seconds the timer interrupt will fire.
|
||||
Which you can read in the raw irq (not masked) register. Once it is
|
||||
set you have to write anything to the clear interrupt register. If you
|
||||
were to set up an interrupt service routine, you would clear that
|
||||
interrupt in the interrupt handler.
|
||||
|
||||
55
blinker04/blinker04.c
Normal file
55
blinker04/blinker04.c
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
extern void PUT32 ( unsigned int, unsigned int );
|
||||
extern unsigned int GET32 ( unsigned int );
|
||||
extern void dummy ( unsigned int );
|
||||
|
||||
#define ARM_TIMER_LOD 0x2000B400
|
||||
#define ARM_TIMER_VAL 0x2000B404
|
||||
#define ARM_TIMER_CTL 0x2000B408
|
||||
#define ARM_TIMER_CLI 0x2000B40C
|
||||
#define ARM_TIMER_RIS 0x2000B410
|
||||
#define ARM_TIMER_MIS 0x2000B414
|
||||
#define ARM_TIMER_RLD 0x2000B418
|
||||
#define ARM_TIMER_DIV 0x2000B41C
|
||||
#define ARM_TIMER_CNT 0x2000B420
|
||||
|
||||
#define SYSTIMERCLO 0x20003004
|
||||
#define GPFSEL1 0x20200004
|
||||
#define GPSET0 0x2020001C
|
||||
#define GPCLR0 0x20200028
|
||||
|
||||
#define TIMEOUT 4000000
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int notmain ( void )
|
||||
{
|
||||
unsigned int ra;
|
||||
|
||||
ra=GET32(GPFSEL1);
|
||||
ra&=~(7<<18);
|
||||
ra|=1<<18;
|
||||
PUT32(GPFSEL1,ra);
|
||||
|
||||
PUT32(ARM_TIMER_CTL,0x003E0000);
|
||||
PUT32(ARM_TIMER_LOD,4000000-1);
|
||||
PUT32(ARM_TIMER_RLD,4000000-1);
|
||||
PUT32(ARM_TIMER_DIV,0x000000F9);
|
||||
PUT32(ARM_TIMER_CLI,0);
|
||||
PUT32(ARM_TIMER_CTL,0x003E0082);
|
||||
|
||||
while(1)
|
||||
{
|
||||
PUT32(GPSET0,1<<16);
|
||||
while(1) if(GET32(ARM_TIMER_RIS)) break;
|
||||
PUT32(ARM_TIMER_CLI,0);
|
||||
PUT32(GPCLR0,1<<16);
|
||||
while(1) if(GET32(ARM_TIMER_RIS)) break;
|
||||
PUT32(ARM_TIMER_CLI,0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
12
blinker04/memmap
Normal file
12
blinker04/memmap
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 0x1000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text*) } > ram
|
||||
.bss : { *(.bss*) } > ram
|
||||
}
|
||||
|
||||
23
blinker04/novectors.s
Normal file
23
blinker04/novectors.s
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
b reset
|
||||
|
||||
reset:
|
||||
mov sp,#0x1000
|
||||
bl notmain
|
||||
hang: b hang
|
||||
|
||||
.globl PUT32
|
||||
PUT32:
|
||||
str r1,[r0]
|
||||
bx lr
|
||||
|
||||
.globl GET32
|
||||
GET32:
|
||||
ldr r0,[r0]
|
||||
bx lr
|
||||
|
||||
.globl dummy
|
||||
dummy:
|
||||
bx lr
|
||||
Reference in New Issue
Block a user