From d6ae04c743259167859e7a1a64bdbf4c6ecf27ee Mon Sep 17 00:00:00 2001 From: dwelch Date: Sat, 9 Apr 2016 23:32:53 -0400 Subject: [PATCH] adding uart02 example --- ATSAMD21/uart02/Makefile | 98 +++++++++++++++ ATSAMD21/uart02/README | 30 +++++ ATSAMD21/uart02/flash.ld | 13 ++ ATSAMD21/uart02/flash.s | 75 ++++++++++++ ATSAMD21/uart02/sram.ld | 13 ++ ATSAMD21/uart02/sram.s | 59 +++++++++ ATSAMD21/uart02/uart02.c | 256 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 544 insertions(+) create mode 100644 ATSAMD21/uart02/Makefile create mode 100644 ATSAMD21/uart02/README create mode 100644 ATSAMD21/uart02/flash.ld create mode 100644 ATSAMD21/uart02/flash.s create mode 100644 ATSAMD21/uart02/sram.ld create mode 100644 ATSAMD21/uart02/sram.s create mode 100644 ATSAMD21/uart02/uart02.c diff --git a/ATSAMD21/uart02/Makefile b/ATSAMD21/uart02/Makefile new file mode 100644 index 0000000..680550b --- /dev/null +++ b/ATSAMD21/uart02/Makefile @@ -0,0 +1,98 @@ + +ARMGNU = arm-none-eabi +#ARMGNU = arm-linux-gnueabi + +AOPS = --warn --fatal-warnings -mcpu=cortex-m0 +COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 + +LOPS = -Wall -m32 -emit-llvm -target arm-none-eabi -mcpu=cortex-m0 -mthumb +LLCOPS = -march=thumb -mcpu=cortex-m0 +#LLCOPS = -mcpu=cortex-m0 +COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding +#at some point they changed this option, gee thanks +#OOPS = -std-compile-opts +OOPS = -std-link-opts + +gcc : uart02.gcc.thumb.flash.bin uart02.gcc.thumb.sram.bin + +all : gcc clang + +clang : uart02.clang.thumb.norm.flash.bin uart02.clang.thumb.opt.flash.bin uart02.clang.thumb.norm.sram.bin uart02.clang.thumb.opt.sram.bin + +clean: + rm -f *.bin + rm -f *.o + rm -f *.elf + rm -f *.list + rm -f *.bc + rm -f *.opt.s + rm -f *.norm.s + rm -f *.hex + +#--------------------------------- + +flash.o : flash.s + $(ARMGNU)-as $(AOPS) flash.s -o flash.o + +sram.o : sram.s + $(ARMGNU)-as $(AOPS) sram.s -o sram.o + +uart02.gcc.thumb.o : uart02.c + $(ARMGNU)-gcc $(COPS) -mthumb -c uart02.c -o uart02.gcc.thumb.o + +uart02.gcc.thumb.flash.bin : flash.ld flash.o uart02.gcc.thumb.o + $(ARMGNU)-ld -o uart02.gcc.thumb.flash.elf -T flash.ld flash.o uart02.gcc.thumb.o + $(ARMGNU)-objdump -D uart02.gcc.thumb.flash.elf > uart02.gcc.thumb.flash.list + $(ARMGNU)-objcopy uart02.gcc.thumb.flash.elf uart02.gcc.thumb.flash.bin -O binary + +uart02.gcc.thumb.sram.bin : sram.ld sram.o uart02.gcc.thumb.o + $(ARMGNU)-ld -o uart02.gcc.thumb.sram.elf -T sram.ld sram.o uart02.gcc.thumb.o + $(ARMGNU)-objdump -D uart02.gcc.thumb.sram.elf > uart02.gcc.thumb.sram.list + $(ARMGNU)-objcopy uart02.gcc.thumb.sram.elf uart02.gcc.thumb.sram.hex -O ihex + $(ARMGNU)-objcopy uart02.gcc.thumb.sram.elf uart02.gcc.thumb.sram.bin -O binary + +#--------------------------------- + +uart02.clang.bc : uart02.c + clang $(LOPS) -c uart02.c -o uart02.clang.bc + +uart02.clang.thumb.norm.flash.bin : flash.ld flash.o uart02.clang.bc + #llc $(LLCOPS) uart02.clang.bc -o uart02.clang.thumb.norm.s + #$(ARMGNU)-as $(AOPS) uart02.clang.thumb.norm.s -o uart02.clang.thumb.norm.o + llc $(LLCOPS) uart02.clang.bc -filetype=obj -o uart02.clang.thumb.norm.o + $(ARMGNU)-ld -o uart02.clang.thumb.norm.flash.elf -T flash.ld flash.o uart02.clang.thumb.norm.o + $(ARMGNU)-objdump -D uart02.clang.thumb.norm.flash.elf > uart02.clang.thumb.norm.flash.list + $(ARMGNU)-objcopy uart02.clang.thumb.norm.flash.elf uart02.clang.thumb.norm.flash.bin -O binary + +uart02.clang.thumb.opt.flash.bin : flash.ld flash.o uart02.clang.bc + opt $(OOPS) uart02.clang.bc -o uart02.clang.thumb.opt.bc + #llc $(LLCOPS) uart02.clang.thumb.opt.bc -o uart02.clang.thumb.opt.s + #$(ARMGNU)-as $(AOPS) uart02.clang.thumb.opt.s -o uart02.clang.thumb.opt.o + llc $(LLCOPS) uart02.clang.thumb.opt.bc -filetype=obj -o uart02.clang.thumb.opt.o + $(ARMGNU)-ld -o uart02.clang.thumb.opt.flash.elf -T flash.ld flash.o uart02.clang.thumb.opt.o + $(ARMGNU)-objdump -D uart02.clang.thumb.opt.flash.elf > uart02.clang.thumb.opt.flash.list + $(ARMGNU)-objcopy uart02.clang.thumb.opt.flash.elf uart02.clang.thumb.opt.flash.bin -O binary + + +uart02.clang.thumb.norm.sram.bin : sram.ld sram.o uart02.clang.bc + #llc $(LLCOPS) uart02.clang.bc -o uart02.clang.thumb.norm.s + #$(ARMGNU)-as $(AOPS) uart02.clang.thumb.norm.s -o uart02.clang.thumb.norm.o + llc $(LLCOPS) uart02.clang.bc -filetype=obj -o uart02.clang.thumb.norm.o + $(ARMGNU)-ld -o uart02.clang.thumb.norm.sram.elf -T sram.ld sram.o uart02.clang.thumb.norm.o + $(ARMGNU)-objdump -D uart02.clang.thumb.norm.sram.elf > uart02.clang.thumb.norm.sram.list + $(ARMGNU)-objcopy uart02.clang.thumb.norm.sram.elf uart02.clang.thumb.norm.sram.hex -O ihex + $(ARMGNU)-objcopy uart02.clang.thumb.norm.sram.elf uart02.clang.thumb.norm.sram.bin -O binary + +uart02.clang.thumb.opt.sram.bin : sram.ld sram.o uart02.clang.bc + opt $(OOPS) uart02.clang.bc -o uart02.clang.thumb.opt.bc + #llc $(LLCOPS) uart02.clang.thumb.opt.bc -o uart02.clang.thumb.opt.s + #$(ARMGNU)-as $(AOPS) uart02.clang.thumb.opt.s -o uart02.clang.thumb.opt.o + llc $(LLCOPS) uart02.clang.thumb.opt.bc -filetype=obj -o uart02.clang.thumb.opt.o + $(ARMGNU)-ld -o uart02.clang.thumb.opt.sram.elf -T sram.ld sram.o uart02.clang.thumb.opt.o + $(ARMGNU)-objdump -D uart02.clang.thumb.opt.sram.elf > uart02.clang.thumb.opt.sram.list + $(ARMGNU)-objcopy uart02.clang.thumb.opt.sram.elf uart02.clang.thumb.opt.sram.hex -O ihex + $(ARMGNU)-objcopy uart02.clang.thumb.opt.sram.elf uart02.clang.thumb.opt.sram.bin -O binary + + + + diff --git a/ATSAMD21/uart02/README b/ATSAMD21/uart02/README new file mode 100644 index 0000000..631367c --- /dev/null +++ b/ATSAMD21/uart02/README @@ -0,0 +1,30 @@ + +See the previous level README for schematic and programmers reference +information and how to run these programs. + +This program assumes the chip is in a just out of reset state, that no +other software has configured the peripherals or adjusted clocks, etc. + +derived from uart01. This is a baseline to use for other examples. + +This sparkfun board has a couple of TX/RX pins called out + +The ones next to the SWCLK/SWDIO + +TX PB22 SERCOM5 PAD[2] PORT FUNCTION D +RX PB23 SERCOM5 PAD[3] PORT FUNCTION D + +The arduino ones in the corner + +TX PA10 SERCOM0 PAD[2] FUNCTION C SERCOM2 PAD[2] FUNCTION D +RX PA11 SERCOM0 PAD[3] FUNCTION C SERCOM2 PAD[3] FUNCTION D + +This example defaults to SERCOM5 the PB22/PB23 pins. Set a define +in the code to swich to SERCOM0. + +It starts by using the status bits to blast characters out, then +prints a few interesting things, and goes into a loop that echos +out what it receives. + +Currently the CPUID shows 410CC601 for my part so this is an r0p1 +version of the Cortex-M0+, so that version of the TRM should be used. diff --git a/ATSAMD21/uart02/flash.ld b/ATSAMD21/uart02/flash.ld new file mode 100644 index 0000000..912da7c --- /dev/null +++ b/ATSAMD21/uart02/flash.ld @@ -0,0 +1,13 @@ + +MEMORY +{ + ram : ORIGIN = 0x00000000, LENGTH = 0x1000 +} + +SECTIONS +{ + .text : { *(.text*) } > ram + .rodata : { *(.rodata*) } > ram + .bss : { *(.bss*) } > ram +} + diff --git a/ATSAMD21/uart02/flash.s b/ATSAMD21/uart02/flash.s new file mode 100644 index 0000000..177a49d --- /dev/null +++ b/ATSAMD21/uart02/flash.s @@ -0,0 +1,75 @@ + +.cpu cortex-m0 +.thumb + +.thumb_func +.global _start +_start: +stacktop: .word 0x20001000 +.word reset +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang +.word hang + +.thumb_func +reset: + bl notmain + b hang +.thumb_func +hang: b . + +.align + +.thumb_func +.globl PUT8 +PUT8: + strb r1,[r0] + bx lr + +.thumb_func +.globl PUT16 +PUT16: + strh r1,[r0] + bx lr + +.thumb_func +.globl PUT32 +PUT32: + str r1,[r0] + bx lr + +.thumb_func +.globl GET8 +GET8: + ldrb r0,[r0] + bx lr + +.thumb_func +.globl GET16 +GET16: + ldrh r0,[r0] + bx lr + +.thumb_func +.globl GET32 +GET32: + ldr r0,[r0] + bx lr + +.thumb_func +.globl dummy +dummy: + bx lr + +.end diff --git a/ATSAMD21/uart02/sram.ld b/ATSAMD21/uart02/sram.ld new file mode 100644 index 0000000..b6205cc --- /dev/null +++ b/ATSAMD21/uart02/sram.ld @@ -0,0 +1,13 @@ + +MEMORY +{ + ram : ORIGIN = 0x20000000, LENGTH = 0x1000 +} + +SECTIONS +{ + .text : { *(.text*) } > ram + .rodata : { *(.rodata*) } > ram + .bss : { *(.bss*) } > ram +} + diff --git a/ATSAMD21/uart02/sram.s b/ATSAMD21/uart02/sram.s new file mode 100644 index 0000000..b608527 --- /dev/null +++ b/ATSAMD21/uart02/sram.s @@ -0,0 +1,59 @@ + +.cpu cortex-m0 +.thumb + +.thumb_func +.global _start +_start: + ldr r0,stacktop + mov sp,r0 + bl notmain + b hang +.thumb_func +hang: b . + +.align +stacktop: .word 0x20002000 + +.thumb_func +.globl PUT8 +PUT8: + strb r1,[r0] + bx lr + +.thumb_func +.globl PUT16 +PUT16: + strh r1,[r0] + bx lr + +.thumb_func +.globl PUT32 +PUT32: + str r1,[r0] + bx lr + +.thumb_func +.globl GET8 +GET8: + ldrb r0,[r0] + bx lr + +.thumb_func +.globl GET16 +GET16: + ldrh r0,[r0] + bx lr + +.thumb_func +.globl GET32 +GET32: + ldr r0,[r0] + bx lr + +.thumb_func +.globl dummy +dummy: + bx lr + +.end diff --git a/ATSAMD21/uart02/uart02.c b/ATSAMD21/uart02/uart02.c new file mode 100644 index 0000000..b23f3e0 --- /dev/null +++ b/ATSAMD21/uart02/uart02.c @@ -0,0 +1,256 @@ + +//------------------------------------------------------------------------ +//------------------------------------------------------------------------ + +void PUT32 ( unsigned int, unsigned int ); +unsigned int GET32 ( unsigned int ); +void PUT16 ( unsigned int, unsigned int ); +unsigned int GET16 ( unsigned int ); +void PUT8 ( unsigned int, unsigned int ); +unsigned int GET8 ( unsigned int ); +void dummy ( unsigned int ); + +#define PORT_BASE 0x41004400 + +#define PORTA_DIRSET (PORT_BASE+0x00+0x08) +#define PORTA_OUTCLR (PORT_BASE+0x00+0x14) +#define PORTA_OUTSET (PORT_BASE+0x00+0x18) +#define PORTA_OUTTGL (PORT_BASE+0x00+0x1C) + +#define PORTB_DIRSET (PORT_BASE+0x80+0x08) +#define PORTB_OUTCLR (PORT_BASE+0x80+0x14) +#define PORTB_OUTSET (PORT_BASE+0x80+0x18) +#define PORTB_OUTTGL (PORT_BASE+0x80+0x1C) + +#define PORTA_PMUX05 (PORT_BASE+0x00+0x30+5) +#define PORTA_PINCFG10 (PORT_BASE+0x00+0x40+10) +#define PORTA_PINCFG11 (PORT_BASE+0x00+0x40+11) + +#define PORTB_PMUX01 (PORT_BASE+0x80+0x30+1) +#define PORTB_PMUX11 (PORT_BASE+0x80+0x30+11) +#define PORTB_PINCFG03 (PORT_BASE+0x80+0x40+3) +#define PORTB_PINCFG22 (PORT_BASE+0x80+0x40+22) +#define PORTB_PINCFG23 (PORT_BASE+0x80+0x40+23) + +#define GCLK_BASE 0x40000C00 +#define GCLK_CTRL (GCLK_BASE+0x00) +#define GCLK_STATUS (GCLK_BASE+0x01) +#define GCLK_CLKCTRL (GCLK_BASE+0x02) +#define GCLK_GENCTRL (GCLK_BASE+0x04) +#define GCLK_GENDIV (GCLK_BASE+0x08) + +#define PM_BASE 0x40000400 +#define APBCMASK (PM_BASE+0x20) + +#define SYSCTRL_BASE 0x40000800 +#define OSC8M (SYSCTRL_BASE+0x20) + +#define SERCOM5_BASE 0x42001C00 +#define SERCOM5_CTRLA (SERCOM5_BASE+0x00) +#define SERCOM5_CTRLB (SERCOM5_BASE+0x04) +#define SERCOM5_BAUD (SERCOM5_BASE+0x0C) +#define SERCOM5_INTFLAG (SERCOM5_BASE+0x18) +#define SERCOM5_SYNCBUSY (SERCOM5_BASE+0x1C) +#define SERCOM5_DATA (SERCOM5_BASE+0x28) + +#define SERCOM0_BASE 0x42000800 +#define SERCOM0_CTRLA (SERCOM0_BASE+0x00) +#define SERCOM0_CTRLB (SERCOM0_BASE+0x04) +#define SERCOM0_BAUD (SERCOM0_BASE+0x0C) +#define SERCOM0_INTFLAG (SERCOM0_BASE+0x18) +#define SERCOM0_SYNCBUSY (SERCOM0_BASE+0x1C) +#define SERCOM0_DATA (SERCOM0_BASE+0x28) + +#define STK_CSR 0xE000E010 +#define STK_RVR 0xE000E014 +#define STK_CVR 0xE000E018 +#define STK_MASK 0x00FFFFFF + +#define ACTLR 0xE000E008 +#define CPUID 0xE000ED00 + +//------------------------------------------------------------------------ +static void clock_init ( void ) +{ + unsigned int ra; + + ra=GET32(OSC8M); + ra&=~(3<<8); + PUT32(OSC8M,ra); +} +//------------------------------------------------------------------------ +#ifdef USE_SERCOM0 +//------------------------------------------------------------------------ +static void uart_init ( void ) +{ + unsigned int ra; + + ra=GET32(APBCMASK); + ra|=1<<2; //enable SERCOM0 + PUT32(APBCMASK,ra); + + PUT32(GCLK_GENCTRL,0x00010605); + + PUT16(GCLK_CLKCTRL,0x4514); + + PUT8(PORTA_PINCFG10,0x01); + PUT8(PORTA_PINCFG11,0x01); + PUT8(PORTA_PMUX05,0x22); + + while(GET32(SERCOM0_SYNCBUSY)) continue; + PUT32(SERCOM0_CTRLA,0x00000000); + while(GET32(SERCOM0_SYNCBUSY)) continue; + PUT32(SERCOM0_CTRLA,0x00000001); + while(GET32(SERCOM0_SYNCBUSY)) continue; + PUT32(SERCOM0_CTRLA,0x40310004); + while(GET32(SERCOM0_SYNCBUSY)) continue; + PUT32(SERCOM0_CTRLB,0x00030000); + while(GET32(SERCOM0_SYNCBUSY)) continue; + PUT16(SERCOM0_BAUD,50436); + while(GET32(SERCOM0_SYNCBUSY)) continue; + PUT32(SERCOM0_CTRLA,0x40310006); + while(GET32(SERCOM0_SYNCBUSY)) continue; +} +//------------------------------------------------------------------------ +static void uart_flush ( void ) +{ + while(1) + { + if(GET8(SERCOM0_INTFLAG)&2) break; + } +} +//------------------------------------------------------------------------ +static void uart_send ( unsigned int d ) +{ + while(1) + { + if(GET8(SERCOM0_INTFLAG)&1) break; + } + PUT8(SERCOM0_DATA,d&0xFF); +} +//------------------------------------------------------------------------ +static unsigned int uart_recv ( void ) +{ + while(1) + { + if(GET8(SERCOM0_INTFLAG)&4) break; + } + return(GET8(SERCOM0_DATA)&0xFF); +} +//------------------------------------------------------------------------ +#else +//------------------------------------------------------------------------ +static void uart_init ( void ) +{ + unsigned int ra; + + ra=GET32(APBCMASK); + ra|=1<<7; //enable SERCOM5 + ra|=1<<2; //enable SERCOM0 + PUT32(APBCMASK,ra); + + PUT32(GCLK_GENCTRL,0x00010605); + + PUT16(GCLK_CLKCTRL,0x4519); + + PUT8(PORTB_PINCFG22,0x01); + PUT8(PORTB_PINCFG23,0x01); + PUT8(PORTB_PMUX11,0x33); + + while(GET32(SERCOM5_SYNCBUSY)) continue; + PUT32(SERCOM5_CTRLA,0x00000000); + while(GET32(SERCOM5_SYNCBUSY)) continue; + PUT32(SERCOM5_CTRLA,0x00000001); + while(GET32(SERCOM5_SYNCBUSY)) continue; + PUT32(SERCOM5_CTRLA,0x40310004); + while(GET32(SERCOM5_SYNCBUSY)) continue; + PUT32(SERCOM5_CTRLB,0x00030000); + while(GET32(SERCOM5_SYNCBUSY)) continue; + PUT16(SERCOM5_BAUD,50436); + while(GET32(SERCOM5_SYNCBUSY)) continue; + PUT32(SERCOM5_CTRLA,0x40310006); + while(GET32(SERCOM5_SYNCBUSY)) continue; +} +//------------------------------------------------------------------------ +static void uart_flush ( void ) +{ + while(1) + { + if(GET8(SERCOM5_INTFLAG)&2) break; + } +} +//------------------------------------------------------------------------ +static void uart_send ( unsigned int d ) +{ + while(1) + { + if(GET8(SERCOM5_INTFLAG)&1) break; + } + PUT8(SERCOM5_DATA,d&0xFF); +} +//------------------------------------------------------------------------ +static unsigned int uart_recv ( void ) +{ + while(1) + { + if(GET8(SERCOM5_INTFLAG)&4) break; + } + return(GET8(SERCOM5_DATA)&0xFF); +} +//------------------------------------------------------------------------ +#endif +//------------------------------------------------------------------------ +void hexstrings ( unsigned int d ) +{ + //unsigned int ra; + unsigned int rb; + unsigned int rc; + + rb=32; + while(1) + { + rb-=4; + rc=(d>>rb)&0xF; + if(rc>9) rc+=0x37; else rc+=0x30; + uart_send(rc); + if(rb==0) break; + } + uart_send(0x20); +} +//------------------------------------------------------------------------ +void hexstring ( unsigned int d ) +{ + hexstrings(d); + uart_send(0x0D); + uart_send(0x0A); +} +//------------------------------------------------------------------------ +int notmain ( void ) +{ + unsigned int ra; + + clock_init(); + + uart_init(); + + for(ra=0;ra<10000;ra++) + { + uart_send(0x30+(ra&7)); + } + uart_send(0x0D); + uart_send(0x0A); + hexstring(0x12345678); + hexstring(GET32(ACTLR)); + hexstring(GET32(CPUID)); + + while(1) + { + ra=uart_recv(); + if(ra==0x0D) uart_send(0x0A); + uart_send(ra); + } + + return(0); +} +//------------------------------------------------------------------------ +//------------------------------------------------------------------------