diff options
Diffstat (limited to '02-usart/src/core')
-rw-r--r-- | 02-usart/src/core/clock.c | 107 | ||||
-rw-r--r-- | 02-usart/src/core/gpio.c | 52 | ||||
-rw-r--r-- | 02-usart/src/core/init.c | 49 | ||||
-rw-r--r-- | 02-usart/src/core/irq.c | 92 | ||||
-rw-r--r-- | 02-usart/src/core/usart.c | 147 |
5 files changed, 0 insertions, 447 deletions
diff --git a/02-usart/src/core/clock.c b/02-usart/src/core/clock.c deleted file mode 100644 index f32cb4e..0000000 --- a/02-usart/src/core/clock.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file sets the system clock to its full glory of 80Mhz - */ - -#include "core/clock.h" -#include "core/flash.h" - -#include <stdint.h> -#include "spin.h" - -#define TIMEOUT 10000 - -int pll_off() -{ - uint32_t c; - - RCC.c_r &= ~BIT(24); /* Turn off pll. */ - for (c = 0; c < TIMEOUT && RCC.c_r & BIT(25); ++c) - ; /* Wait for OFF. */ - - if (c == TIMEOUT) { - return E_TIMEOUT; - } - - return 0; -} - -int pll_on() -{ - uint32_t c; - - RCC.c_r |= BIT(24); /* Turn on PLL. */ - for (c = 0; c < TIMEOUT && !(RCC.c_r & BIT(25)); ++c) - ; /* Wait for RDY. */ - - if (c == TIMEOUT) { - return E_TIMEOUT; - } - - return 0; -} - -int configure_pll( - uint8_t pllp_div_factor, pll_divisor_t pllr, /* System clock divisor. */ - pll_divisor_t pllq, /* Divison factor for PLL48M1CLK. */ - pllp_divisor_t pllp, /* Divison factor for PLLSAI2CLK. */ - uint8_t plln, /* PLL numerator. */ - pllm_divisor_t pllm, /* PLL denominator. */ - pll_src_t pllsrc /* PLL source */) -{ - if (RCC.c_r & BIT(25)) { - /* PLL must be off to configure it. */ - return E_NOT_OFF; - } - - /* Make sure inputs are valid. */ - if (pllp_div_factor == 1 || pllp_div_factor > 31) { - return E_BADPLLP_DIV; - } - if (plln < 8 || plln > 86) { - return E_BADPLLN; - } - - RCC.pllcfg_r = (pllp_div_factor << 27) | (pllr << 24) | (pllq << 20) | - (pllp << 16) | (plln << 8) | (pllm << 4) | (pllsrc << 0); - - return 0; -} - -int set_system_clock_MHz(uint8_t mhz) -{ - /* Set the source of the system colck to MSI temporarily. */ - set_system_clock_src(SYSTEM_CLOCK_SRC_MSI); - - if (mhz <= 8 || mhz > 80) { - return E_BAD_ARG; - } - - pll_off(); - - configure_pll( - 0 /* pllp_div_factor */, PLL_DIVISOR_4 /* pllr: VCO / 4 = mhz MHz. */, - PLL_DIVISOR_4 /* pllq: VCO / 4 = mhz MHz */, PLLP_DIVISOR_7 /* pllp */, - - /* The following set the frequency of VCO to (mhz*4)MHz: mhz * 1 * 4MHz. - */ - mhz /* plln | mhz */, PLLM_DIVISOR_1 /* pllm | 01 */, - PLL_SRC_MSI /* pll src | 04 Mhz */); - - pll_on(); - - /* Configure the flash to have 4 wait states. This is required at - * 80 MHz. */ - FLASH.ac_r &= ~0x07; - FLASH.ac_r |= 0x04; - - /* Set the source of the system colck to PLL. */ - set_system_clock_src(SYSTEM_CLOCK_SRC_PLL); - return 0; -} - -int set_system_clock_src(system_clock_src_t src) -{ - uint8_t value = RCC.cfg_r & ~0x03; - RCC.cfg_r = value | src; - return 0; -} diff --git a/02-usart/src/core/gpio.c b/02-usart/src/core/gpio.c deleted file mode 100644 index c46b1ff..0000000 --- a/02-usart/src/core/gpio.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "core/gpio.h" -#include "core/rcc.h" - -/* - * Sets the mode of a pin on a gpio por. - */ -void set_gpio_pin_mode( - __IO gpio_port_t* gpio_port, gpio_pin_t pin, gpio_pin_mode_t mode) -{ - /* Each pin has a 2-bit mode provided at bits pin#*2 and pin#*2+1 */ - gpio_port->mode_r &= ~(0x03 << pin * 2); - gpio_port->mode_r |= mode << pin * 2; -} - -gpio_output_pin_t set_gpio_pin_output( - __IO gpio_port_t* gpio_port, gpio_pin_t pin) -{ - set_gpio_pin_mode(gpio_port, pin, MODE_OUTPUT); - - return (gpio_output_pin_t){.gpio_port = gpio_port, .pin = pin}; -} - -void set_gpio_output_pin(gpio_output_pin_t pin, bool onoff) -{ - if (onoff) { - pin.gpio_port->output_r |= 1 << pin.pin; - } else { - pin.gpio_port->output_r &= ~(1 << pin.pin); - } -} - -void set_gpio_alternate_function( - __IO gpio_port_t* port, gpio_pin_t gpio_pin, alternate_function_t afn) -{ - __IO uint32_t* reg; - if (gpio_pin < 8) { - reg = &(port->af_rl); - } else { - reg = &(port->af_rh); - gpio_pin -= 8; - } - - uint32_t tmp = *reg & (~0x0f << gpio_pin * 4); - *reg = tmp | (afn << gpio_pin * 4); -} - -#define GPIO_PORTS_BASE_ADDR ((uint8_t*)0x48000000) -__IO gpio_port_t* enable_gpio(gpio_port_number_t gpio_port_number) -{ - RCC.ahb2en_r |= 1 << gpio_port_number; /* Enable the GPIO port. */ - return (__IO gpio_port_t*)(GPIO_PORTS_BASE_ADDR + (gpio_port_number * 0x400)); -} diff --git a/02-usart/src/core/init.c b/02-usart/src/core/init.c deleted file mode 100644 index 0a7cb7f..0000000 --- a/02-usart/src/core/init.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "arch.h" -#include "core/system.h" - -/* Forward-declare the main function. This is implemented in main.c. */ -void main(); - -/* These are defined in the linker script. */ - -#ifdef ARCH_STM32L4 -extern uint32_t INIT_DATA_VALUES; -extern uint32_t DATA_SEGMENT_START; -extern uint32_t DATA_SEGMENT_STOP; -extern uint32_t BSS_START; -extern uint32_t BSS_END; - -/* - * Runs before main. Initializes the data and bss segments by loading them - * into memory. - */ -_Noreturn void on_reset() -{ - uint32_t* src; - uint32_t* dest; - - src = &INIT_DATA_VALUES; - dest = &DATA_SEGMENT_START; - - /* Copy the values from flash into the data segment. */ - while (dest != &DATA_SEGMENT_STOP) { - *(dest++) = *(src++); - } - - /* Everything in the BSS segment is set to zero. */ - dest = &BSS_START; - while (dest != &BSS_END) { - *(dest++) = 0; - } - - /* Set the vector offset table to be at the start - * of FLASH memory. */ - SCB.vto_r = 0x08000000; - - /* Jump to main. */ - main(); - - for(;;); -} - -#endif /* ARCH_STM32L4 */ diff --git a/02-usart/src/core/irq.c b/02-usart/src/core/irq.c deleted file mode 100644 index 47ad924..0000000 --- a/02-usart/src/core/irq.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "core/irq.h" -#include "core/gpio.h" -#include "core/nvic.h" - -#include "arch.h" -#include "delay.h" - -#define IRQ_RESERVED(n) -#define IRQ(name, uname_, n) \ - void WEAK name () { \ - unhandled_isr(n); \ - } -#include "core/isrs.inc" -#undef IRQ_RESERVED -#undef IRQ - -void isr_simple_pin_on() -{ - __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B); - gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3); - - pin_on(pin3); -} - -#define IRQ_RESERVED(n) 0, -#define IRQ(name, uname_, n) name, -const void* vectors[] __attribute__((section(".vectors"))) = { - (void*)0x2000c000, /* Top of stack at top of sram1. 48k */ -#include "core/isrs.inc" -}; -#undef IRQ_RESERVED -#undef IRQ - -/* Encodes the provided number as a series of flashes on the on-board - * LED. The flashes follow as such: - * - * Before the bits of the code are flashed, a rapid succession of 20 flashes - * followed by a pause will occur indicating that the next 8 flashes indicate - * the bits of the provided code. - * - * Eoch of the next eight flashes indicate either a 1 or 0 depending on the - * length of flash. The first flash is the least-significant bit, the next the - * second least, the third third least, etc. - * - * - A quick flash followed by a long pause indicates a 0 bit. - * - A "long" flash followed by a equally long pause indicates a 1 bit. - */ -void unhandled_isr(uint8_t number) -{ - __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B); - gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3); - for (;;) { - for (int i = 0; i < 20; ++ i) { - pin_on(pin3); - delay(1000000); - pin_off(pin3); - delay(1000000); - } - delay(50000000); - - int n = number; - for (int i = 0; i < 8; ++ i) { - if (n & 1) { - // LSB is a 1 - pin_on(pin3); - delay(15000000); - pin_off(pin3); - delay(15000000); - } else { - // LSB is a 0 - pin_on(pin3); - delay(1000000); - pin_off(pin3); - delay(29000000); - } - - n >>= 1; - } - } -} - -void enable_interrupts(interrupt_set_t* interrupts) -{ - for (int i = 0; i < sizeof(NVIC.ise_r) / sizeof(uint32_t); ++ i) - NVIC.ise_r[i] = interrupts->irqs[i]; -} - -void disable_interrupts(interrupt_set_t* interrupts) -{ - for (int i = 0; i < sizeof(NVIC.ise_r) / sizeof(uint32_t); ++ i) - NVIC.ice_r[i] = interrupts->irqs[i]; -} diff --git a/02-usart/src/core/usart.c b/02-usart/src/core/usart.c deleted file mode 100644 index 19d982e..0000000 --- a/02-usart/src/core/usart.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "core/usart.h" -#include "delay.h" -#include "lib.h" -#include <stdarg.h> - -void set_usart1_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src) -{ - rcc->ccip_r = (rcc->ccip_r & (~0x03)) | usart_clk_src; -} - -void set_usart2_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src) -{ - rcc->ccip_r = (rcc->ccip_r & ~(0x03 << 2)) | (usart_clk_src << 2); -} - -void set_usart2_clock_enabled(__IO rcc_t* rcc, bool enable) -{ - if (enable) { - rcc->apb1en1_r |= BIT(17); - } else { - rcc->apb1en1_r &= ~BIT(17); - } -} - -void set_usart1_clock_enabled(__IO rcc_t* rcc, bool enable) -{ - if (enable) { - rcc->apb2en_r |= BIT(14); - } else { - rcc->apb2en_r &= ~BIT(14); - } -} - -void usart_set_parity(__IO usart_t* usart, usart_parity_t parity) -{ - uint32_t c_r1 = usart->c_r1; - c_r1 &= ~(0x3 << 9); - c_r1 |= parity; - usart->c_r1 = c_r1; -} - -void usart_set_enabled(__IO usart_t* usart, usart_enable_t enabled) -{ - if (!enabled) { - regset(usart->c_r1, usart_ue, 0); - } else { - /* Set the rx enabled. */ - regset(usart->c_r1, usart_re, !!(enabled & USART_ENABLE_RX)); - regset(usart->c_r1, usart_te, !!(enabled & USART_ENABLE_TX)); - regset(usart->c_r1, usart_ue, 1); - } -} - -void usart_transmit_byte_sync(__IO usart_t* usart, uint8_t byte) -{ - usart->td_r = byte; - /* Per the manual, when bit 7 of the IS register is set, then the usart - * data has been sent to the shift register. - * - * This bit is cleared by writing to the TD register. */ - while (!(usart->is_r & BIT(7))) - ; -} - -void usart_transmit_bytes_sync(__IO usart_t* usart, const uint8_t* bytes, uint32_t n) -{ - while (n --) { - usart_transmit_byte_sync(usart, *(bytes ++)); - } -} - -void usart_transmit_str_sync(__IO usart_t* usart, const char* str) -{ - while (*str) { - if (*str == '\n') { - usart_transmit_byte_sync(usart, '\r'); - } - usart_transmit_byte_sync(usart, *(str ++)); - } -} - -void usart_enable_dma(__IO usart_t* usart, usart_enable_t enabled) -{ - switch(enabled) { - case USART_ENABLE_DISABLED: - regset(usart->c_r3, usart_dmar, 0); - regset(usart->c_r3, usart_dmat, 0); - break; - - case USART_ENABLE_TX: - regset(usart->c_r3, usart_dmat, 1); - break; - - case USART_ENABLE_RX: - regset(usart->c_r3, usart_dmar, 1); - break; - }; -} - -void usart_printf(__IO usart_t* usart, const char* fmt, ...) -{ - va_list l; - union { - void* ptr; - char* str; - int i; - } b; - char buf[128]; - - va_start(l, fmt); - - while (*fmt != 0) { - if (*fmt == '%') { - switch (*(++fmt)) { - case 0: - goto end; - case '%': - usart_transmit_byte_sync(usart, '%'); - break; - case 'p': - b.ptr = va_arg(l, void*); - hexify(ptr2reg(b.ptr), buf); - usart_transmit_str_sync(usart, "0x"); - usart_transmit_str_sync(usart, buf); - break; - case 'd': - case 'i': - b.i = va_arg(l, int); - decimalify(b.i, buf); - usart_transmit_str_sync(usart, buf); - break; - case 's': - b.str = va_arg(l, char*); - usart_transmit_str_sync(usart, b.str); - } - ++ fmt; - } else { - if (*fmt == '\n') { - usart_transmit_byte_sync(usart, '\r'); - } - usart_transmit_byte_sync(usart, *(fmt ++)); - } - } - -end: - va_end(l); -} |