print to uart0 [note: always printed on screen through DMA]
authorRobin Krens <robin@robinkrens.nl>
Tue, 9 Jul 2019 06:24:26 +0000 (14:24 +0800)
committerRobin Krens <robin@robinkrens.nl>
Tue, 9 Jul 2019 06:24:26 +0000 (14:24 +0800)
Makefile
include/stm32.h [new file with mode: 0644]
main.c
uart.c [new file with mode: 0644]

index 143f75d..f75c606 100644 (file)
--- 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 (file)
index 0000000..0928463
--- /dev/null
@@ -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 (file)
--- a/main.c
+++ b/main.c
@@ -1,7 +1,63 @@
-void main(void);
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stm32.h> // <-- 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 (file)
index 0000000..1cc5c03
--- /dev/null
+++ b/uart.c
@@ -0,0 +1,90 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stm32.h>
+
+#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;
+}
+
+