From: Robin Krens Date: Tue, 9 Jul 2019 06:24:26 +0000 (+0800) Subject: print to uart0 [note: always printed on screen through DMA] X-Git-Url: https://robinkrens.nl/gitweb/?a=commitdiff_plain;h=f868eff133428422f3ded32c58156144eb670a1f;p=cortex-from-scratch print to uart0 [note: always printed on screen through DMA] --- diff --git a/Makefile b/Makefile index 143f75d..f75c606 100644 --- a/Makefile +++ b/Makefile @@ -5,19 +5,20 @@ AS=arm-none-eabi-as MKIMG=arm-none-eabi-objcopy LDFLAGS+= -mthumb -mcpu=cortex-m3 -CFLAGS+= -mcpu=cortex-m3 -mthumb +CFLAGS+= -mcpu=cortex-m3 -mthumb -g as: $(AS) $(CFLAGS) -o start.o start.asm all: $(AS) $(CFLAGS) -o start.o start.asm - $(CC) $(CFLAGS) -c -o main.o main.c - $(LD) -nostartfiles -T link.ld -o start.out start.o main.o + $(CC) $(CFLAGS) -c -I./include -ffreestanding -o main.o main.c + $(CC) $(CFLAGS) -c -I./include -ffreestanding -o uart.o uart.c + $(LD) -nostartfiles -T link.ld -o start.out start.o main.o uart.o $(MKIMG) -Obinary -R .data start.out kernel.bin run: - qemu-system-arm -monitor stdio -M lm3s6965evb -kernel kernel.bin + qemu-system-arm -serial stdio -M lm3s6965evb -kernel kernel.bin examine: arm-none-eabi-objdump -S start.out diff --git a/include/stm32.h b/include/stm32.h new file mode 100644 index 0000000..0928463 --- /dev/null +++ b/include/stm32.h @@ -0,0 +1,17 @@ +#ifndef __SYSTEM_H +#define __SYSTEM_H + +/* MAIN.C */ +extern void *memcpy(void*, void*, size_t); +extern void *memset(void*, unsigned char, size_t); +extern unsigned short *memsetw(unsigned short *dest, unsigned short val, size_t count); +extern int strlen(const char *); +extern unsigned char inportb (uint32_t _addr); +extern void outportb (uint32_t _addr, unsigned char _data); + +/* UART.C */ +extern void uart_init(); +extern void uart_putc(unsigned char); +extern void uart_puts(unsigned char *); + +#endif diff --git a/main.c b/main.c index 57a199e..87b45e7 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,63 @@ -void main(void); +#include +#include +#include +#include // <-- your own header file located located in ./include -void main(void ) { - int i = 1; - for (;;); +void *memcpy(void *dest, void *src, size_t count) +{ + const char *sp = (const char *)src; + char *dp = (char *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +/* fillout memory with 'val' (i.e. all zeroes) + */ +void *memset(void *dest, unsigned char val, size_t count) +{ + char *temp = (char *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +/* same as above but shorter */ +unsigned short *memsetw(unsigned short *dest, unsigned short val, size_t count) +{ + unsigned short *temp = (unsigned short *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +int strlen(const char *str) +{ + int retval; + for(retval = 0; *str != '\0'; str++) retval++; + return retval; +} + +unsigned char inportb (uint32_t _addr) +{ + unsigned char rv; + //__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; + +} + +void outportb (uint32_t _addr, unsigned char _data) +{ + + // __asm__ __volatile__ ("str %1, %0" : "=r" (_data) : "m" (_addr) ); + + // __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} + +void main() +{ + uart_init(); + uart_puts("LOADING SYSTEM...\n"); + // loop + for(;;) { + + } } diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..1cc5c03 --- /dev/null +++ b/uart.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include + +#define SYSCTRL_RCC ((volatile unsigned long *)(0x400FE060)) +#define SYSCTRL_RIS ((volatile unsigned long *)(0x400FE050)) +#define SYSCTRL_RCGC1 ((volatile unsigned long *)(0x400FE104)) +#define SYSCTRL_RCGC2 ((volatile unsigned long *)(0x400FE108)) +#define GPIOPA_AFSEL ((volatile unsigned long *)(0x40004420)) + +#define UART0_DATA ((volatile unsigned long *)(0x4000C000)) +#define UART0_FLAG ((volatile unsigned long *)(0x4000C018)) +#define UART0_IBRD ((volatile unsigned long *)(0x4000C024)) +#define UART0_FBRD ((volatile unsigned long *)(0x4000C028)) +#define UART0_LCRH ((volatile unsigned long *)(0x4000C02C)) +#define UART0_CTRL ((volatile unsigned long *)(0x4000C030)) +#define UART0_RIS ((volatile unsigned long *)(0x4000C03C)) + +#define UART1_DATA ((volatile unsigned long *)(0x4000D000)) +#define UART1_FLAG ((volatile unsigned long *)(0x4000D018)) +#define UART1_IBRD ((volatile unsigned long *)(0x4000D024)) +#define UART1_FBRD ((volatile unsigned long *)(0x4000D028)) +#define UART1_LCRH ((volatile unsigned long *)(0x4000D02C)) +#define UART1_CTRL ((volatile unsigned long *)(0x4000D030)) +#define UART1_RIS ((volatile unsigned long *)(0x4000D03C)) + + +void uart_init() { + +/* To use the UARTs, the peripheral clock must be enabled by setting the UART0, UART1, or UART2 +bits in the RCGC1 register. (section 12.4: Initialization and Configuration */ + +*SYSCTRL_RCGC1 = *SYSCTRL_RCGC1 | 0x0003; + +/* + * Configure UART0: + 1. Disable the UART by clearing the UARTEN bit in the UARTCTL register. + 2. Write the integer portion of the BRD to the UARTIBRD register. + 3. Write the fractional portion of the BRD to the UARTFBRD register. + 4. Write the desired serial parameters to the UARTLCRH register + 5. Enable the UART by setting the UARTEN bit in the UARTCTL register. +*/ + +/* TODO: bitrate: How fast is CPU running?*/ + +*UART0_CTRL = 0; +*UART0_IBRD = 27; +*UART0_FBRD = 9; +*UART0_LCRH = 0x60; +*UART0_CTRL = 0x301; + +*UART1_CTRL = 0; +*UART1_IBRD = 27; +*UART1_FBRD = 9; +*UART1_LCRH = 0x60; +*UART1_CTRL = 0x301; + + +} + +extern void uart_putc(unsigned char ch) { + + if (ch == '\n') { + while ((*UART0_FLAG & 0x8)); // busy bit + *UART0_DATA = 0x0D; // return line + } + + while ((*UART0_FLAG & 0x8)); // busy bit + *UART0_DATA = ch; +} + +extern void uart_puts(unsigned char *str) +{ + + int i; + + for (i = 0; i < strlen(str); i++) + { + uart_putc(str[i]); + } +} + + +char * uart_read() { + + return NULL; +} + +