tested working terminal and reordering of code
authorRobin Krens <robin@robinkrens.nl>
Wed, 24 Jul 2019 20:26:08 +0000 (04:26 +0800)
committerRobin Krens <robin@robinkrens.nl>
Wed, 24 Jul 2019 20:26:08 +0000 (04:26 +0800)
27 files changed:
Makefile
drivers/README [new file with mode: 0644]
drivers/uart.c [new file with mode: 0644]
include/drivers/uart.h [new file with mode: 0644]
include/lib/pool.h [new file with mode: 0644]
include/lib/regfunc.h [new file with mode: 0644]
include/lib/stdio.h [new file with mode: 0644]
include/lib/string.h [new file with mode: 0644]
include/mmap.h [deleted file]
include/stm32.h [deleted file]
include/sys/mmap.h [new file with mode: 0644]
include/sys/robsys.h [new file with mode: 0644]
ivt.c
lib.c [deleted file]
lib/pool.c [new file with mode: 0644]
lib/regfunc.c [new file with mode: 0644]
lib/stdio.c [new file with mode: 0644]
lib/string.c [new file with mode: 0644]
main.c
mm.c [deleted file]
pool.c [deleted file]
regf.c [deleted file]
start.asm
sysinfo.c
systick.c
term.c
uart.c [deleted file]

index b4a4133..520f0f1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,24 +15,42 @@ LDFLAGS+= -mthumb -mcpu=cortex-m3
 ASFLAGS+= -mcpu=cortex-m3 -mthumb -g
 CFLAGS+= -mcpu=cortex-m3 -mthumb -g -ffreestanding 
 
+INCLUDE+= -Iinclude 
+
 BIN = bin
 
 ODIR = obj
-_OBJ = ivt.o uart.o systick.o sysinfo.o lib.o regf.o pool.o term.o main.o
+_OBJ = ivt.o systick.o sysinfo.o term.o main.o 
 OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
 
+DDIR = obj/drivers
+_DRIVERS = uart.o
+DRIVERS = $(patsubst %, $(DDIR)/%,$(_DRIVERS))
+
+LDIR = obj/lib
+_LIBS = string.o stdio.o regfunc.o pool.o  
+LIBS = $(patsubst %, $(LDIR)/%,$(_LIBS))
+
+$(DDIR)/%.o: drivers/%.c
+       @mkdir -p $(@D) 
+       $(CC) -c $< $(CFLAGS) $(INCLUDE) -o $@
+
 $(ODIR)/%.o: %.c 
        @mkdir -p $(@D)
        $(CC) -c $< $(CFLAGS) -I./include -o $@
 
+$(LDIR)/%.o: lib/%.c 
+       @mkdir -p $(@D)
+       $(CC) -c $< $(CFLAGS) -I./include -o $@
+
 # Start up machine assembly
 as: 
        $(AS) $(ASFLAGS) -o start.o start.asm
 
 # Compile and link all
-kernel: $(OBJ)
+kernel: $(OBJ) $(DRIVERS) $(LIBS) 
        $(AS) $(ASFLAGS) -o start.o start.asm
-       $(LD) -nostartfiles -Map $@.MAP -T link.ld -o $(BIN)/$@.ELF start.o $^ --print-memory-usage
+       $(LD) -nostartfiles -Map $(BIN)/$@.MAP -T link.ld -o $(BIN)/$@.ELF start.o $^ --print-memory-usage
        @echo "Creating binary..."
        @mkdir -p $(BIN)
        $(MKIMG) -Obinary -R .data $(BIN)/$@.ELF  $(BIN)/$@.bin
@@ -56,7 +74,7 @@ flash:
 .PHONY: clean
 
 clean:
-       rm -rf $(ODIR)/*.o start.o $(BIN)/kernel.*
+       rm -rf $(ODIR)/* start.o $(BIN)/kernel.*
 
 # Altijd handig deze template
 #%.o: %.c
diff --git a/drivers/README b/drivers/README
new file mode 100644 (file)
index 0000000..61c2416
--- /dev/null
@@ -0,0 +1,2 @@
+Note to self: Place drivers or loadable modules here
+
diff --git a/drivers/uart.c b/drivers/uart.c
new file mode 100644 (file)
index 0000000..6fc940b
--- /dev/null
@@ -0,0 +1,111 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/mmap.h>
+#include <sys/robsys.h>
+
+#include <lib/regfunc.h>
+#include <lib/string.h>
+
+#include <drivers/uart.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;
+
+
+void * uart_handler() {
+
+       //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('\n');
+               
+}
+
+void uart_init() {
+
+       linefeed.rpos = 0; 
+       linefeed.wpos = 0;
+
+       //memset(&linefeed, 0, (sizeof(struct linefeed) ));
+       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, 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, SETBIT);
+
+       /* baud rate 115200,  8MHz / (16 * USARTDIV)
+        * USARTDIV = 4.34
+        * FRACTION: 16 x 0.34 = 0d5.44 0d5 -> 0x5
+        * MANTISSA: 0d4.34 0d4 -> 0x4 
+        * USART_BRR = 0x45*/
+
+       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, OWRITE);
+
+       ivt_set_gate(53, uart_handler, 0);
+       
+       *NVIC_ISER1 = (1 << 5); // Enable UART interrupt at NVIC
+}
+
+static void wait() {
+       for (int i = 0; i < 100; i++);
+}
+
+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, OWRITE); // return line
+       }
+
+       while (*USART1_SR & 0x0C) {} 
+               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++)     {
+        uart_putc(str[i]);
+    }
+}
+
diff --git a/include/drivers/uart.h b/include/drivers/uart.h
new file mode 100644 (file)
index 0000000..5b0badc
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __UART_H
+#define __UART_H
+
+/* SERIAL INIT AND BASIC I/O 
+ * DON'T USE DIRECTLY USE, RATHER
+ * USE HIGHER LEVEL I/O 
+ * */
+extern void uart_init();
+extern void uart_putc(unsigned char ch); 
+char uart_getc(void); 
+
+#endif
diff --git a/include/lib/pool.h b/include/lib/pool.h
new file mode 100644 (file)
index 0000000..9204d36
--- /dev/null
@@ -0,0 +1,4 @@
+/* Fixed size memory pool allocation  */
+extern void pool_init(size_t size_arg, unsigned int blocks_arg, uint32_t * entry_SRAM); 
+extern void * alloc();
+extern void free(void* p); 
diff --git a/include/lib/regfunc.h b/include/lib/regfunc.h
new file mode 100644 (file)
index 0000000..6b0c50b
--- /dev/null
@@ -0,0 +1,4 @@
+/* regfunc.h */
+extern char * regtohex(uint32_t );
+extern void regw_u8(volatile uint32_t *, uint8_t, short, short);
+extern void regw_u32(volatile uint32_t *, uint32_t, short, short);
diff --git a/include/lib/stdio.h b/include/lib/stdio.h
new file mode 100644 (file)
index 0000000..cf3075b
--- /dev/null
@@ -0,0 +1,8 @@
+/* 
+ * Not really "standard" but doable 
+ * for small programs 
+ * */
+extern char getchar();
+extern void cputchar(char);
+extern void cputs(unsigned char *);
+extern char * readline();
diff --git a/include/lib/string.h b/include/lib/string.h
new file mode 100644 (file)
index 0000000..e8e52f7
--- /dev/null
@@ -0,0 +1,5 @@
+/* string.h TODO */
+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 *);
diff --git a/include/mmap.h b/include/mmap.h
deleted file mode 100644 (file)
index e88c752..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* (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 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 MEM_ADDR(0xE000ED00) 
-#define FLASH_MEM MEM_ADDR(0x1FFFF000) 
-
-/* SYSTEM CONTROL BLOCK REGISTER */
-#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 MEM_ADDR(0xE000E100) // interrupt set enable register
-#define NVIC_ISER1 MEM_ADDR(0xE000E104) // interrupt set enable register
-
-/* SYSTICK REGISTER */
-#define STK_CTRL MEM_ADDR(0xE000E010)
-#define STK_RELOAD MEM_ADDR(0xE000E014)
-
-/* CLOCK REGISTER */
-#define RCC_CR MEM_ADDR(0x40021000)
-#define RCC_CFGR MEM_ADDR(0x40021004)
-
-/* SYSTEM CONTROL REGISTER */
-#define SYSCTRL_RCC MEM_ADDR(0x40021000)
-#define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1
-
-#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 MEM_ADDR(0x40010804)
-
-#define AFIO_EVCR MEM_ADDR(0x40010000)
-
-/* EXTERNAL INTERRUPTS */
-#define EXTI_IMR MEM_ADDR(0x40010400)
-#define EXTI_RTSR MEM_ADDR(0x40010408)
-
-/* UART1 REGISTERS */
-#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)
diff --git a/include/stm32.h b/include/stm32.h
deleted file mode 100644 (file)
index 433c5d4..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#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 *);
-
-/* CLOCK.C */
-extern void clock_init();
-
-/* UART.C */
-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();
-extern void ivt_set_gate(unsigned char, void *(), short);
-
-/* SYSTICK.C */
-extern void systick_init();
-
-/* SYSINFO.C */
-extern void sysinfo();
-
-/* LIB.C */
-extern void addrtohex(const uint32_t);
-
-/* MM.C */
-extern void mm_init();
-extern void * malloc(size_t);
-extern void free(void *);
-extern void test_memory(uint32_t *);
-
-/* POOL.c */
-extern void pool_init(size_t, unsigned int, uint32_t *);
-extern void * alloc();
-extern void free();
-
-/* REGF.C */ 
-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/include/sys/mmap.h b/include/sys/mmap.h
new file mode 100644 (file)
index 0000000..a5921d2
--- /dev/null
@@ -0,0 +1,74 @@
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ * 
+ * $LOG$
+ * 2019/7/20 - ROBIN KRENS     
+ * Initial version 
+ * 
+ * $DESCRIPTION$
+ * 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 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 MEM_ADDR(0xE000ED00) 
+#define FLASH_MEM MEM_ADDR(0x1FFFF000) 
+
+/* SYSTEM CONTROL BLOCK REGISTER */
+#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 MEM_ADDR(0xE000E100) // interrupt set enable register
+#define NVIC_ISER1 MEM_ADDR(0xE000E104) // interrupt set enable register
+
+/* SYSTICK REGISTER */
+#define STK_CTRL MEM_ADDR(0xE000E010)
+#define STK_RELOAD MEM_ADDR(0xE000E014)
+
+/* CLOCK REGISTER */
+#define RCC_CR MEM_ADDR(0x40021000)
+#define RCC_CFGR MEM_ADDR(0x40021004)
+
+/* SYSTEM CONTROL REGISTER */
+#define SYSCTRL_RCC MEM_ADDR(0x40021000)
+#define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1
+
+#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 MEM_ADDR(0x40010804)
+
+#define AFIO_EVCR MEM_ADDR(0x40010000)
+
+/* EXTERNAL INTERRUPTS */
+#define EXTI_IMR MEM_ADDR(0x40010400)
+#define EXTI_RTSR MEM_ADDR(0x40010408)
+
+/* UART1 REGISTERS */
+#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)
diff --git a/include/sys/robsys.h b/include/sys/robsys.h
new file mode 100644 (file)
index 0000000..e02eded
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __SYSTEM_H
+#define __SYSTEM_H
+
+/* CLOCK.C */
+extern void clock_init();
+
+/* IVT.C */
+extern void ivt_init();
+extern void ivt_set_gate(unsigned char, void *(), short);
+
+/* SYSTICK.C */
+extern void systick_init();
+
+/* SYSINFO.C */
+extern void sysinfo();
+
+/* MM.C DELETE TODO */
+//extern void mm_init();
+//extern void * malloc(size_t);
+//extern void free(void *);
+//extern void test_memory(uint32_t *);
+
+/* POOL.c */
+extern void pool_init(size_t, unsigned int, uint32_t *);
+extern void * alloc();
+extern void free();
+
+/* TERM.C */
+extern void terminal();
+
+#endif
diff --git a/ivt.c b/ivt.c
index b3854f1..a6761d0 100644 (file)
--- a/ivt.c
+++ b/ivt.c
@@ -5,14 +5,31 @@
  * Initial version 
  * 
  * $DESCRIPTION$
+ * Set up of basic exceptions and interrupts. These interrupts
+ * don't do much, except for halting the system. 
+ * ivt_set_gate(interrupt nr, function, priority) can be used
+ * later to define more appropriate handling. See timer (timer.c) 
+ * or serial or (uart.c) handling for non-trivial examples.
+ *
+ * The actual code is not much, but there are a lot of details
+ * to consider. Besides that, in case more control is desired over
+ * entering and exiting interrupts (what is pushed on the stack) 
+ * A so-called naked function can be used. See below for more
+ * details.
  * 
+ *
  * */
 
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stm32.h>
-#include <mmap.h>
+
+#include <sys/robsys.h>
+#include <sys/mmap.h>
+
+#include <lib/stdio.h>
+#include <lib/string.h>
+#include <lib/regfunc.h>
 
 /* 
  * These values are pushed on the stack just before
@@ -22,7 +39,7 @@
  * gives me a little bit more control over the caller
  *
  * The following register are pushed to the stack
- * in reverse order
+ * in reverse order:
  *
  * */
 struct interrupt_frame {
@@ -43,6 +60,8 @@ struct interrupt_frame {
  *
  * interrupt vector 1-15: processor exceptions
  * interrupt vector 16-92: irq0 - irq ..
+ *
+ * Vector table needs to be aligned in memory.
  * */
 
 uint32_t __attribute__((aligned(0x100))) ivt[92];
@@ -92,15 +111,17 @@ void ivt_set_gate(unsigned char num, void * isr(), short pri) {
 }
 
 
-/* Dummy interrupt */
+/* Dummy interrupt: comment out the comment to use a naked f
+ * function */
+
 // __attribute__ ((interrupt)) 
 void * dummy_isr(/* struct interrupt_frame * frame */) {
 
        uint8_t nr = *SCB_VTOR_ST & 0xFF;
        
-       uart_puts("EXCEPTION: ");
-       uart_puts(exception_message(nr));
-       uart_puts("\nSYSTEM HALTED\n");
+       cputs("EXCEPTION: ");
+       cputs(exception_message(nr));
+       cputs("\nSYSTEM HALTED\n");
        
        for(;;);
 }
@@ -108,7 +129,7 @@ void * dummy_isr(/* struct interrupt_frame * frame */) {
 /* Initialize interrupt vector  */
 void ivt_init() {
 
-       /* clear entiry IVT, in SRAM location for SRAM + .data (in .bss section) */
+       /* clear entire IVT, in SRAM location for SRAM + .data (in .bss section) */
        memset(&ivt, 0, (sizeof(uint32_t) * 92));
 
        // stack top is loaded from the first entry table on boot/reset
@@ -119,13 +140,10 @@ void ivt_init() {
                ivt_set_gate(i, dummy_isr, 0);
        }
 
-
-       /* the vector table starts at 0x0. Since the address 0x0 point to 
-        * bootcode, it is on ROM or FLASH. The vector table can be
+       /* The vector table is intially at 0x0. The vector table can be
         * relocated to other memory locations. We can do this by setting 
         * 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, OWRITE);
 
 }
diff --git a/lib.c b/lib.c
deleted file mode 100644 (file)
index ba55c01..0000000
--- a/lib.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stm32.h>
-//#include <mmap.h>
-
-/* Temporary libc functions, which can later be 
- * replaced by a *real* library */
-
-char hexbuf[8];
-
-/* Still kind of a debug function */
-void addrtohex(uint32_t addr) {
-       char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
-       memset(&hexbuf, 0, sizeof(uint32_t) * 8);
-
-       for (int i = 0; i < 8 ; i++) {
-               uint32_t tmp = addr;
-               tmp = tmp >> (i * 4);
-               tmp = tmp & 0xF;
-               if ((tmp >= 0) && tmp < 10) {
-                       hexbuf[i] = (char) tmp + 48;
-               }
-               else {
-                       hexbuf[i] = tmpbuf[tmp - 10];
-               }
-       }
-
-        for (int i = 7; i >= 0; i--) {
-               cputchar(hexbuf[i]);
-       } 
-}
-
-
-
-
-
diff --git a/lib/pool.c b/lib/pool.c
new file mode 100644 (file)
index 0000000..63cf3fd
--- /dev/null
@@ -0,0 +1,108 @@
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ * 
+ * $LOG$
+ * 2019/7/20 - ROBIN KRENS     
+ * 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.
+ *
+ * This work is based on an article of Ben Kenwright.
+ * 
+ * Preconditions: programmer should make sure the SRAM entry point
+ * + (blocks * blocksize) is free. 
+ *
+ * $SAMPLE USAGE$
+ * 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)
+ * 
+ * 
+ * * */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/pool.h>
+#include <lib/string.h>
+
+struct MEMPOOL {
+
+       unsigned short blocks; 
+       unsigned short block_size; 
+       unsigned short free_blocks;
+       unsigned short blocks_alloc; 
+       uint32_t * SRAM_entry;
+       uint32_t * m_next; 
+
+};
+
+struct MEMPOOL mem;
+
+void pool_init(size_t size_arg, unsigned int blocks_arg, uint32_t * entry_SRAM) {
+
+        mem.blocks = blocks_arg;
+        mem.block_size = size_arg;
+        mem.SRAM_entry = entry_SRAM;
+        memset(entry_SRAM, 0x00, (sizeof(char) * (size_arg * blocks_arg)));
+        mem.free_blocks = blocks_arg;
+        mem.m_next = mem.SRAM_entry;
+ }
+
+ /* void deletepool()  {
+        mem.SRAM_entry = NULL;
+ } */
+
+/* Helper functions */
+uint32_t * AddrFromIndex(unsigned int i)  {
+       return mem.SRAM_entry + ( i * mem.block_size );
+
+ }
+unsigned int IndexFromAddr(const uint32_t * p) {
+       return (((unsigned int)(p - mem.SRAM_entry)) / mem.block_size);
+
+}
+
+/* alloc and free */ 
+void * alloc() {
+       if (mem.blocks_alloc < mem.blocks ) {
+                unsigned int * p = (unsigned int *)AddrFromIndex( mem.blocks_alloc );
+               *p = mem.blocks_alloc + 1;
+                mem.blocks_alloc++;
+        }
+
+        void* ret = NULL;
+        if ( mem.free_blocks > 0 ) {
+                ret = (void*)mem.m_next;
+                --mem.free_blocks;
+        if (mem.free_blocks!=0) {
+               mem.m_next = AddrFromIndex( *((unsigned int*)mem.m_next) );
+        }
+        else {
+                mem.m_next = NULL;
+        }
+       }
+        
+        return ret;
+ }
+
+void free(void* p)  {
+        if (mem.m_next != NULL) {
+                (*(unsigned int *)p) = IndexFromAddr( mem.m_next );
+                mem.m_next = (uint32_t *)p;
+       }
+        else {
+                *((unsigned int*)p) = mem.blocks;
+                mem.m_next = (uint32_t *) p;
+        }
+               
+        ++mem.free_blocks;
+ }
diff --git a/lib/regfunc.c b/lib/regfunc.c
new file mode 100644 (file)
index 0000000..6add220
--- /dev/null
@@ -0,0 +1,64 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/regfunc.h>
+#include <lib/string.h>
+#include <lib/stdio.h>
+
+#include <sys/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 OWRITE:
+                       *reg = (val << shift);
+                       break;
+               case SETBIT:
+                       *reg = *reg | (val << shift);
+                       break;
+               case CLRBIT:
+                       *reg = (val << shift);
+                       break;
+       }
+}
+
+/* write value (uint32_t) to register */
+void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) {
+
+       switch(flag) {
+               case OWRITE:
+                       *reg = (val << shift);
+                       break;
+               case SETBIT:
+                       *reg = *reg | (val << shift);
+                       break;
+               case CLRBIT:
+                       break;
+       }
+}
+
+/* Print out the hexidecimal representation of an integer
+   After implementation of a printf function, this code
+   will be obsolete.  */
+
+char hexbuf[8];
+char * regtohex(uint32_t addr) {
+       char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
+       memset(&hexbuf, 0, sizeof(uint32_t) * 8);
+
+
+       for (int i = 0; i < 8 ; i++) {
+               uint32_t tmp = addr;
+               tmp = tmp >> (28 - (i * 4));
+               tmp = tmp & 0xF;
+               if ((tmp >= 0) && tmp < 10) {
+                       hexbuf[i] = (char) tmp + 48;
+               }
+               else {
+                       hexbuf[i] = tmpbuf[tmp - 10];
+               }
+       }
+       return &hexbuf[0];      
+}
diff --git a/lib/stdio.c b/lib/stdio.c
new file mode 100644 (file)
index 0000000..ac26165
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/stdio.h>
+#include <lib/string.h>
+#include <drivers/uart.h>
+
+#define SERIAL 1
+#define TFT 0
+#define BUFSIZE 256
+
+static char stdbuf[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]);
+    }
+
+}
+
+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);
+                       stdbuf[i++] = c;
+               } else if (c == '\n' || c == '\r') {
+                       if (echoing)
+                               cputchar('\n');
+                       stdbuf[i] = 0;
+                       return stdbuf;
+               }
+       }
+}
diff --git a/lib/string.c b/lib/string.c
new file mode 100644 (file)
index 0000000..b1618b0
--- /dev/null
@@ -0,0 +1,38 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/string.h> 
+
+// TODO: add more
+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;
+}
diff --git a/main.c b/main.c
index 2b6fdba..35b718e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,55 +1,35 @@
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ * 
+ * $LOG$
+ * 2019/7/20 - ROBIN KRENS     
+ * Initial version 
+ * 
+ * $DESCRIPTION$
+ *
+ * */
+
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stm32.h> // <-- my own header file located located in ./include
-#include <mmap.h>
-
-
-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;
-}
-
 
+#include <sys/robsys.h> 
+#include <sys/mmap.h>
 
+#include <drivers/uart.h>
 
 void main()
 {
-
        ivt_init();
        uart_init();
-       
+
        systick_init();
        
        sysinfo();
 
+       extern void stub();
+       //stub();
+       //__asm__ __volatile__ ("ldc p1, cr1, r0");
+
        terminal();
 
        for(;;) {
diff --git a/mm.c b/mm.c
deleted file mode 100644 (file)
index 1e20f75..0000000
--- a/mm.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
- * 
- * $LOG$
- * 2019/7/20 - ROBIN KRENS     
- * Initial version 
- * 
- * $DESCRIPTION$
- * Simple bitmap on bitband memory implementation for kernel
- * heap. Sensitive to fragmentation over time. Bitband 
- * memory makes it possible to access each bit of memory
- * atomically. 
- * 
- * DEPRECATED
- *
- * */
-
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stm32.h>
-#include <mmap.h>
-
-
-#define CHUNKS 256
-
-#define MEM_VALUE(addr) *((volatile uint32_t *) (addr))
-#define MEM_ADDR(addr) ((uint32_t *) (addr))
-#define BITBAND(a, b) ((a & 0xF0000000) + 0x02000000 + ((a &0xFFFFF)<<5) + (b<<2))
-#define INDEXTOADDR(a) (((a & 0xFFFFF) >> 5) + ((a & 0xFF000000) - 0x02000000))
-
-
-/* Total SRAM: ~ 64kB 
- * Divided into chunks (256 bytes)
- * Each bit will index a chunk
- * Bits needed: 0x100 (= 4 uint32_t)
- * */
-
-//uint32_t chunk_index[4];
-
-void mm_init() {
-
-
-//     memset(&chunk_index, 0, sizeof(uint32_t) * 4);
-
-
-//     uint32_t *p = MEM_ADDR(0x20000278);
-       
-//     extern stub();
-//     stub();
-       // __asm__ __volatile__ ("udiv r1, r3 ,%0" :: "r"(0)); 
-//
-//     for(;;);
-//     *p = (uint32_t volatile) 0x12345678;
-//     *x = (uint32_t volatile) 0x12345679;
-//     addrtohex(p);
-//     addrtohex(*p);
-//     MEM_ADDR(x) = 0x1;
-//
-       
-
-//     char * new = malloc(10);
-//     addrtohex(new);
-//     char * new2 = malloc(10);
-//     addrtohex(new2);
-
-
-       //uint32_t * test = MEM_ADDR(0x20000000);
-       //uint32_t random_location = MEM_VALUE(0x20000000);
-
-       //uint32_t random_location = 0x20000900;
-
-       //MEM_VALUE(random_location);
-       //MEM_VALUE(BITBAND(random_location, 0)) = 0x1;
-
-       //addrtohex(MEM_VALUE(random_location));
-
-
-       
-}
-
- void test_memory(uint32_t * ptr) {
-
-       *ptr = 0xEEEEEEEE;
-       for (int i = 0; i < 100; i++) {
-               ptr++;
-               *ptr = 0xEEEEEEEE;
-       }
-
-} 
-
-/* BIT BAND SCAN */
-
- /* uint32_t fits(uint32_t * current, size_t size) {
-       uint32_t addr_start = current;
-       for (int i = 1; i < size; i++) {
-               current + 4; // next bit offset is 0x4
-               if ((MEM_VALUE(current)) == 0x1) 
-                       return 0x0;
-       }
-       return addr_start;
- } */
-
-
-/* void * malloc(size_t size) {
-
-       if (size < 256) {
-
-               extern char * _endofbss;
-
-               uint32_t start = (uint32_t) &chunk_index[0];    
-               uint32_t current;
-               int offset = 0x100;
-
-               uint32_t * index = MEM_ADDR(BITBAND(start, 0));
-               for(int i = 0; i < CHUNKS; i++) {
-                       if (*index == 0x0) {
-                               addrtohex(*index);
-                               *index = 0x1;
-                               return INDEXTOADDR(((uint32_t)index)) + (i * offset);
-                       }
-                       index += 0x04;
-               }
-               return NULL;
-       }
-} */
-
-
diff --git a/pool.c b/pool.c
deleted file mode 100644 (file)
index 0e0b94d..0000000
--- a/pool.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
- * 
- * $LOG$
- * 2019/7/20 - ROBIN KRENS     
- * 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.
- *
- * This work is based on an article of Ben Kenwright.
- * 
- * Preconditions: programmer should make sure the SRAM entry point
- * + (blocks * blocksize) is free. 
- *
- * $SAMPLE USAGE$
- * 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)
- * 
- * 
- * * */
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stm32.h>
-#include <mmap.h>
-
-
-struct MEMPOOL {
-
-       unsigned short blocks; 
-       unsigned short block_size; 
-       unsigned short free_blocks;
-       unsigned short blocks_alloc; 
-       uint32_t * SRAM_entry;
-       uint32_t * m_next; 
-
-};
-
-struct MEMPOOL mem;
-
-void pool_init(size_t size_arg, unsigned int blocks_arg, uint32_t * entry_SRAM) {
-
-        mem.blocks = blocks_arg;
-        mem.block_size = size_arg;
-        mem.SRAM_entry = entry_SRAM;
-        memset(entry_SRAM, 0x00, (sizeof(char) * (size_arg * blocks_arg)));
-        mem.free_blocks = blocks_arg;
-        mem.m_next = mem.SRAM_entry;
-
-
-/*      uint32_t * a =  alloc();
-        uint32_t * b = alloc();
-        uint32_t * c = alloc();
-        free(c);
-        uint32_t * d = alloc();
-
-        addrtohex(a);
-        addrtohex(b);
-        addrtohex(c);
-        addrtohex(d); */
-
- }
-
-
- /* void deletepool()  {
-        mem.SRAM_entry = NULL;
- } */
-
-/* Helper functions */
-uint32_t * AddrFromIndex(unsigned int i)  {
-       return mem.SRAM_entry + ( i * mem.block_size );
-
- }
-unsigned int IndexFromAddr(const uint32_t * p) {
-       return (((unsigned int)(p - mem.SRAM_entry)) / mem.block_size);
-
-}
-
-/* alloc and free */ 
-void * alloc() {
-       if (mem.blocks_alloc < mem.blocks ) {
-                unsigned int * p = (unsigned int *)AddrFromIndex( mem.blocks_alloc );
-               *p = mem.blocks_alloc + 1;
-                mem.blocks_alloc++;
-        }
-
-        void* ret = NULL;
-        if ( mem.free_blocks > 0 ) {
-                ret = (void*)mem.m_next;
-                --mem.free_blocks;
-        if (mem.free_blocks!=0) {
-               mem.m_next = AddrFromIndex( *((unsigned int*)mem.m_next) );
-        }
-        else {
-                mem.m_next = NULL;
-        }
-       }
-        
-        return ret;
- }
-
-void free(void* p)  {
-        if (mem.m_next != NULL) {
-                (*(unsigned int *)p) = IndexFromAddr( mem.m_next );
-                mem.m_next = (uint32_t *)p;
-       }
-        else {
-                *((unsigned int*)p) = mem.blocks;
-                mem.m_next = (uint32_t *) p;
-        }
-               
-        ++mem.free_blocks;
- }
diff --git a/regf.c b/regf.c
deleted file mode 100644 (file)
index 75f0a3c..0000000
--- a/regf.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stm32.h>
-#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 OWRITE:
-                       *reg = (val << shift);
-                       break;
-               case SETBIT:
-                       *reg = *reg | (val << shift);
-                       break;
-               case CLRBIT:
-                       *reg = (val << shift);
-                       break;
-       }
-}
-
-/* write value (uint32_t) to register */
-void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) {
-
-       switch(flag) {
-               case OWRITE:
-                       //*reg = (val << shift);
-                       *reg = (val << shift);
-                       break;
-               case SETBIT:
-                       *reg = *reg | (val << shift);
-                       break;
-               case CLRBIT:
-                       //
-                       break;
-       }
-}
-
-
index ba161a2..54d2b91 100644 (file)
--- a/start.asm
+++ b/start.asm
@@ -29,6 +29,7 @@ hardfault:
 stub:
        ldr R0,=10
        mov R1,#0
+       ldc2 11, cr0, [r1, #4]
        udiv.w R2, R0, R1 
 
        .data
index fe544ee..e9b2429 100644 (file)
--- a/sysinfo.c
+++ b/sysinfo.c
@@ -1,8 +1,12 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stm32.h>
-#include <mmap.h>
+
+#include <sys/robsys.h>
+#include <sys/mmap.h>
+
+#include <lib/stdio.h>
+#include <lib/regfunc.h>
 
 #define MEM_SIZE       0x00010000 
 #define MEM_OFFSET     0x20000000
@@ -22,7 +26,7 @@ void sysinfo() {
        }
 
        tmp = (tmp >> 16);
-       uart_puts("# REVISION: ");
+       cputs("# REVISION: ");
        switch  (tmp) {
                case 0x1000:
                      cputs("REVISION A\n");
@@ -45,13 +49,13 @@ void sysinfo() {
        uint32_t mem_free = MEM_SIZE - stack_usage - data_bss;
 
        cputs("# TOTAL MEMORY: ");
-       addrtohex(MEM_SIZE);
+       cputs(regtohex(MEM_SIZE));
        cputchar('\n');
        cputs("# FREE MEMORY: ");
-       addrtohex(mem_free);
+       cputs(regtohex(mem_free));
        cputchar('\n');
        cputs("# STACK USAGE: ");
-       addrtohex(stack_usage);
+       cputs(regtohex(stack_usage));
        cputchar('\n');
 
 }
index 40e7862..1d632ec 100644 (file)
--- a/systick.c
+++ b/systick.c
@@ -1,8 +1,11 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stm32.h>
-#include <mmap.h>
+
+#include <sys/robsys.h>
+#include <sys/mmap.h>
+
+#include <lib/regfunc.h> // TODO
 
 struct interrupt_frame {
 
diff --git a/term.c b/term.c
index 8b81255..0628e1e 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,40 +1,41 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stm32.h>
-#include <mmap.h>
+
+#include <sys/robsys.h>
+#include <sys/mmap.h>
+
+#include <lib/stdio.h>
 
 #define SERIAL 1
-#define BUFSIZE 256
+#define BUFSIZE 200
 
-static char buf[BUFSIZE];
 
-/* Abstraction layer for I/O communication */
+int help(int, char**);
 
-char getchar(void) {
-        char c;
-       if (SERIAL) {
-                while ((c = uart_getc()) == 0);
-                /* do nothing */
-       }
-        return c;
-}
+/* 
+ * Built in commands
+ *     info -- shows basic info of system
+ *     reset -- software reset
+ *     show [ADDRESS-ADDRESS] -- shows SRAM range
+ *     switchmode -- switch to unprivileged mode
+ * */
 
-void cputchar(char c) {
+static char buf[BUFSIZE];
 
-       if (SERIAL) {
-               uart_putc(c);
-       }
 
-}
+struct cmd {
+       char * name;
+       char * description;
+       int (*function)(int argc, char ** argsv);
+};
 
-void cputs(unsigned char *str) {
-     
-     int i;
-     for (i = 0; i < strlen(str); i++)     {
-         cputchar(str[i]);
-    }
+static struct cmd builtin[] = 
+       { "info", "show info", help};
 
+int help(int argc, char ** argsv) {
+       sysinfo();
+       return 0;
 }
 
 void terminal() {
@@ -43,40 +44,9 @@ void terminal() {
         cputs("Terminal running!\n");
  
          while (1) {
-                 buf = readline("> ");
+                 buf = readline("root# ");
                  /* 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
deleted file mode 100644 (file)
index 9dbc01c..0000000
--- a/uart.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdbool.h>
-#include <stddef.h>
-#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;
-
-
-void * uart_handler() {
-
-       //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('\n');
-               
-}
-
-void uart_init() {
-
-       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, 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, SETBIT);
-
-       /* baud rate 115200,  8MHz / (16 * USARTDIV)
-        * USARTDIV = 4.34
-        * FRACTION: 16 x 0.34 = 0d5.44 0d5 -> 0x5
-        * MANTISSA: 0d4.34 0d4 -> 0x4 
-        * USART_BRR = 0x45*/
-
-       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, OWRITE);
-
-       ivt_set_gate(53, uart_handler, 0);
-       
-       *NVIC_ISER1 = (1 << 5); // Enable UART interrupt at NVIC
-}
-
-static void wait() {
-       for (int i = 0; i < 100; i++);
-}
-
-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, OWRITE); // return line
-       }
-
-       while (*USART1_SR & 0x0C) {} 
-               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++)     {
-        uart_putc(str[i]);
-    }
-}
-