diff options
Diffstat (limited to '02-usart/src/kern/main.c')
-rw-r--r-- | 02-usart/src/kern/main.c | 117 |
1 files changed, 117 insertions, 0 deletions
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 |