further ivt and isr implementation
[cortex-from-scratch] / uart.c
1 #include <stdbool.h>
2 #include <stddef.h>
3 #include <stdint.h>
4 #include <stm32.h>
5 #include <mmap.h>
6
7 #define RXNE ((*USART1_SR >> 5) & 0x1)
8
9 #define O_WRITE 0x01
10 #define SET 0x02
11 #define CLEAR 0x03
12
13 void * uart_handler() {
14
15         uart_puts("echo: ");
16         while (RXNE) {
17                 char echochar = *USART1_DR;
18                 //regw_u32(USART1_DR, echochar, 0, O_WRITE);
19                 uart_putc(echochar);
20         }
21         uart_putc('\n');
22                 
23
24 }
25 void uart_init() {
26
27         // global interrupt setup
28 //      regw_u32(EXTI_IMR, 0x000FFFFF, 0, O_WRITE);
29 //      regw_u32(EXTI_RTSR, 0x000FFFFF, 0, O_WRITE);
30
31                 
32         regw_u32(RCC_APB2ENR, 0x4005, 0, SET);// enable clock to UART1, AFIO and GPIOA
33         
34         /* (after enable GPIOA), on PA9&PA10 and set mode
35          *  to alternative output */
36         regw_u32(GPIOA_CRH, 0x444444D4, 0, O_WRITE);
37         regw_u8(AFIO_EVCR, 0x89, 0, O_WRITE);// set event control register, output on PA, Pin 9
38
39         //disable temporarily to set values
40         regw_u8(USART1_CR1, 0x0, 13, SET);
41
42         /* baud rate 115200,  8MHz / (16 * USARTDIV)
43          * USARTDIV = 4.34
44          * FRACTION: 16 x 0.34 = 0d5.44 0d5 -> 0x5
45          * MANTISSA: 0d4.34 0d4 -> 0x4 
46          * USART_BRR = 0x45*/
47
48         regw_u32(USART1_BRR, 0x00000045, 0, O_WRITE);
49         regw_u32(USART1_CR2, 0x0000, 0, O_WRITE); //set stop bit, default is 1 stop bit 0x00
50         
51         /* parity = 8 bit, UART1 enabled,
52          * TX and RX enabled, interrupts enabled */
53         //regw_u32(USART1_CR1, 0x000030AC, 0, O_WRITE);
54         regw_u32(USART1_CR1, 0x0000302C, 0, O_WRITE);
55
56         ivt_set_gate(53, uart_handler, 0);
57         
58         *NVIC_ISER1 = (1 << 5); // Enable UART interrupt at NVIC
59 }
60
61 void wait() {
62         for (int i = 0; i < 100; i++);
63 }
64
65 extern void uart_putc(unsigned char ch) {
66         
67         if (ch == '\n') {
68                 while (*USART1_SR & 0x0C) { } // transmit data register empty and complete
69                 regw_u8(USART1_DR, 0x0D, 0, O_WRITE); // return line
70         }
71
72         while (*USART1_SR & 0x0C) {} 
73                 regw_u8(USART1_DR, ch, 0, O_WRITE);
74
75         wait();
76 }
77
78 extern void uart_puts(unsigned char *str) {
79     int i;
80     for (i = 0; i < strlen(str); i++)     {
81         uart_putc(str[i]);
82     }
83 }
84
85
86
87 char uart_read() { 
88
89         /* while (buffer not empty)
90          *      read()
91          *      uart_putc(ch) // echo
92          *              if ch = enter
93          *              process inquiry.
94          */
95         
96 }
97
98