]> wirehaze git hosting - stm32f411ceu6.git/blobdiff - kernel.c

wirehaze git hosting

faultmask, kentry ()
[stm32f411ceu6.git] / kernel.c
index 6f66e49640c08b006a41bd93c87ce39135e5f692..1545c6e857f48b2c0bd12d70eca5919c200a490c 100644 (file)
--- a/kernel.c
+++ b/kernel.c
@@ -1,71 +1,96 @@
 #include "link.h"
 #include "stm32f411.h"
 
 #include "link.h"
 #include "stm32f411.h"
 
-const char msg[] = "blink ";
-
-static void
-delay (void)
-{
-  volatile unsigned int i;
-  for (i = 0; i < 500000; i++);
-}
+__attribute__ ((noreturn)) extern void kentry (void);
 
 static void
 reset_handler (void)
 {
   unsigned int *src, *dst;
 
 static void
 reset_handler (void)
 {
   unsigned int *src, *dst;
-  unsigned int off;
 
 
-  /* relocate .data to sram  */
+  /* Set FAULTMASK  */
+  asm ("cpsid f");
+
+  /*  Initialize .data and .bss in SRAM  ------------------------------------  */
+
+  /* Relocate .data section  */
   src = &_data_lma_start;
   dst = &_data_vma_start;
 
   while (dst < &_data_vma_end)
     *(dst++) = *(src++);
 
   src = &_data_lma_start;
   dst = &_data_vma_start;
 
   while (dst < &_data_vma_end)
     *(dst++) = *(src++);
 
-  /* initialize .bss  */
+  /* Initialize .bss  */
   dst = &_bss_vma_start;
 
   while (dst < &_bss_vma_end)
     *(dst++) = 0;
 
   dst = &_bss_vma_start;
 
   while (dst < &_bss_vma_end)
     *(dst++) = 0;
 
-  /* (todo) usart pin setup (alt func and enable port clock)  */
+  /*  LED setup  ------------------------------------------------------------  */
+
+  /* GPIOCEN: IO port C clock enable  */
+  *RCC_AHB1ENR |= (1u << 2); /* 1: IO port C clock enabled  */
+  /* MODERy[1:0]: Port x configuration bits (y = 0..15)  */
+  *GPIOC_MODER &= ~(0b11u << 26); /* Clear PC13 bits  */
+  *GPIOC_MODER |= (1u << 26); /* 01: General purpose output mode  */
+
+  /* PC13: 0 = LED on
+   *       1 = LED off  */
 
 
+  /*  SYSCLK setup  ---------------------------------------------------------  */
+
+  /* HSEBYP: HSE clock bypass  */
+  *RCC_CR &= ~(1u << 18); /* 0: HSE oscillator not bypassed  */
+  /* HSEON: HSE clock enable  */
+  *RCC_CR |= (1u << 16); /* 1: HSE oscillator ON  */
+  /* HSERDY: HSE clock ready flag  */
+  while (!(*RCC_CR & (1u << 17))); /* 0: HSE oscillator not ready  */
+  /* SW: System clock switch  */
+  *RCC_CFGR &= ~(0b11u); /* Clear SW bits  */
+  *RCC_CFGR |= (0b01u); /* 01: HSE oscillator selected as system clock  */
+  /* SWS: System clock switch status  */
+  while ((*RCC_CFGR & (0b11u << 2)) != (0b01u << 2)); /* 01: HSE oscillator used
+                                                         as the system clock  */
+  /* HSION: Internal high-speed clock enable  */
+  *RCC_CR &= ~(1u); /* 0: HSI oscillator OFF  */
+
+  /*  UART setup  -----------------------------------------------------------  */
+
+  /* GPIOAEN: IO port A clock enable  */
+  *RCC_AHB1ENR |= (1u); /* 1: IO port A clock enabled  */
+  /* MODERy[1:0]: Port x configuration bits (y = 0..15)  */
+  *GPIOA_MODER &= ~(0b1111u << 18); /* Clear PA9 and PA10 bits  */
+  *GPIOA_MODER |= (0b1010u << 18); /* 10: Alternate function mode  */
+  /* AFRHy: Alternate function selection for port x bit y (y = 8..15)  */
+  *GPIOA_AFRH &= ~(0b11111111u << 4); /* Clear PA9 and PA10 bits  */
+  *GPIOA_AFRH |= (0b01110111u << 4); /* 0111: AF7  */
+
+  /* PA9: USART1_TX
+   * PA10: USART1_RX  */
+
+  /* USART1EN: USART1 clock enable  */
+  *RCC_APB2ENR |= (1u << 4); /* 1: USART1 clock enabled  */
   /* UE: USART enable  */
   /* UE: USART enable  */
-  *USART_CR1 |= (1u << 13); /* 1: USART enable  */
+  *USART1_CR1 |= (1u << 13); /* 1: USART enable  */
   /* M: Word length  */
   /* M: Word length  */
-  *USART_CR1 &= ~(1u << 12); /* 0: 1 Start bit, 8 Data bits, n Stop bit  */
+  *USART1_CR1 &= ~(1u << 12); /* 0: 1 Start bit, 8 Data bits, n Stop bit  */
+  /* PCE: Parity control enable  */
+  *USART1_CR1 &= ~(1u << 10); /* 0: Parity control disabled  */
   /* STOP: STOP bits  */
   /* STOP: STOP bits  */
-  *USART_CR2 &= ~(3u << 12); /* 00: 1 Stop bit  */
-  /* the clock frequnecy is 16mhz initially, so for a baud rate of 115.2 KBps we
-   * need to set USARTDIV=8.6875  */
-  *USART_BRR = (8u << 4) | 11; /* mantissa and fraction (/16)  */
+  *USART1_CR2 &= ~(0b11u << 12); /* 00: 1 Stop bit  */
+  /* Clock frequency: 25MHz
+   * Desired baud rate: 1.2 KBps
+   * USARTDIV = 1302.0625  */
+  *USART1_BRR = (1302u << 4) | 1u; /* mantissa and fraction (/16)  */
   /* TE: Transmitter enable  */
   /* TE: Transmitter enable  */
-  *USART_CR1 |= (1u << 3); /* 1: Transmitter is enabled  */
-
-  /* blink blink setup  */
-  *RCC_AHB1ENR |= (1u << 2);
-  *GPIOC_MODER &= ~(3u << 26);
-  *GPIOC_MODER |= (1u << 26);
-
-  while (1)
-    {
-      /* speak  */
-      off = 0;
-      do
-        {
-          /* TXE: Transmit data register empty  */
-          if (!(*USART_SR & (1u << 7)))
-            continue;
-
-          *USART_DR = msg[off++];
-        }
-      while (off < sizeof msg);
-
-      /* blink  */
-      *GPIOC_ODR ^= (1u << 13);
-      delay ();
-    }
+  *USART1_CR1 |= (1u << 3); /* 1: Transmitter is enabled  */
+
+  /*  Jump to kernel entry code  --------------------------------------------  */
+
+  /* Clear FAULTMASK  */
+  asm ("cpsie f");
+
+  kentry ();
 }
 
 __attribute__ ((section (".vector_table"), used))
 }
 
 __attribute__ ((section (".vector_table"), used))