basic terminal
authorRobin Krens <robin@robinkrens.nl>
Tue, 23 Jul 2019 19:00:45 +0000 (03:00 +0800)
committerRobin Krens <robin@robinkrens.nl>
Tue, 23 Jul 2019 19:00:45 +0000 (03:00 +0800)
14 files changed:
AUTHORS
Makefile
include/mmap.h
include/stm32.h
ivt.c
lib.c
link.ld
main.c
pool.c
regf.c
sysinfo.c
systick.c
term.c [new file with mode: 0644]
uart.c

diff --git a/AUTHORS b/AUTHORS
index e69de29..6975af5 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -0,0 +1 @@
+Robin Krens - robin@robinkrens.nl
index d7e1652..b4a4133 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,12 +15,13 @@ LDFLAGS+= -mthumb -mcpu=cortex-m3
 ASFLAGS+= -mcpu=cortex-m3 -mthumb -g
 CFLAGS+= -mcpu=cortex-m3 -mthumb -g -ffreestanding 
 
+BIN = bin
+
 ODIR = obj
-_OBJ = main.o uart.o ivt.o systick.o sysinfo.o lib.o regf.o pool.o
+_OBJ = ivt.o uart.o systick.o sysinfo.o lib.o regf.o pool.o term.o main.o
 OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
 
-
-$(ODIR)/%.o: %.c $(DEPS)
+$(ODIR)/%.o: %.c 
        @mkdir -p $(@D)
        $(CC) -c $< $(CFLAGS) -I./include -o $@
 
@@ -31,30 +32,31 @@ as:
 # Compile and link all
 kernel: $(OBJ)
        $(AS) $(ASFLAGS) -o start.o start.asm
-       $(LD) -nostartfiles -Map $@.MAP -T link.ld -o $@.ELF start.o $^ --print-memory-usage
+       $(LD) -nostartfiles -Map $@.MAP -T link.ld -o $(BIN)/$@.ELF start.o $^ --print-memory-usage
        @echo "Creating binary..."
-       $(MKIMG) -Obinary -R .data $@.ELF $@.bin
+       @mkdir -p $(BIN)
+       $(MKIMG) -Obinary -R .data $(BIN)/$@.ELF  $(BIN)/$@.bin
 
 # Run in Qemu; note this is a patched version for stm32-f103c8
 run:
-       /usr/local/bin/qemu-system-arm -serial stdio  -M stm32-f103c8 -kernel kernel.bin
+       /usr/local/bin/qemu-system-arm -serial stdio  -M stm32-f103c8 -kernel $(BIN)/kernel.bin
 
 # Examine all sections
 examine-all:
-       arm-none-eabi-objdump -D kernel.ELF | less
+       arm-none-eabi-objdump -D $(BIN)/kernel.ELF | less
 
 # Examine just headers
 examine-header:
-       arm-none-eabi-objdump -x kernel.ELF | less
+       arm-none-eabi-objdump -x $(BIN)/kernel.ELF | less
 
 # Flash kernel to board
 flash:
-       stm32flash -w kernel.bin -v /dev/ttyUSB0
+       stm32flash -w $(BIN)/kernel.bin -v /dev/ttyUSB0
 
 .PHONY: clean
 
 clean:
-       rm -rf $(ODIR)/*.o start.o kernel.*
+       rm -rf $(ODIR)/*.o start.o $(BIN)/kernel.*
 
 # Altijd handig deze template
 #%.o: %.c
index aa8a902..e88c752 100644 (file)
@@ -1,59 +1,74 @@
-/* 
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ * 
+ * $LOG$
+ * 2019/7/20 - ROBIN KRENS     
+ * Initial version 
+ * 
+ * $DESCRIPTION$
  * Example memory map for the Cortex-A3
  * Implementations vary among manufacturers. This one is
  * a STM32F013RC6. Addresses of peripherals vary amongst 
  * manufacturers of boards with similar chips
- * 
+ *
+ * $USAGE$
+ * These are volatile memory addresses of 32 bit. The macro's
+ * MEM_VALUE and MEM_ADDR should used.
+ * In case you want to use a address on the lside of a assigment
+ * use volatile uint32_t * p = MEM_ADDR(0x20000000); 
+ *
  * */
 
-#define BSS_BASE ((volatile uint32_t *)(0x20000800)) //TODO: .data flexible siz
-#define TOTAL_MEM_SIZE 64000;
+#define OWRITE 0x01
+#define SETBIT 0x02
+#define CLRBIT 0x03
+
+/* Safety macro's to get the address or value */
+#define MEM_VALUE(addr) *((volatile uint32_t(*) (addr))
+#define MEM_ADDR(addr) ((volatile uint32_t *) (addr))
 
 /* SYSTEM INFO AND DEBUG */
-#define MCU_ID ((volatile uint32_t*)( 0xE000ED00)
-#define FLASH_MEM ((volatile uint32_t*)( 0x1FFFF000)
+#define MCU_ID MEM_ADDR(0xE000ED00
+#define FLASH_MEM MEM_ADDR(0x1FFFF000
 
 /* SYSTEM CONTROL BLOCK REGISTER */
-#define SCB_VTOR ((volatile uint32_t *)( 0xE000ED08)) // VECTOR TABLE
-#define SCB_VTOR_ST ((volatile uint32_t *)( 0xE000ED04)) // STATUS OF VECTOR
-#define SCB_CCR ((volatile uint32_t *)( 0xE000ED14)) // SET SOFTWARE TRAPS
+#define SCB_VTOR MEM_ADDR(0xE000ED08) // VECTOR TABLE
+#define SCB_VTOR_ST MEM_ADDR(0xE000ED04) // STATUS OF VECTOR
+#define SCB_CCR MEM_ADDR(0xE000ED14) // SET SOFTWARE TRAPS
 
 /* NESTED VECTOR INTERRUPT CONTROL REGISTER */
-#define NVIC_ISER0 ((volatile uint32_t*)( 0xE000E100)) // interrupt set enable register
-#define NVIC_ISER1 ((volatile uint32_t*)( 0xE000E104)) // interrupt set enable register
+#define NVIC_ISER0 MEM_ADDR(0xE000E100) // interrupt set enable register
+#define NVIC_ISER1 MEM_ADDR(0xE000E104) // interrupt set enable register
 
 /* SYSTICK REGISTER */
-#define STK_CTRL ((volatile uint32_t *)(0xE000E010))
-#define STK_RELOAD ((volatile uint32_t *)(0xE000E014))
+#define STK_CTRL MEM_ADDR(0xE000E010)
+#define STK_RELOAD MEM_ADDR(0xE000E014)
 
 /* CLOCK REGISTER */
-#define RCC_CR ((volatile uint32_t *)(0x40021000))
-#define RCC_CFGR ((volatile uint32_t *)(RCC_CR + 0x04))
+#define RCC_CR MEM_ADDR(0x40021000)
+#define RCC_CFGR MEM_ADDR(0x40021004)
 
 /* SYSTEM CONTROL REGISTER */
-#define SYSCTRL_RCC ((volatile unsigned long *)(0x40021000))
-#define RCC_APB2ENR ((volatile uint32_t *)(0x40021018)) // register to enable USART1
+#define SYSCTRL_RCC MEM_ADDR(0x40021000)
+#define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1
 
-#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 SYSCTRL_RIS MEM_ADDR(0x400FE050)
+#define SYSCTRL_RCGC1 MEM_ADDR(0x400FE104)
+#define SYSCTRL_RCGC2 MEM_ADDR(0x400FE108)
+#define GPIOPA_AFSEL MEM_ADDR(0x40004420)
 
-#define GPIOA_CRH ((volatile unsigned long *)(0x40010804))
+#define GPIOA_CRH MEM_ADDR(0x40010804)
 
-#define AFIO_EVCR ((volatile uint32_t *)(0x40010000))
-//#define AFIO_EXTICR1 ((volatile uint32_t *)(AFIO_EVCR + 0x08))
+#define AFIO_EVCR MEM_ADDR(0x40010000)
 
 /* EXTERNAL INTERRUPTS */
-#define EXTI_IMR ((volatile uint32_t *)(0x40010400))
-#define EXTI_RTSR ((volatile uint32_t *)  (EXTI_IMR + 0x08))
-//#define EXTI_FTSR ((volatile uint32_t *)  (EXTI_IMR + 0x04))
+#define EXTI_IMR MEM_ADDR(0x40010400)
+#define EXTI_RTSR MEM_ADDR(0x40010408)
 
 /* UART1 REGISTERS */
-#define USART1_BASE ((volatile uint32_t) (0x40013800))
-#define USART1_SR ((volatile uint32_t *) (USART1_BASE))
-#define USART1_DR ((volatile uint32_t *)  (USART1_BASE + 0x04))
-#define USART1_BRR ((volatile uint32_t *) (USART1_BASE + 0x08))
-#define USART1_CR1 ((volatile uint32_t *) (USART1_BASE + 0x0C))
-#define USART1_CR2 ((volatile uint32_t *) (USART1_BASE + 0x10))
-#define USART1_CR3 ((volatile uint32_t *) (USART1_BASE + 0x14))
+#define USART1_BASE MEM_ADDR(0x40013800)
+#define USART1_SR MEM_ADDR(0x40013800)
+#define USART1_DR MEM_ADDR(0x40013804)
+#define USART1_BRR MEM_ADDR(0x40013808)
+#define USART1_CR1 MEM_ADDR(0x4001380C)
+#define USART1_CR2 MEM_ADDR(0x40013810)
+#define USART1_CR3 MEM_ADDR(0x40013814)
index bc510d4..433c5d4 100644 (file)
@@ -14,6 +14,7 @@ extern void clock_init();
 extern void uart_init();
 extern void uart_putc(unsigned char);
 extern void uart_puts(unsigned char *);
+extern char uart_getc(); 
 
 /* IVT.C */
 extern void ivt_init();
@@ -43,4 +44,11 @@ extern void free();
 extern void regw_u8(volatile uint32_t *, uint8_t, short, short);
 extern void regw_u32(volatile uint32_t *, uint32_t, short, short);
 
+/* TERM.C */
+extern char getchar();
+extern void cputchar(char);
+extern void cputs(unsigned char *);
+extern char * readline();
+extern void terminal();
+
 #endif
diff --git a/ivt.c b/ivt.c
index 33a2bd4..b3854f1 100644 (file)
--- a/ivt.c
+++ b/ivt.c
@@ -45,7 +45,7 @@ struct interrupt_frame {
  * interrupt vector 16-92: irq0 - irq ..
  * */
 
-uint32_t ivt[92];
+uint32_t __attribute__((aligned(0x100))) ivt[92];
 
 /* each message corresponds to each and every exception. 
  * We get the correct message by accessing
@@ -126,6 +126,6 @@ void ivt_init() {
         * a register in the NVIC called the vector table offset register */
 
        //*SCB_VTOR = (volatile uint32_t) &ivt; 
-       regw_u32(SCB_VTOR, (uint32_t) &ivt, 0, 0x01);
+       regw_u32(SCB_VTOR, (uint32_t) &ivt, 0, OWRITE);
 
 }
diff --git a/lib.c b/lib.c
index d753ac3..ba55c01 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -26,13 +26,12 @@ void addrtohex(uint32_t addr) {
                }
        }
 
-       //uart_puts("ADDRESS: 0x");
         for (int i = 7; i >= 0; i--) {
-               uart_putc(hexbuf[i]);
+               cputchar(hexbuf[i]);
        } 
-       //uart_puts(hexbuf);
-       //uart_putc('\n');
 }
 
 
 
+
+
diff --git a/link.ld b/link.ld
index db37888..1f6b5f6 100644 (file)
--- a/link.ld
+++ b/link.ld
@@ -12,7 +12,7 @@ SECTIONS
        . = 0x0;
        .text : ALIGN(4)
        {
-               /* (.vector_table */ 
+               /* (.vector_table */
                *(.text)
                *(.rodata)
        }
@@ -21,7 +21,7 @@ SECTIONS
        {
                *(.data)
        } 
-       .bss : ALIGN(256
+       .bss : ALIGN(4
        {
                *(.bss)
        }
diff --git a/main.c b/main.c
index 19d0eb5..2b6fdba 100644 (file)
--- a/main.c
+++ b/main.c
@@ -44,30 +44,14 @@ void main()
 {
 
        ivt_init();
-//     clock_init();
        uart_init();
-       //uart_puts("LOADING SYSTEM 0.1 ...\n");
+       
        systick_init();
-//     mm_init();
-       sysinfo();
-
-
-       pool_init(20, 5, 0x20000800);
-
-       //addrtohex(p2);
-       //addrtohex(*p2);
-       
-       /* extern stub();
-       stub();
-       __asm__ __volatile__ ("udiv r1, r3 ,%0" :: "r"(0)); */
        
-       //regw_u32(p, 0x0CCCCCCCC, 4, 0x01);
-
-       //regw_u8(p, 0xFF, 0, 0x02);
+       sysinfo();
 
-//     asm("cpsie i"); // enable irq , cpsied f (disable faukts(
+       terminal();
 
-       // loop
        for(;;) {
 
        }
diff --git a/pool.c b/pool.c
index fa08c29..0e0b94d 100644 (file)
--- a/pool.c
+++ b/pool.c
@@ -5,24 +5,22 @@
  * Initial version 
  * 
  * $DESCRIPTION$
- * Fixed-sized memory pool allocation. A so called
- * memory-pool (i.e. 4kB * 12 blocks) can be 
- * initialized. Note: this allocator is for use on
- * processors without an MMU (memory management 
- * unit). A MPU (memory protection unit), if 
- * available can be used to protect certain zones.
+ * Fixed-sized memory pool allocation. A so called * memory-pool
+ * (i.e. 4kB * 12 blocks) can be initialized. Note: this allocator
+ * is for use on processors without an MMU (memory management 
+ * unit). A MPU (memory protection unit), if available can be used
+ * to protect certain zones.
  *
- * This work is based on an article of Ben Kenwright
+ * This work is based on an article of Ben Kenwright.
  * 
- * Preconditions: programmer should make sure the 
- * SRAM entry point + (blocks * blocksize) is free. 
+ * Preconditions: programmer should make sure the SRAM entry point
+ * + (blocks * blocksize) is free. 
  *
  * $SAMPLE USAGE$
- * KERNEL: can use initialize a big pool for all
- * user tasks
+ * KERNEL: can initialize a big pool for all user tasks
  *
- * USER TASKS/PROCESS: can use this to dynamically
- * allocate their own memory (i.e. heap)
+ * USER TASKS/PROCESS: can use this to dynamically allocate their
+ * own memory (i.e. heap)
  * 
  * 
  * * */
@@ -76,6 +74,7 @@ void pool_init(size_t size_arg, unsigned int blocks_arg, uint32_t * entry_SRAM)
         mem.SRAM_entry = NULL;
  } */
 
+/* Helper functions */
 uint32_t * AddrFromIndex(unsigned int i)  {
        return mem.SRAM_entry + ( i * mem.block_size );
 
@@ -86,6 +85,7 @@ unsigned int IndexFromAddr(const uint32_t * p) {
 
 }
 
+/* alloc and free */ 
 void * alloc() {
        if (mem.blocks_alloc < mem.blocks ) {
                 unsigned int * p = (unsigned int *)AddrFromIndex( mem.blocks_alloc );
diff --git a/regf.c b/regf.c
index 257a417..75f0a3c 100644 (file)
--- a/regf.c
+++ b/regf.c
@@ -2,24 +2,20 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <stm32.h>
-
-#define O_WRITE 0x01
-#define SET 0x02
-#define CLEAR 0x03
+#include <mmap.h>
 
 /* write value (uint8_t) to register */
 void regw_u8(volatile uint32_t * reg, uint8_t val, short shift, short flag) {
 
        switch(flag) {
-               case O_WRITE:
-                       (*(volatile uint32_t *) (reg)) = (val << shift);
+               case OWRITE:
+                       *reg = (val << shift);
                        break;
-               case SET:
-                       (*(volatile uint32_t *) (reg)) = 
-                       ((*(volatile uint32_t *) (reg)) | (val << shift));
+               case SETBIT:
+                       *reg = *reg | (val << shift);
                        break;
-               case CLEAR:
-                       (*(volatile uint32_t *) (reg)) = (val << shift);
+               case CLRBIT:
+                       *reg = (val << shift);
                        break;
        }
 }
@@ -28,13 +24,14 @@ void regw_u8(volatile uint32_t * reg, uint8_t val, short shift, short flag) {
 void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) {
 
        switch(flag) {
-               case O_WRITE:
-                       (*(volatile uint32_t *) (reg)) = (val << shift);
+               case OWRITE:
+                       //*reg = (val << shift);
+                       *reg = (val << shift);
+                       break;
+               case SETBIT:
+                       *reg = *reg | (val << shift);
                        break;
-               case SET:
-                       (*(volatile uint32_t *) (reg)) = 
-                       ((*(volatile uint32_t *) (reg)) | (val << shift));
-               case CLEAR:
+               case CLRBIT:
                        //
                        break;
        }
index 2d6f047..fe544ee 100644 (file)
--- a/sysinfo.c
+++ b/sysinfo.c
@@ -12,29 +12,29 @@ uint32_t get_msp(void);
 void sysinfo() {
 
        uint32_t tmp = *MCU_ID;
-       uart_puts("# ROBSYS 0.1 LOADING...\n");
-       uart_puts("# DEVICE ID: ");
+       cputs("# ROBSYS 0.1 LOADING...\n");
+       cputs("# DEVICE ID: ");
 
        if (tmp & 0x414) 
-               uart_puts("HIGH DENSITY\n");
+               cputs("HIGH DENSITY\n");
        else {
-               uart_puts("UNKNOWN\n");
+               cputs("UNKNOWN\n");
        }
 
        tmp = (tmp >> 16);
        uart_puts("# REVISION: ");
        switch  (tmp) {
                case 0x1000:
-                     uart_puts("REVISION A\n");
+                     cputs("REVISION A\n");
                      break;
                case 0x1001:
-                     uart_puts("REVISION Z\n");
+                     cputs("REVISION Z\n");
                      break;
                case 0x1003:
-                     uart_puts("REVISION 1/2/3/X/Y\n");
+                     cputs("REVISION 1/2/3/X/Y\n");
                      break;
                default:
-                     uart_puts("UNKNOWN\n");
+                     cputs("UNKNOWN\n");
        }
 
        extern char _endofbss;
@@ -44,15 +44,15 @@ void sysinfo() {
        uint32_t data_bss = &_endofbss - MEM_OFFSET;
        uint32_t mem_free = MEM_SIZE - stack_usage - data_bss;
 
-       uart_puts("# TOTAL MEMORY: ");
+       cputs("# TOTAL MEMORY: ");
        addrtohex(MEM_SIZE);
-       uart_putc('\n');
-       uart_puts("# FREE MEMORY: ");
+       cputchar('\n');
+       cputs("# FREE MEMORY: ");
        addrtohex(mem_free);
-       uart_putc('\n');
-       uart_puts("# STACK USAGE: ");
+       cputchar('\n');
+       cputs("# STACK USAGE: ");
        addrtohex(stack_usage);
-       uart_putc('\n');
+       cputchar('\n');
 
 }
 
index ed062c0..40e7862 100644 (file)
--- a/systick.c
+++ b/systick.c
@@ -20,7 +20,7 @@ struct interrupt_frame {
 void * systick_handler(/* struct interrupt_frame * frame */) {
 
 //     uint32_t volatile status;
-       uart_puts("TICKING\n");
+       //uart_puts("TICKING\n");
 //     for(;;);
 }
 
diff --git a/term.c b/term.c
new file mode 100644 (file)
index 0000000..8b81255
--- /dev/null
+++ b/term.c
@@ -0,0 +1,82 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stm32.h>
+#include <mmap.h>
+
+#define SERIAL 1
+#define BUFSIZE 256
+
+static char buf[BUFSIZE];
+
+/* Abstraction layer for I/O communication */
+
+char getchar(void) {
+        char c;
+       if (SERIAL) {
+                while ((c = uart_getc()) == 0);
+                /* do nothing */
+       }
+        return c;
+}
+
+void cputchar(char c) {
+
+       if (SERIAL) {
+               uart_putc(c);
+       }
+
+}
+
+void cputs(unsigned char *str) {
+     
+     int i;
+     for (i = 0; i < strlen(str); i++)     {
+         cputchar(str[i]);
+    }
+
+}
+
+void terminal() {
+       char *buf;
+        cputs("Terminal running!\n");
+         while (1) {
+                 buf = readline("> ");
+                 /* if (buf != NULL)
+                         if (runcmd(buf, tf) < 0)
+                                 break; */
+         }
+}
+
+char * readline(char *prompt)
+{
+       int i, c, echoing;
+
+       if (prompt != NULL)
+               cputs(prompt); 
+
+       i = 0;
+       echoing = 1;
+       while (1) {
+               c = getchar();
+               if (c < 0) {
+                       cputs("read error");
+                       return NULL;
+               } else if ((c == '\b' || c == '\x7f') && i > 0) {
+                       if (echoing)
+                               cputchar('\b');
+                       i--;
+               } else if (c >= ' ' && i < BUFSIZE-1) {
+                       if (echoing)
+                               cputchar(c);
+                       buf[i++] = c;
+               } else if (c == '\n' || c == '\r') {
+                       if (echoing)
+                               cputchar('\n');
+                       buf[i] = 0;
+                       return buf;
+               }
+       }
+}
diff --git a/uart.c b/uart.c
index 86bf9fe..9dbc01c 100644 (file)
--- a/uart.c
+++ b/uart.c
@@ -3,41 +3,45 @@
 #include <stdint.h>
 #include <stm32.h>
 #include <mmap.h>
+#include <drivers.h>
 
 #define RXNE ((*USART1_SR >> 5) & 0x1)
+#define UARTBUF 256
+#define ECHO 1
+
+static struct {
+                uint8_t buf[UARTBUF] ;
+         uint32_t rpos;
+                uint32_t wpos;
+} linefeed;
 
-#define O_WRITE 0x01
-#define SET 0x02
-#define CLEAR 0x03
 
 void * uart_handler() {
 
-       uart_puts("echo: ");
+       //uart_puts("echo: ");
        while (RXNE) {
                char echochar = *USART1_DR;
+               //uart_putc(echochar);
+                linefeed.buf[linefeed.wpos++] = echochar;
+                 if (linefeed.wpos == UARTBUF)
+                         linefeed.wpos = 0;
                //regw_u32(USART1_DR, echochar, 0, O_WRITE);
-               uart_putc(echochar);
        }
-       uart_putc('\n');
+       //uart_putc('\n');
                
-
 }
-void uart_init() {
 
-       // global interrupt setup
-//     regw_u32(EXTI_IMR, 0x000FFFFF, 0, O_WRITE);
-//     regw_u32(EXTI_RTSR, 0x000FFFFF, 0, O_WRITE);
+void uart_init() {
 
-               
-       regw_u32(RCC_APB2ENR, 0x4005, 0, SET);// enable clock to UART1, AFIO and GPIOA
+       regw_u32(RCC_APB2ENR, 0x4005, 0, SETBIT);// enable clock to UART1, AFIO and GPIOA
        
        /* (after enable GPIOA), on PA9&PA10 and set mode
         *  to alternative output */
-       regw_u32(GPIOA_CRH, 0x444444D4, 0, O_WRITE);
-       regw_u8(AFIO_EVCR, 0x89, 0, O_WRITE);// set event control register, output on PA, Pin 9
+       regw_u32(GPIOA_CRH, 0x444444D4, 0, OWRITE);
+       regw_u8(AFIO_EVCR, 0x89, 0, OWRITE);// set event control register, output on PA, Pin 9
 
        //disable temporarily to set values
-       regw_u8(USART1_CR1, 0x0, 13, SET);
+       regw_u8(USART1_CR1, 0x0, 13, SETBIT);
 
        /* baud rate 115200,  8MHz / (16 * USARTDIV)
         * USARTDIV = 4.34
@@ -45,20 +49,20 @@ void uart_init() {
         * MANTISSA: 0d4.34 0d4 -> 0x4 
         * USART_BRR = 0x45*/
 
-       regw_u32(USART1_BRR, 0x00000045, 0, O_WRITE);
-       regw_u32(USART1_CR2, 0x0000, 0, O_WRITE); //set stop bit, default is 1 stop bit 0x00
+       regw_u32(USART1_BRR, 0x00000045, 0, OWRITE);
+       regw_u32(USART1_CR2, 0x0000, 0, OWRITE); //set stop bit, default is 1 stop bit 0x00
        
        /* parity = 8 bit, UART1 enabled,
         * TX and RX enabled, interrupts enabled */
        //regw_u32(USART1_CR1, 0x000030AC, 0, O_WRITE);
-       regw_u32(USART1_CR1, 0x0000302C, 0, O_WRITE);
+       regw_u32(USART1_CR1, 0x0000302C, 0, OWRITE);
 
        ivt_set_gate(53, uart_handler, 0);
        
        *NVIC_ISER1 = (1 << 5); // Enable UART interrupt at NVIC
 }
 
-void wait() {
+static void wait() {
        for (int i = 0; i < 100; i++);
 }
 
@@ -66,15 +70,29 @@ extern void uart_putc(unsigned char ch) {
        
        if (ch == '\n') {
                while (*USART1_SR & 0x0C) { } // transmit data register empty and complete
-               regw_u8(USART1_DR, 0x0D, 0, O_WRITE); // return line
+               regw_u8(USART1_DR, 0x0D, 0, OWRITE); // return line
        }
 
        while (*USART1_SR & 0x0C) {} 
-               regw_u8(USART1_DR, ch, 0, O_WRITE);
+               regw_u8(USART1_DR, ch, 0, OWRITE);
 
        wait();
 }
 
+char uart_getc(void) {
+         char c;
+
+         if (linefeed.rpos != linefeed.wpos) {
+                 c = linefeed.buf[linefeed.rpos++];
+                 if (linefeed.rpos == UARTBUF)
+                         linefeed.rpos = 0;
+                 return c;
+         }
+         return 0;
+ }
+
+
+// move to library 
 extern void uart_puts(unsigned char *str) {
     int i;
     for (i = 0; i < strlen(str); i++)     {
@@ -82,17 +100,3 @@ extern void uart_puts(unsigned char *str) {
     }
 }
 
-
-
-char uart_read() { 
-
-       /* while (buffer not empty)
-        *      read()
-        *      uart_putc(ch) // echo
-        *              if ch = enter
-        *              process inquiry.
-        */
-       
-}
-
-