From 18d0f8feacd7af4cb7a0944e7038887f6314cd2b Mon Sep 17 00:00:00 2001 From: David Welch Date: Sun, 27 May 2012 00:14:35 -0400 Subject: [PATCH] finally got the uart working --- uart01/Makefile | 30 +++++++++++++++++++ uart01/README | 25 ++++++++++++++++ uart01/memmap | 12 ++++++++ uart01/novectors.s | 23 ++++++++++++++ uart01/uart01.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 uart01/Makefile create mode 100644 uart01/README create mode 100644 uart01/memmap create mode 100644 uart01/novectors.s create mode 100644 uart01/uart01.c diff --git a/uart01/Makefile b/uart01/Makefile new file mode 100644 index 0000000..ace0626 --- /dev/null +++ b/uart01/Makefile @@ -0,0 +1,30 @@ + +ARMGNU ?= arm-none-eabi + +COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding + +all : kernel.img + +clean : + rm -f *.o + rm -f *.bin + rm -f *.elf + rm -f *.list + rm -f *.img + +novectors.o : novectors.s + $(ARMGNU)-as novectors.s -o novectors.o + +uart01.o : uart01.c + $(ARMGNU)-gcc $(COPS) -c uart01.c -o uart01.o + +kernel.img : memmap novectors.o uart01.o + $(ARMGNU)-ld novectors.o uart01.o -T memmap -o uart01.elf + $(ARMGNU)-objdump -D uart01.elf > uart01.list + $(ARMGNU)-objcopy uart01.elf -O binary kernel.img + + + + + + diff --git a/uart01/README b/uart01/README new file mode 100644 index 0000000..3b3f62d --- /dev/null +++ b/uart01/README @@ -0,0 +1,25 @@ + +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. + +Okay this was incredibly painful. I might have saved a few hours if +was at the office with an oscilloscope, I eventually had to fashion +something to look at the output using an mbed. + +The documentation for the chip has some glaring errors. The IER and +IIR register descriptions are screwy. The one that killed me was +the word length. The document says that the single bit controls 7 +bits per word vs 8 bits per word. And that bit 1 and some above +do not do anything, they might on real 16550's but not here. Well +that is wrong. If bits 1:0 are 00 you get 7 bits if bits 1:0 are 01 +you get 7 bits. You need bit 1 set to get 8 bits. + +This example uses the mini uart, uart1, to transmit characters on +GPIO14. You will need a level shifter or something that can receive +3.3v. One like this http://www.sparkfun.com/products/718 works perfectly. +Connect ground to pin 6 of P1 and rx on the FTDI board to tx on the +raspi which is pin 8 on the P1 connector. + +This example sets up the uart for 115200 baud, and blasts the characters +0123456701234567...forever as fast as it can. diff --git a/uart01/memmap b/uart01/memmap new file mode 100644 index 0000000..8d9566d --- /dev/null +++ b/uart01/memmap @@ -0,0 +1,12 @@ + +MEMORY +{ + ram : ORIGIN = 0x00000000, LENGTH = 0x1000 +} + +SECTIONS +{ + .text : { *(.text*) } > ram + .bss : { *(.bss*) } > ram +} + diff --git a/uart01/novectors.s b/uart01/novectors.s new file mode 100644 index 0000000..ac90378 --- /dev/null +++ b/uart01/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 diff --git a/uart01/uart01.c b/uart01/uart01.c new file mode 100644 index 0000000..a6d5aaf --- /dev/null +++ b/uart01/uart01.c @@ -0,0 +1,74 @@ + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- + +extern void PUT32 ( unsigned int, unsigned int ); +extern unsigned int GET32 ( unsigned int ); +extern void dummy ( unsigned int ); + +#define GPFSEL1 0x20200004 +#define GPSET0 0x2020001C +#define GPCLR0 0x20200028 +#define GPPUD 0x20200094 +#define GPPUDCLK0 0x20200098 + +#define AUX_ENABLES 0x20215004 +#define AUX_MU_IO_REG 0x20215040 +#define AUX_MU_IER_REG 0x20215044 +#define AUX_MU_IIR_REG 0x20215048 +#define AUX_MU_LCR_REG 0x2021504C +#define AUX_MU_MCR_REG 0x20215050 +#define AUX_MU_LSR_REG 0x20215054 +#define AUX_MU_MSR_REG 0x20215058 +#define AUX_MU_SCRATCH 0x2021505C +#define AUX_MU_CNTL_REG 0x20215060 +#define AUX_MU_STAT_REG 0x20215064 +#define AUX_MU_BAUD_REG 0x20215068 + +//GPIO14 TXD0 and TXD1 +//GPIO15 RXD0 and RXD1 +//alt function 5 for uart1 +//alt function 0 for uart0 + +//((250,000,000/115200)/8)-1 = 270 + +int notmain ( void ) +{ + unsigned int ra; + + PUT32(AUX_ENABLES,1); + PUT32(AUX_MU_IER_REG,0); + PUT32(AUX_MU_CNTL_REG,0); + PUT32(AUX_MU_LCR_REG,3); + PUT32(AUX_MU_MCR_REG,0); + PUT32(AUX_MU_IER_REG,0); + PUT32(AUX_MU_IIR_REG,0xC6); + PUT32(AUX_MU_BAUD_REG,270); + + ra=GET32(GPFSEL1); + ra&=~(7<<12); //gpio14 + ra|=2<<12; //alt5 + PUT32(GPFSEL1,ra); + + PUT32(GPPUD,0); + for(ra=0;ra<150;ra++) dummy(ra); + PUT32(GPPUDCLK0,(1<<14)); + for(ra=0;ra<150;ra++) dummy(ra); + PUT32(GPPUDCLK0,0); + + PUT32(AUX_MU_CNTL_REG,2); + + ra=0; + while(1) + { + while(1) + { + if(GET32(AUX_MU_LSR_REG)&0x20) break; + } + PUT32(AUX_MU_IO_REG,0x30+(ra++&7)); + } + + return(0); +} +//------------------------------------------------------------------------- +//-------------------------------------------------------------------------