aboutsummaryrefslogtreecommitdiff
path: root/02-usart/src/kern/main.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2020-11-22 01:06:30 -0700
committerJosh Rahm <joshuarahm@gmail.com>2020-11-22 01:06:30 -0700
commit9f28e53c71d28d04e2775c59944d2887a99f1e86 (patch)
treec0ecb2872c6d27acf08aa73919d709f949200de5 /02-usart/src/kern/main.c
parentebb9123c00d1e9629376b6f0a2f1f4e7e550c2af (diff)
downloadstm32l4-9f28e53c71d28d04e2775c59944d2887a99f1e86.tar.gz
stm32l4-9f28e53c71d28d04e2775c59944d2887a99f1e86.tar.bz2
stm32l4-9f28e53c71d28d04e2775c59944d2887a99f1e86.zip
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/<peripheral> 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.)
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