aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-12-20 22:25:48 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2015-12-20 22:25:48 +0100
commitacf22f18828595a0731d3558b7e2d2ba321c926d (patch)
treecf32cd1322184382d79e1a248ce907fbdb5856b6
parent4ce09995e336103ab1d6e20171e732bba1b4cfb2 (diff)
downloadstm32f103-playground-acf22f18828595a0731d3558b7e2d2ba321c926d.tar.gz
stm32f103-playground-acf22f18828595a0731d3558b7e2d2ba321c926d.tar.bz2
stm32f103-playground-acf22f18828595a0731d3558b7e2d2ba321c926d.tar.xz
stm32f103-playground-acf22f18828595a0731d3558b7e2d2ba321c926d.zip
o Interrupt-driven serial port writing.
-rw-r--r--CMakeLists.txt14
-rw-r--r--gdb-start16
-rw-r--r--init_low.s222
-rw-r--r--serial2.cpp98
4 files changed, 289 insertions, 61 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c894168..99b97dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,17 +6,17 @@ project(stm32f103-playground C CXX ASM)
function(add_extra_commands target_name)
add_custom_command(TARGET ${target_name} POST_BUILD
- COMMAND arm-none-eabi-objdump -D ${target_name} > ${target_name}.asm)
+ COMMAND mkdir -p ${target_name}-info && arm-none-eabi-objdump -D ${target_name} > ${target_name}-info/${target_name}.asm)
add_custom_command(TARGET ${target_name} POST_BUILD
- COMMAND arm-none-eabi-nm ${target_name} > ${target_name}.nm)
+ COMMAND mkdir -p ${target_name}-info && arm-none-eabi-nm ${target_name} > ${target_name}-info/${target_name}.nm)
add_custom_command(TARGET ${target_name} POST_BUILD
- COMMAND arm-none-eabi-size ${target_name} > ${target_name}.size)
+ COMMAND mkdir -p ${target_name}-info && arm-none-eabi-size ${target_name} > ${target_name}-info/${target_name}.size)
add_custom_command(TARGET ${target_name} POST_BUILD
- COMMAND arm-none-eabi-readelf -a ${target_name} > ${target_name}.readelf)
+ COMMAND mkdir -p ${target_name}-info && arm-none-eabi-readelf -a ${target_name} > ${target_name}-info/${target_name}.readelf)
add_custom_command(TARGET ${target_name} POST_BUILD
- COMMAND arm-none-eabi-objcopy -O ihex ${target_name} ${target_name}.hex)
+ COMMAND mkdir -p ${target_name}-info && arm-none-eabi-objcopy -O ihex ${target_name} ${target_name}-info/${target_name}.hex)
add_custom_command(TARGET ${target_name} POST_BUILD
- COMMAND arm-none-eabi-objcopy -O binary ${target_name} ${target_name}.bin)
+ COMMAND mkdir -p ${target_name}-info && arm-none-eabi-objcopy -O binary ${target_name} ${target_name}-info/${target_name}.bin)
endfunction()
# https://github.com/cjlano/tinyprintf
@@ -78,7 +78,9 @@ add_executable(serial2.elf serial2.cpp init_low.s init_high.cpp include/stm32f10
debug.cpp debug.h
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c
+ tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c
+ tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c
)
target_link_libraries(serial2.elf tinyprintf)
diff --git a/gdb-start b/gdb-start
index 07bb364..ead4d9b 100644
--- a/gdb-start
+++ b/gdb-start
@@ -27,7 +27,21 @@ define flash_serial1
set confirm on
monitor stm32f1x.cpu mwb 0x20000000 0x5a 20480
- delete breakpoint 1
+ hbreak halt
+end
+
+define flash_serial2
+ shell cd build && make serial2.elf
+
+ monitor arm semihosting enable
+ monitor reset halt
+
+ set confirm off
+ file build/serial2.elf
+ load build/serial2.elf
+ set confirm on
+
+ monitor stm32f1x.cpu mwb 0x20000000 0x5a 20480
hbreak halt
end
diff --git a/init_low.s b/init_low.s
index bd7f329..1c3d10e 100644
--- a/init_low.s
+++ b/init_low.s
@@ -9,24 +9,68 @@ http://stackoverflow.com/questions/9565921/cortex-m3-initialisation
.section .isr_vectors
+/* TODO: Move this to C code */
.global vectors
vectors:
-stacktop: .word 0x20001000
-.word _Reset_Handler
-.word NMI_Handler
-.word HardFault_Handler
-.word MemManage_Handler
-.word BusFault_Handler
-.word UsageFault_Handler
-.word halt
-.word halt
-.word halt
-.word halt
-.word halt
-.word halt
-.word halt
-.word halt
-.word halt
+ .word 0x20001000 /* TODO: this should come from the linker */
+ .word _Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0 /* Not used */
+ .word 0 /* Not used */
+ .word 0 /* Not used */
+ .word 0 /* Not used */
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0 /* Not used */
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN1_TX_IRQHandler
+ .word USB_LP_CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTCAlarm_IRQHandler
+ .word USBWakeUp_IRQHandler
/* VERY significant */
.section .text
@@ -66,4 +110,150 @@ BusFault_Handler:
UsageFault_Handler:
b halt
+/*
+TODO: replace with functions like this:
+void TIM2_IRQHandler() __attribute__ ((weak, alias ("Default_Handler")));
+*/
+
+.weak SVC_Handler
+.thumb_set SVC_Handler, halt
+
+.weak DebugMon_Handler
+.thumb_set DebugMon_Handler, halt
+
+.weak PendSV_Handler
+.thumb_set PendSV_Handler, halt
+
+.weak SysTick_Handler
+.thumb_set SysTick_Handler, halt
+
+.weak WWDG_IRQHandler
+.thumb_set WWDG_IRQHandler, halt
+
+.weak PVD_IRQHandler
+.thumb_set PVD_IRQHandler, halt
+
+.weak TAMPER_IRQHandler
+.thumb_set TAMPER_IRQHandler, halt
+
+.weak RTC_IRQHandler
+.thumb_set RTC_IRQHandler, halt
+
+.weak FLASH_IRQHandler
+.thumb_set FLASH_IRQHandler, halt
+
+.weak RCC_IRQHandler
+.thumb_set RCC_IRQHandler, halt
+
+.weak EXTI0_IRQHandler
+.thumb_set EXTI0_IRQHandler, halt
+
+.weak EXTI1_IRQHandler
+.thumb_set EXTI1_IRQHandler, halt
+
+.weak EXTI2_IRQHandler
+.thumb_set EXTI2_IRQHandler, halt
+
+.weak EXTI3_IRQHandler
+.thumb_set EXTI3_IRQHandler, halt
+
+.weak EXTI4_IRQHandler
+.thumb_set EXTI4_IRQHandler, halt
+
+.weak DMA1_Channel1_IRQHandler
+.thumb_set DMA1_Channel1_IRQHandler, halt
+
+.weak DMA1_Channel2_IRQHandler
+.thumb_set DMA1_Channel2_IRQHandler, halt
+
+.weak DMA1_Channel3_IRQHandler
+.thumb_set DMA1_Channel3_IRQHandler, halt
+
+.weak DMA1_Channel4_IRQHandler
+.thumb_set DMA1_Channel4_IRQHandler, halt
+
+.weak DMA1_Channel5_IRQHandler
+.thumb_set DMA1_Channel5_IRQHandler, halt
+
+.weak DMA1_Channel6_IRQHandler
+.thumb_set DMA1_Channel6_IRQHandler, halt
+
+.weak DMA1_Channel7_IRQHandler
+.thumb_set DMA1_Channel7_IRQHandler, halt
+
+.weak ADC1_2_IRQHandler
+.thumb_set ADC1_2_IRQHandler, halt
+
+.weak USB_HP_CAN1_TX_IRQHandler
+.thumb_set USB_HP_CAN1_TX_IRQHandler, halt
+
+.weak USB_LP_CAN1_RX0_IRQHandler
+.thumb_set USB_LP_CAN1_RX0_IRQHandler, halt
+
+.weak CAN1_RX1_IRQHandler
+.thumb_set CAN1_RX1_IRQHandler, halt
+
+.weak CAN1_SCE_IRQHandler
+.thumb_set CAN1_SCE_IRQHandler, halt
+
+.weak EXTI9_5_IRQHandler
+.thumb_set EXTI9_5_IRQHandler, halt
+
+.weak TIM1_BRK_IRQHandler
+.thumb_set TIM1_BRK_IRQHandler, halt
+
+.weak TIM1_UP_IRQHandler
+.thumb_set TIM1_UP_IRQHandler, halt
+
+.weak TIM1_TRG_COM_IRQHandler
+.thumb_set TIM1_TRG_COM_IRQHandler, halt
+
+.weak TIM1_CC_IRQHandler
+.thumb_set TIM1_CC_IRQHandler, halt
+
+.weak TIM2_IRQHandler
+.thumb_set TIM2_IRQHandler, halt
+
+.weak TIM3_IRQHandler
+.thumb_set TIM3_IRQHandler, halt
+
+.weak TIM4_IRQHandler
+.thumb_set TIM4_IRQHandler, halt
+
+.weak I2C1_EV_IRQHandler
+.thumb_set I2C1_EV_IRQHandler, halt
+
+.weak I2C1_ER_IRQHandler
+.thumb_set I2C1_ER_IRQHandler, halt
+
+.weak I2C2_EV_IRQHandler
+.thumb_set I2C2_EV_IRQHandler, halt
+
+.weak I2C2_ER_IRQHandler
+.thumb_set I2C2_ER_IRQHandler, halt
+
+.weak SPI1_IRQHandler
+.thumb_set SPI1_IRQHandler, halt
+
+.weak SPI2_IRQHandler
+.thumb_set SPI2_IRQHandler, halt
+
+.weak USART1_IRQHandler
+.thumb_set USART1_IRQHandler, halt
+
+.weak USART2_IRQHandler
+.thumb_set USART2_IRQHandler, halt
+
+.weak USART3_IRQHandler
+.thumb_set USART3_IRQHandler, halt
+
+.weak EXTI15_10_IRQHandler
+.thumb_set EXTI15_10_IRQHandler, halt
+
+.weak RTCAlarm_IRQHandler
+.thumb_set RTCAlarm_IRQHandler, halt
+
+.weak USBWakeUp_IRQHandler
+.thumb_set USBWakeUp_IRQHandler, halt
+
.end
diff --git a/serial2.cpp b/serial2.cpp
index 58ea536..c01aa13 100644
--- a/serial2.cpp
+++ b/serial2.cpp
@@ -1,22 +1,30 @@
-#include "tinyprintf.h"
#include <stdint.h>
#include <stm32f10x.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include "tinyprintf.h"
+#include <stm32f10x_usart.h>
+#include <misc.h>
+
#include "debug.h"
+#include "tinyprintf.h"
int init_high();
extern "C" void halt();
-#include "stm32f10x_conf.h"
-
extern "C"
__attribute__((naked))
void HardFault_Handler_C(uint32_t *hardfault_args) {
+ dbg_printf("r0 = 0x%08x (%d)\n", hardfault_args[0], hardfault_args[0]);
+ dbg_printf("r1 = 0x%08x (%d)\n", hardfault_args[1], hardfault_args[1]);
+ dbg_printf("r2 = 0x%08x (%d)\n", hardfault_args[2], hardfault_args[2]);
+ dbg_printf("r3 = 0x%08x (%d)\n", hardfault_args[3], hardfault_args[3]);
+ dbg_printf("r12 = 0x%08x (%d)\n", hardfault_args[4], hardfault_args[4]);
+ dbg_printf("lr = 0x%08x (%d)\n", hardfault_args[5], hardfault_args[5]);
+ dbg_printf("pc = 0x%08x (%d)\n", hardfault_args[6], hardfault_args[6]);
+ dbg_printf("psr = 0x%08x (%d)\n", hardfault_args[7], hardfault_args[7]);
+ dbg_printf("\n");
+
halt();
}
@@ -30,6 +38,8 @@ 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
*/
@@ -79,53 +89,65 @@ int main() {
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_IRQChannel =*/ 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;
- USART1->CR1 |= USART_CR1_UE /* Set UART Enable */
- | USART_CR1_TE; /* Set Transmission Enable */
-
// 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) {
- int txe = USART1->SR & USART_SR_TXE;
-
-// dbg_printf("1:%d?\n", x);
-
-// char mm[100];
-// tfp_sprintf(mm, "2:%d?\n", x);
-// send_command(SYS_WRITE0, mm);
-
-// printf(" %u?\n", usart1->SR);
-// printf(" %u?\n", 1);
-
- if (txe) {
- GPIO_SetBits(GPIOB, GPIO_Pin_All);
- GPIO_ResetBits(GPIOB, GPIO_Pin_All);
-
- USART1->DR = (uint16_t) c;
-// USART1->DR = 0x55;
-
- 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++;
- }
+ // 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);
+ }
+}