aboutsummaryrefslogtreecommitdiff
path: root/02-usart/src/kern/main.c
diff options
context:
space:
mode:
Diffstat (limited to '02-usart/src/kern/main.c')
-rw-r--r--02-usart/src/kern/main.c117
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