From: Robin Krens Date: Sun, 14 Jul 2019 17:38:53 +0000 (+0800) Subject: uart functionality (delay) + interrupt tested X-Git-Url: https://robinkrens.nl/gitweb/?a=commitdiff_plain;h=22c1abee1ad44eb88784fd7ff38ca669f41b6c01;p=cortex-from-scratch uart functionality (delay) + interrupt tested --- diff --git a/Makefile b/Makefile index dbcbc85..9f7f517 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,10 @@ all: $(CC) $(CFLAGS) -c -I./include -ffreestanding -o uart.o uart.c $(CC) $(CFLAGS) -c -I./include -ffreestanding -o ivt.o ivt.c $(CC) $(CFLAGS) -c -I./include -ffreestanding -o systick.o systick.c - $(LD) -nostartfiles -T link.ld -o start.out start.o main.o uart.o ivt.o systick.o + $(CC) $(CFLAGS) -c -I./include -ffreestanding -o sysinfo.o sysinfo.c + $(CC) $(CFLAGS) -c -I./include -ffreestanding -o lib.o lib.c + $(CC) $(CFLAGS) -c -I./include -ffreestanding -o mm.o mm.c + $(LD) -nostartfiles -T link.ld -o start.out start.o main.o uart.o ivt.o systick.o sysinfo.o lib.o mm.o $(MKIMG) -Obinary -R .data start.out kernel.bin run: diff --git a/clock.c b/clock.c new file mode 100644 index 0000000..7d5dc19 --- /dev/null +++ b/clock.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + + +void clock_init() { + + + *RCC_CR = *RCC_CR | 0x00010000; + for (int i = 0; i < 200; i++) { + } + *RCC_CFGR = *RCC_CFGR | 0x05000001; +} diff --git a/include/mmap.h b/include/mmap.h index 604579b..1aba65b 100644 --- a/include/mmap.h +++ b/include/mmap.h @@ -6,8 +6,13 @@ * * */ -/* RANDOM DEBUG LOCATION */ -#define RANDOM_ADDR ((volatile uint32_t *)(0x21000000)) + +#define BSS_BASE ((volatile uint32_t)(0x20000000)); +#define MEM_SIZE 512000; + +/* SYSTEM INFO AND DEBUG */ +#define MCU_ID ((volatile uint32_t*)( 0xE0042000)) +#define FLASH_MEM ((volatile uint32_t*)( 0x1FFFF000)) /* SYSTEM CONTROL BLOCK REGISTER */ #define SCB_VTOR ((volatile uint32_t *)( 0xE000ED08)) // VECTOR TABLE @@ -19,6 +24,9 @@ #define STK_CTRL ((volatile uint32_t *)(0xE000E010)) #define STK_RELOAD ((volatile uint32_t *)(0xE000E014)) +/* CLOCK REGISTER */ +#define RCC_CR ((volatile uint32_t *)(0x40021000)) +#define RCC_CFGR ((volatile uint32_t *)(RCC_CR + 0x04)) /* SYSTEM CONTROL REGISTER */ #define SYSCTRL_RCC ((volatile unsigned long *)(0x40021000)) @@ -32,8 +40,11 @@ #define GPIOA_CRH ((volatile unsigned long *)(0x40010804)) #define AFIO_EVCR ((volatile unsigned long *)(0x40010000)) -#define USART1_SR ((volatile unsigned long *)(0x40013800)) -#define USART1_DR ((volatile unsigned long *)(0x40013804)) -#define USART1_BRR ((volatile unsigned long *)(0x40013808)) -#define USART1_CR1 ((volatile unsigned long *)(0x4001380C)) -#define USART1_CR3 ((volatile unsigned long *)(0x40013814)) +/* 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)) diff --git a/include/stm32.h b/include/stm32.h index 2d1544c..37f039f 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -7,6 +7,9 @@ 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); @@ -19,4 +22,10 @@ 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); + #endif diff --git a/ivt.c b/ivt.c index ba617ef..1b4cb9b 100644 --- a/ivt.c +++ b/ivt.c @@ -26,6 +26,8 @@ void ivt_set_gate(unsigned char num, void * isr(), short pri) { /* Dummy interrupt */ void * dummy_isr() { + uart_puts("EXCEPTION X: SYSTEM HALTED\n"); + for(;;); } /* Initialize interrupt vector */ @@ -41,6 +43,9 @@ void ivt_init() { ivt_set_gate(1, dummy_isr, 0); ivt_set_gate(2, dummy_isr, 0); ivt_set_gate(3, dummy_isr, 0); + ivt_set_gate(4, dummy_isr, 0); + ivt_set_gate(5, dummy_isr, 0); + ivt_set_gate(6, 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 diff --git a/lib.c b/lib.c new file mode 100644 index 0000000..62c56e8 --- /dev/null +++ b/lib.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +//#include + +/* Temporary libc functions, which can later be + * replaced by a *real* library */ + +char hexbuf[8] = {'0', '0','0', '0','0', '0','0', '0'}; + +void addrtohex(const uint32_t addr) { + char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'}; + memset(&hexbuf, 0, sizeof(uint32_t) * 8); + uint32_t tmp = addr; + + for (int i = 0; i < 8 ; i++) { + 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]; + } + } + + uart_puts("ADDRESS: 0x"); + for (int i = 7; i >= 0; i--) { + uart_putc(hexbuf[i]); + } + uart_putc('\n'); +} + + +void *malloc(size_t size) { + + + +} + +void free(void * ptr) { + + +} diff --git a/main.c b/main.c index 5453cbd..5b488cf 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ #include #include #include // <-- your own header file located located in ./include +#include void *memcpy(void *dest, void *src, size_t count) @@ -41,12 +42,16 @@ int strlen(const char *str) void main() { - //uart_puts("LOADING SYSTEM...\n"); ivt_init(); +// clock_init(); uart_init(); systick_init(); - uart_puts("WOGSYS LOADING..."); + uart_puts("LOADING SYSTEM 0.1 ...\n"); + sysinfo(); + addrtohex((volatile uint32_t) 0x12345678 ); + addrtohex((volatile uint32_t) *SCB_VTOR ); + // asm("cpsie i"); // enable irq , cpsied f (disable faukts( // loop diff --git a/mm.c b/mm.c new file mode 100644 index 0000000..ba0cc2c --- /dev/null +++ b/mm.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +uint32_t free_base; + + +void mm_init() { + + free_base = MEM_SIZE; + +} + +size_t mm_free() { + + return MEM_SIZE; + +} + diff --git a/sysinfo.c b/sysinfo.c new file mode 100644 index 0000000..fb19c9b --- /dev/null +++ b/sysinfo.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + + +void sysinfo() { + + uint32_t tmp = *MCU_ID; + + uart_puts("CHECKING SYS INFO\n"); + uart_puts("# DEVICE ID: "); + + if (tmp & 0x414) { + uart_puts("HIGH DENSITY\n"); + } + else { + uart_puts("UNKNOWN\n"); + } + + tmp = (tmp >> 16); + uart_puts("# REVISION: "); + switch (tmp) { + case 0x1000: + uart_puts("REVISION A\n"); + break; + case 0x1001: + uart_puts("REVISION Z\n"); + break; + case 0x1003: + uart_puts("REVISION 1/2/3/X/Y\n"); + break; + default: + uart_puts("UNKNOWN\n"); + } + +} + diff --git a/uart.c b/uart.c index 20a8d5e..93b2c91 100644 --- a/uart.c +++ b/uart.c @@ -6,24 +6,31 @@ void uart_init() { - // enable clock to UART1 - *RCC_APB2ENR = 0x4005; - *GPIOA_CRH = 0x444444D4; - *AFIO_EVCR = 0x89; - *USART1_CR1 = (0 << 13); // disable control register - *USART1_CR3 = 0xC0; + *RCC_APB2ENR = 0x4005; // enable clock to UART1, AFIO and GPIOA + *GPIOA_CRH = 0x444444D4; // (after enable GPIOA), on PA9&PA10 and set mode to alternative output + *AFIO_EVCR = 0x89; // (after enable) set event control register, output on PA, Pin 9 - /* baud rate 9600 - * 115200 = 8MHz / (16 * USARTDIV) + *USART1_CR1 = (0 << 13); // disable temporarily to set values + + /* 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*/ - *USART1_BRR = 0x00000045; + /* baud rate 2400 + * + * 16 * 0.33 -> 0x5 + * 208 -> 0x34 */ - /* parity = 8 bit, UART1 enabled, TX and RX enabled, interrupts enabled */ + *USART1_BRR = (volatile uint32_t) 0x00000045; + + *USART1_CR2 = (volatile uint32_t) 0x0000; // set stop bit, default is 1 stop bit 0x00 + // enable DMA + // *USART1_CR3 = 0x0C0; + /* parity = 8 bit, UART1 enabled, + * TX and RX enabled, interrupts enabled */ *USART1_CR1 = (volatile uint32_t) 0x000030AC; /* @@ -34,35 +41,24 @@ void uart_init() { 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 ((*UART1_DR & 0x8)); // busy bit -// *USART1_DR = 0x0D; // return line -// } -// -// while ((*UART0_FLAG & 0x8)); // busy bit - *USART1_DR = ch; + if (ch == '\n') { + while (*USART1_SR & 0x0C) { } // transmit data register empty and complete + *USART1_DR = 0x0D; // return line + } + + while ((*USART1_SR & 0xFF) == 0x0C) {} // busy bit + *USART1_DR = ch; + } +void wait() { + for (int i = 0; i < 100; i++); +} extern void uart_puts(unsigned char *str) { @@ -70,11 +66,13 @@ extern void uart_puts(unsigned char *str) for (i = 0; i < strlen(str); i++) { + wait(); uart_putc(str[i]); } } + char * uart_read() { return NULL;