aboutsummaryrefslogtreecommitdiff
path: root/apps/serial2
diff options
context:
space:
mode:
Diffstat (limited to 'apps/serial2')
-rw-r--r--apps/serial2/CMakeLists.txt23
-rw-r--r--apps/serial2/serial2.cpp150
2 files changed, 173 insertions, 0 deletions
diff --git a/apps/serial2/CMakeLists.txt b/apps/serial2/CMakeLists.txt
new file mode 100644
index 0000000..3c31c50
--- /dev/null
+++ b/apps/serial2/CMakeLists.txt
@@ -0,0 +1,23 @@
+add_executable(serial2.elf serial2.cpp
+ ${PLAYGROUND_DIR}/src/init_low.s ${PLAYGROUND_DIR}/src/init_high.cpp ${PLAYGROUND_DIR}/include/init_high.h
+ ${PLAYGROUND_DIR}/include/playground.h
+ ${PLAYGROUND_DIR}/src/debug.cpp ${PLAYGROUND_DIR}/include/debug.h
+ ${PLAYGROUND_DIR}/include/stm32f10x_conf.h
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c
+ )
+target_link_libraries(serial2.elf tinyprintf)
+
+target_include_directories(serial2.elf PUBLIC
+ ${PLAYGROUND_DIR}/include
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x
+ ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc)
+target_compile_definitions(serial2.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES})
+
+set_target_properties(serial2.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld")
+add_extra_commands(serial2.elf)
diff --git a/apps/serial2/serial2.cpp b/apps/serial2/serial2.cpp
new file mode 100644
index 0000000..c0259ea
--- /dev/null
+++ b/apps/serial2/serial2.cpp
@@ -0,0 +1,150 @@
+#include <stdint.h>
+#include <stm32f10x.h>
+#include <stm32f10x_rcc.h>
+#include <stm32f10x_gpio.h>
+#include <stm32f10x_usart.h>
+#include <misc.h>
+
+#include "debug.h"
+#include "tinyprintf.h"
+#include "playground.h"
+
+extern "C"
+__attribute__((naked, used))
+void HardFault_Handler_C(uint32_t *hardfault_args) {
+ dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]);
+ dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]);
+ dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]);
+ dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]);
+ dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]);
+ dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]);
+ dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]);
+ dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]);
+ dbg_printf("\n");
+
+ halt();
+}
+
+size_t strlen(const char *s) {
+ size_t size = 0;
+ while (*s++ != '\0') size++;
+ return size;
+}
+
+int run = 1;
+
+volatile USART_TypeDef *usart1 = (volatile USART_TypeDef *) USART1_BASE;
+
+volatile uint8_t tx_ready = 0;
+
+/*
+ * When we get there the stack pointer is set
+ */
+int main() {
+ SystemInit();
+
+ init_printf(nullptr, dbg_putc);
+
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO
+ | RCC_APB2Periph_USART1
+ | RCC_APB2Periph_GPIOA
+ | RCC_APB2Periph_GPIOB
+ | RCC_APB2Periph_GPIOC,
+ ENABLE);
+
+ /* ***************************************** */
+
+ // Debug on port B
+
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);
+
+ // Make Port B's pin #5 the debug output pin
+ GPIO_InitTypeDef init;
+ GPIO_StructInit(&init);
+ init.GPIO_Pin = GPIO_Pin_5;
+ init.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(GPIOB, &init);
+
+ /* ***************************************** */
+
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);
+
+ /*
+ * PA9 USART1_TX
+ * PA10 USART1_RX
+ */
+
+ // Enable USART1
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
+
+ // Make the TX pin an output
+ GPIO_StructInit(&init);
+ init.GPIO_Pin = GPIO_Pin_9;
+ init.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(GPIOA, &init);
+
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
+ NVIC_InitTypeDef NVIC_InitStruct = {
+ NVIC_IRQChannel: USART1_IRQn,
+ NVIC_IRQChannelPreemptionPriority: 0,
+ NVIC_IRQChannelSubPriority: 0,
+ NVIC_IRQChannelCmd: ENABLE,
+ };
+ NVIC_Init(&NVIC_InitStruct);
+ NVIC_EnableIRQ(USART1_IRQn);
+
+ // 8 bit mode
+ USART1->CR1 &= ~USART_CR1_M;
+ USART1->CR2 &= ~USART_CR2_STOP_1;
+
+ // Set baud rate
+ int mantissa = 39;
+ int fraction = static_cast<int>(16 * 0.0625); // == 1
+ // 72M / (16*39.0625) = 115200
+ USART1->BRR = static_cast<uint16_t >(mantissa << 4 | fraction);
+
+ USART1->CR1 |= USART_CR1_UE /* Set UART Enable */
+ | USART_CR1_TE /* Set Transmission Enable */
+ | USART_CR1_TXEIE; /* Set TX buffer Empty Interrupt Enable */
+
+ char c = 'A';
+ tx_ready = 1;
+ while (run) {
+ // wait for TX to be ready
+ while (!tx_ready);
+ tx_ready = 0;
+
+ GPIO_SetBits(GPIOB, GPIO_Pin_All);
+ GPIO_ResetBits(GPIOB, GPIO_Pin_All);
+
+ USART1->DR = (uint16_t) c;
+ USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
+
+ if (c == 'Z') {
+ c = 'a';
+ } else if (c == 'z') {
+ c = '0';
+ } else if (c == '9') {
+ c = '\n';
+ } else if (c == '\n') {
+ c = 'A';
+ } else {
+ c++;
+ }
+ }
+
+ return 0;
+}
+
+extern "C"
+void USART1_IRQHandler() {
+ tx_ready = 1;
+
+ if (USART_GetITStatus(USART1, USART_IT_TXE) == SET) {
+ // Disable the interrupt
+ USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
+ }
+}