implementation of interrupts, SysTick exception
authorRobin Krens <robin@robinkrens.nl>
Wed, 10 Jul 2019 20:11:15 +0000 (04:11 +0800)
committerRobin Krens <robin@robinkrens.nl>
Wed, 10 Jul 2019 20:11:15 +0000 (04:11 +0800)
Makefile
include/mmap.h
include/stm32.h
ivt.c
link.ld
main.c
systick.c [new file with mode: 0644]

index 58ae9ac..dbcbc85 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,11 +15,12 @@ all:
        $(CC) $(CFLAGS) -c -I./include -ffreestanding -o main.o main.c
        $(CC) $(CFLAGS) -c -I./include -ffreestanding -o uart.o uart.c
        $(CC) $(CFLAGS) -c -I./include -ffreestanding -o ivt.o ivt.c 
-       $(LD) -nostartfiles -T link.ld -o start.out start.o main.o uart.o ivt.o
+       $(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
        $(MKIMG) -Obinary -R .data start.out kernel.bin
 
 run:
-       qemu-system-arm -serial stdio  -M lm3s6965evb -kernel kernel.bin
+       /usr/local/bin/qemu-system-arm -serial stdio  -M stm32-f103c8 -kernel kernel.bin
 
 examine:
        arm-none-eabi-objdump -S start.out
index ad45038..7caee1d 100644 (file)
@@ -4,15 +4,23 @@
  * a STM32F013RC6. Addresses of peripherals vary amongst 
  * manufacturers of boards with similar chips
  * 
- * Peaceļ¼
  * */
 
-/* VECTOR TABLE */
-#define NVIC_VECTTBL ((volatile unsigned long *)( 0xE000ED08))
-#define NVIC_EN0 ((volatile unsigned long *)( 0xE000E100))
-#define NVIC_EN1 ((volatile unsigned long *)( 0xE000E104))
+/* RANDOM DEBUG LOCATION */
+#define RANDOM_ADDR ((volatile uint32_t *)(0x21000000))
 
-/* SYSTEM CONTROL REGISTERS */
+/* SYSTEM CONTROL BLOCK REGISTER */
+#define SCB_VTOR ((volatile uint32_t *)( 0xE000ED08)) // VECTOR TABLE
+
+/* NESTED VECTOR INTERRUPT CONTROL REGISTER */
+#define NVIC_ISER0 ((volatile uint32_t*)( 0xE000E100)) // interrupt set enable register
+
+/* SYSTICK REGISTER */
+#define STK_CTRL ((volatile uint32_t *)(0xE000E010))
+#define STK_RELOAD ((volatile uint32_t *)(0xE000E014))
+
+
+/* SYSTEM CONTROL REGISTER */
 #define SYSCTRL_RCC ((volatile unsigned long *)(0x400FE060))
 #define SYSCTRL_RIS ((volatile unsigned long *)(0x400FE050))
 #define SYSCTRL_RCGC1 ((volatile unsigned long *)(0x400FE104))
index e4409f2..2d1544c 100644 (file)
@@ -6,8 +6,6 @@ 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 *);
-extern unsigned char inportb (uint32_t _addr);
-extern void outportb (uint32_t _addr, unsigned char _data);
 
 /* UART.C */
 extern void uart_init();
@@ -16,5 +14,9 @@ extern void uart_puts(unsigned char *);
 
 /* IVT.C */
 extern void ivt_init();
+extern void ivt_set_gate(unsigned char, void *(), short);
+
+/* SYSTICK.C */
+extern void systick_init();
 
 #endif
diff --git a/ivt.c b/ivt.c
index fadf533..ba617ef 100644 (file)
--- a/ivt.c
+++ b/ivt.c
@@ -4,82 +4,49 @@
 #include <stm32.h>
 #include <mmap.h>
 
-/* TIMER, TODO: move to timer.c */
-
-
+/* 
+ * Vector table, each entry contains an interrupt
+ * service routine:  * 
+ *
+ * interrupt vector 1-15: processor exceptions
+ * interrupt vector 16-32: irq0 - irq ..
+ * */
 
-/* Interrupt vector can contain 16 exceptions and up to 256 interrupts
- * In this code we use 16 exceptions and 36 interrupts  
- * (note: this should be aligned to the vector table size) 
- * Offsets of each entry is:  0x0, 0x80, 0x100, 0x180 .. */
+uint32_t ivt[32];
 
-/* interrupt vector 1-15: processor exceptions
- * interrupt vector 16-43: irq0 - irq .. */
-uint32_t ivt[43];
 
-/* * base is location of interrupt service request
- * */
 void ivt_set_gate(unsigned char num, void * isr(), short pri) {
 
        ivt[num] = (uint32_t) isr;
-       // TODO priority
+       *NVIC_ISER0 = (1 << ((uint32_t)(num) & 0x1F));
+       /* Priorities */
 }
 
-// test Interrupt service routine
-void * test_ISR() {
-       uart_puts("PING!");
+
+/* Dummy interrupt */
+void * dummy_isr() {
+
 }
 
 /* Initialize interrupt vector  */
-
 void ivt_init() {
 
        /* clear entiry IVT, in SRAM location for SRAM + .data (in .bss section) */
-       memset(&ivt, 0, (sizeof(uint32_t) * 44));
+       memset(&ivt, 0, (sizeof(uint32_t) * 87));
 
        // stack top is loaded from the first entry table on boot/reset
        // don't need to relocate or init this here
-
-       // copy old vectors 
        extern void * reset,  * nmi, * hardfault;
-       //extern uint32_t reset, nmi, hardfault;
-       //ivt[1] = &reset;
-       //ivt[2] = &nmi;
-       //ivt[3] = &hardfault;
-
-       ivt_set_gate(1, test_ISR, 0);
-       ivt_set_gate(2, test_ISR, 0);
-       ivt_set_gate(3, test_ISR, 0);
-       ivt_set_gate(15, test_ISR ,0);
-
-       // enable all interrupts
-       
-       *SYSCTRL_RCGC1 = *SYSCTRL_RCGC1 | 0x00010000;
-
-       // TODO systimer 
-       // ivt[15]
-       *NVIC_EN0 = *NVIC_EN0 | 0x00008003;
-//     *NVIC_EN1 = (volatile uint32_t) 0xFFFFFFFF; // TODO not all registers
-
-       // priority levels are 0 by default (only executable by kernel)
-       
-       /* disable all interrupts
-        * MOV R0, #1 ; disable all
-        * MSR PRIMASK, R0 
-        * MOV R0, #0 ; allow all
-        * MSR PRIMASK, R0 */
 
-       
-       
-       /* relocate the vector table to (S)RAM 
-        * vector table starts at 0x0. since the address 0x0 point to bootcode, it is on ROM or FLASH. 
-        * the value cannot be changed during runtime. however, the vector table can be
-        * relocated to other memory locations in the code or RAM later on
-        *
-        * we can do this by setting a register in the NVIC called
-        * the vector table offset register (address 0xE000ED08).  */
+       ivt_set_gate(1, dummy_isr, 0);
+       ivt_set_gate(2, dummy_isr, 0);
+       ivt_set_gate(3, 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
+        * relocated to other memory locations. We can do this by setting 
+        * a register in the NVIC called the vector table offset register */
 
-       *NVIC_VECTTBL = (volatile unsigned long) &ivt; 
+       *SCB_VTOR = (volatile uint32_t) &ivt; 
 
 }
diff --git a/link.ld b/link.ld
index 096fb5d..d1a01dd 100644 (file)
--- a/link.ld
+++ b/link.ld
@@ -1,7 +1,7 @@
 /* 
  * MEMORY MAP
 {
-       FLASH (xr) : ORIGIN = 0x00000000, LENGTH = 512K
+       FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 512K
        SRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
 } */
 
diff --git a/main.c b/main.c
index c17c664..58e4771 100644 (file)
--- a/main.c
+++ b/main.c
@@ -36,31 +36,17 @@ int strlen(const char *str)
     return retval;
 }
 
-unsigned char inportb (uint32_t _addr) 
-{
-    unsigned char rv;
-    //__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
-    return rv;
-
-}
 
-void outportb (uint32_t _addr, unsigned char _data)
-{
 
-  // __asm__ __volatile__ ("str %1, %0"  : "=r" (_data)  : "m" (_addr) );
-
-   // __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
-}
 
 void main()
 {
-       uart_init();
-       uart_puts("LOADING SYSTEM...\n");
+       //uart_init();
+       //uart_puts("LOADING SYSTEM...\n");
 
        ivt_init();
-
-       //extern void stub();
-       //stub();
+       systick_init();
+//     asm("cpsie i"); // enable irq , cpsied f (disable faukts(
 
        // loop
        for(;;) {
diff --git a/systick.c b/systick.c
new file mode 100644 (file)
index 0000000..b9c8756
--- /dev/null
+++ b/systick.c
@@ -0,0 +1,28 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stm32.h>
+#include <mmap.h>
+
+
+void * systick_handler() {
+
+       *RANDOM_ADDR = (volatile uint32_t) 0x10101010 ;
+}
+
+void systick_init() {
+
+       /* Enable the counter and enable the interrupt
+        * associated with it */
+       *STK_CTRL = (volatile uint32_t) 0x00000003;
+
+       /* The counter reload register here holds 
+        * 0x1000 -- that's 4096 clock cycles -- if 
+        * it is down to zero it is restores the value */
+       *STK_RELOAD = (volatile uint32_t) 0x00000400; 
+
+       /* Every time the counter counts down to zero
+        * a systick exception is asserted. Systick has
+        * exception number 15. in the vector table  */
+       ivt_set_gate(15, systick_handler, 0); 
+}