#include "link.h" #include "stm32f411.h" static const char *text[] = { "hello, friend.\r\n", "hello, friend?\r\n", "that's lame.\r\n", "maybe i should give you a name.\r\n", "but that's a slippery slope.\r\n", "you're only in my head.\r\n", "we have to remember that.\r\n", "shit.\r\n", "it's actually happening, i'm talking to an imaginary person.\r\n\n" }; static void reset_handler (void) { unsigned int *src, *dst; unsigned int line, off; /* Relocate .data section to SRAM */ src = &_data_lma_start; dst = &_data_vma_start; while (dst < &_data_vma_end) *(dst++) = *(src++); /* Initialize .bss section */ dst = &_bss_vma_start; while (dst < &_bss_vma_end) *(dst++) = 0; /* 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 */ *USART1_CR1 |= (1u << 13); /* 1: USART enable */ /* M: Word length */ *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 */ *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 */ *USART1_CR1 |= (1u << 3); /* 1: Transmitter is enabled */ /* 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 */ /* Test UART and LED ---------------------------------------------------- */ while (1) { for (line = 0; line < sizeof text / sizeof *text; ++line) { /* Print current line */ off = 0; while (text[line][off]) { /* TXE: Transmit data register empty */ while (!(*USART1_SR & (1u << 7))); /* 0: Data is not transferred to the shift register */ /* DR[8:0]: Data value */ *USART1_DR = text[line][off++]; } /* TC: Transmission complete */ while (!(*USART1_SR & (1u << 6))); /* 0: Transmission is not complete */ /* Blink LED */ *GPIOC_ODR ^= (1u << 13); } } } __attribute__ ((section (".vector_table"), used)) static unsigned long const vector_table[] = { (unsigned long) &_sram_end, (unsigned long) reset_handler, };