basic terminal
[cortex-from-scratch] / uart.c
diff --git a/uart.c b/uart.c
index 1cc5c03..9dbc01c 100644 (file)
--- a/uart.c
+++ b/uart.c
 #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))
-
+#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() {
 
-/* 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;
+       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 ((*UART0_FLAG & 0x8)); // busy bit
-               *UART0_DATA = 0x0D; // return line
+       if (ch == '\n') {
+               while (*USART1_SR & 0x0C) { } // transmit data register empty and complete
+               regw_u8(USART1_DR, 0x0D, 0, OWRITE); // return line
        }
-       
-       while ((*UART0_FLAG & 0x8)); // busy bit
-       *UART0_DATA = ch;
-}
 
-extern void uart_puts(unsigned char *str)
-{
+       while (*USART1_SR & 0x0C) {} 
+               regw_u8(USART1_DR, ch, 0, OWRITE);
 
-    int i;
-
-    for (i = 0; i < strlen(str); i++)
-    {
-        uart_putc(str[i]);
-    }
+       wait();
 }
 
+char uart_getc(void) {
+         char c;
 
-char * uart_read() {
+         if (linefeed.rpos != linefeed.wpos) {
+                 c = linefeed.buf[linefeed.rpos++];
+                 if (linefeed.rpos == UARTBUF)
+                         linefeed.rpos = 0;
+                 return c;
+         }
+         return 0;
+ }
 
-       return NULL;
-}
 
+// move to library 
+extern void uart_puts(unsigned char *str) {
+    int i;
+    for (i = 0; i < strlen(str); i++)     {
+        uart_putc(str[i]);
+    }
+}