From 36fd5ec1f26b4fe4affd9afa1e1494450bd893d0 Mon Sep 17 00:00:00 2001 From: David Welch Date: Mon, 28 May 2012 18:23:24 -0400 Subject: [PATCH] adding blinker04, this uses the ARM timer --- blinker04/Makefile | 31 ++++++++++++++++++++++++ blinker04/README | 32 +++++++++++++++++++++++++ blinker04/blinker04.c | 55 +++++++++++++++++++++++++++++++++++++++++++ blinker04/memmap | 12 ++++++++++ blinker04/novectors.s | 23 ++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 blinker04/Makefile create mode 100644 blinker04/README create mode 100644 blinker04/blinker04.c create mode 100644 blinker04/memmap create mode 100644 blinker04/novectors.s diff --git a/blinker04/Makefile b/blinker04/Makefile new file mode 100644 index 0000000..d326c4b --- /dev/null +++ b/blinker04/Makefile @@ -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 + diff --git a/blinker04/README b/blinker04/README new file mode 100644 index 0000000..4f68377 --- /dev/null +++ b/blinker04/README @@ -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. + diff --git a/blinker04/blinker04.c b/blinker04/blinker04.c new file mode 100644 index 0000000..658f03e --- /dev/null +++ b/blinker04/blinker04.c @@ -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); +} +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- diff --git a/blinker04/memmap b/blinker04/memmap new file mode 100644 index 0000000..8d9566d --- /dev/null +++ b/blinker04/memmap @@ -0,0 +1,12 @@ + +MEMORY +{ + ram : ORIGIN = 0x00000000, LENGTH = 0x1000 +} + +SECTIONS +{ + .text : { *(.text*) } > ram + .bss : { *(.bss*) } > ram +} + diff --git a/blinker04/novectors.s b/blinker04/novectors.s new file mode 100644 index 0000000..ac90378 --- /dev/null +++ b/blinker04/novectors.s @@ -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