From 9f28e53c71d28d04e2775c59944d2887a99f1e86 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Sun, 22 Nov 2020 01:06:30 -0700 Subject: Large reorganization. What was in core/ is now moved to arch/stm34l4xxx/peripherals. This new directory is *supposed to* to contain raw header files defining just the pertinent register structures for the various peripherals. Peripheral management belongs somewhere in the new `kern/..` directories. This is not completely the case at the moment, so more refactoring needs to be done. What was sitting in the root has now been moved into the kern/ directory. The kern/ directory is to contain everything else other than raw device register definitions. The root of the kern/ tree is reserved for standard library-esque headers. The kern/ directory contains management systems for that peripheral. (At the moment DMA is the only peripheral with a decent management system.) Preferably these peripheral systems should only include their correlating header in arch/stm34l4xxx/peripherals, and use other management systems for handling other peripherals rather than manipulating their raw registers directly. (Though this ideal will require much more critical mass of management systems.) --- 02-usart/src/kern/main.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 02-usart/src/kern/main.c (limited to '02-usart/src/kern/main.c') diff --git a/02-usart/src/kern/main.c b/02-usart/src/kern/main.c new file mode 100644 index 0000000..0e0c89c --- /dev/null +++ b/02-usart/src/kern/main.c @@ -0,0 +1,117 @@ + +#include "arch.h" + +#include "arch/stm32l4xxx/peripherals/clock.h" +#include "arch/stm32l4xxx/peripherals/dma.h" +#include "arch/stm32l4xxx/peripherals/gpio.h" +#include "arch/stm32l4xxx/peripherals/system.h" +#include "arch/stm32l4xxx/peripherals/usart.h" +#include "arch/stm32l4xxx/peripherals/nvic.h" +#include "arch/stm32l4xxx/peripherals/irq.h" + +#include "kern/dma/dma_manager.h" + +#include "kern/delay.h" +#include "kern/mem.h" +#include "kern/spin.h" +#include "kern/string.h" + +/** Overrides the default systick irq handler. */ +void on_systick() +{ + static int is_on = 0; + + __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B); + gpio_output_pin_t pin3 = set_gpio_pin_output(port_b, PIN_3); + + if (is_on) { + pin_off(pin3); + } else { + pin_on(pin3); + } + + is_on = ! is_on; +} + +void setup_usart2(uint32_t baud_rate) +{ + __IO gpio_port_t* port_a = enable_gpio(GPIO_PORT_A); + enable_hsi(&RCC, true); + + set_usart2_clock_src(&RCC, USART_CLK_SRC_HSI16); + set_usart2_clock_enabled(&RCC, USART_CLK_SRC_HSI16); + + set_gpio_pin_mode(port_a, PIN_2, MODE_ALTERNATE); + set_gpio_pin_mode(port_a, PIN_15, MODE_ALTERNATE); + set_gpio_alternate_function(port_a, PIN_2, AFN_7); + set_gpio_alternate_function(port_a, PIN_15, AFN_3); + + /* De-assert reset of USART2 */ + regset(RCC.apb1rst1_r, rcc_usart2rst, 0); + + USART2.c_r1 = 0; + USART2.c_r2 = 0; + USART2.c_r3 = 0; + + usart_set_divisor(&USART2, 16000000 / baud_rate); +} + +#ifdef ARCH_STM32L4 + +/* Main function. This gets executed from the interrupt vector defined above. */ +int main() +{ + /* Enable a higher clock frequency. */ + set_system_clock_MHz(80); + + setup_usart2(115200); + regset(USART2.c_r1, usart_txeie, 1); + regset(USART2.c_r1, usart_rxneie, 1); + usart_enable_dma(&USART2, USART_ENABLE_TX); + usart_set_enabled(&USART2, USART_ENABLE_TX | USART_ENABLE_RX); + + + dma_opts_t opts = DEFAULT_DMA_OPTS; + opts.transfer_complete_interrupt_enable = 1; + int ec = 0; + dma_mem2p_channel_t dma_chan = + select_dma_channel_mem2p(DMA1_PERIPH_USART2_TX, &opts, &ec); + enable_interrupt(dma_channel_get_interrupt(dma_chan.c_)); + + if (ec) { + usart_printf(&USART2, "Select DMA channel failed :( %d\n", ec); + for (;;); + } + + // const char* thing = "Good Thing This Works!"; + + char* str = halloc(128); + kstrcpy(str, "Hello, Heap!"); + + usart_printf(&USART2, "DATA_SEGMENT_START %p\n", &DATA_SEGMENT_START); + usart_printf(&USART2, "DATA_SEGMENT_STOP: %p\n", &DATA_SEGMENT_STOP); + usart_printf(&USART2, "str at: %p\n", str); + usart_printf(&USART2, "str: %s\n", str); + // usart_printf(&USART2, "%s\n", thing); + // regset(USART2.ic_r, usart_tccf, 1); + // dma_mem2p_initiate_transfer(dma_chan, thing, strlen(thing)); + + __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); + + // usart_printf(&USART2, "Start Configuring Countdown!\n"); + + /* Set the countdown to start from 1,000,0000. */ + SCB.strv_r = 10000000; + + /* Enable interrupts. */ + regset(SCB.stcs_r, scb_tickint, 1); + + /* Start the systick. */ + regset(SCB.stcs_r, scb_enable, 1); + + // usart_printf(&USART2, "Start Countdown Started!\n"); +} + +#endif -- cgit