From 6e5f2635d162027edd2dd859731610bba5afd971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Sat, 19 Nov 2022 15:46:17 +0100 Subject: [PATCH] Hardfault handler + FPGA abort/interrupt collision fix --- .../Application/Drivers/FPGA/FPGA.cpp | 21 ++++- .../Application/Drivers/FPGA/FPGA.hpp | 1 + .../VNA_embedded/Application/Hardware.cpp | 1 + Software/VNA_embedded/Src/app_freertos.c | 48 +++++++++++ Software/VNA_embedded/Src/stm32g4xx_it.c | 22 ++--- ..._embedded Debug into running system.launch | 80 +++++++++++++++++++ 6 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 Software/VNA_embedded/VNA_embedded Debug into running system.launch diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index 0f95cd9..7f81664 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -14,6 +14,7 @@ static FPGA::HaltedCallback halted_cb; static uint16_t SysCtrlReg = 0x0000; static uint16_t ISRMaskReg = 0x0000; static uint32_t ADC_samplerate; +static volatile bool busy_reading = false; using namespace FPGAHAL; @@ -86,6 +87,7 @@ bool FPGA::Configure(uint32_t start_address, uint32_t bitstream_size) { bool FPGA::Init(HaltedCallback cb) { halted_cb = cb; + busy_reading = false; SysCtrlReg = 0; ISRMaskReg = 0; // Reset FPGA @@ -180,6 +182,11 @@ void FPGA::DisableInterrupt(Interrupt i) { WriteRegister(Reg::InterruptMask, ISRMaskReg); } +void FPGA::DisableAllInterrupts() { + ISRMaskReg = 0x0000; + WriteRegister(Reg::InterruptMask, ISRMaskReg); +} + void FPGA::WriteMAX2871Default(uint32_t *DefaultRegs) { WriteRegister(Reg::MAX2871Def0LSB, DefaultRegs[0] & 0xFFFF); WriteRegister(Reg::MAX2871Def0MSB, DefaultRegs[0] >> 16); @@ -259,19 +266,21 @@ static inline int64_t sign_extend_64(int64_t x, uint16_t bits) { static FPGA::ReadCallback callback; static uint8_t raw[40]; static FPGA::SamplingResult result; -static bool busy_reading = false; bool FPGA::InitiateSampleRead(ReadCallback cb) { if(busy_reading) { - LOG_ERR("ISR while still reading old data"); + LOG_ERR("ISR while SPI is busy"); return false; } callback = cb; - uint8_t cmd[40] = {0xC0, 0x00}; + static uint8_t cmd[40] = {0xC0, 0x00}; // Start data read Low(CS); busy_reading = true; - HAL_SPI_TransmitReceive_DMA(&FPGA_SPI, cmd, raw, 40); + if(HAL_SPI_TransmitReceive_DMA(&FPGA_SPI, cmd, raw, 40) != HAL_OK) { + LOG_ERR("Failed to start SPI DMA"); + busy_reading = false; + } return true; } @@ -313,7 +322,11 @@ void FPGA::StartSweep() { } void FPGA::AbortSweep() { + // abort any FPGA operation by pulling sweep pin low Low(AUX3); + // data transfer of a datapoint might still be active, abort + HAL_SPI_DMAStop(&FPGA_SPI); + busy_reading = false; } void FPGA::SetMode(Mode mode) { diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp index f356f83..db9809c 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp @@ -121,6 +121,7 @@ bool IsEnabled(Periphery p); void SetWindow(Window w); void EnableInterrupt(Interrupt i); void DisableInterrupt(Interrupt i); +void DisableAllInterrupts(); void WriteMAX2871Default(uint32_t *DefaultRegs); void WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs, uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt = false, LowpassFilter filter = LowpassFilter::Auto); diff --git a/Software/VNA_embedded/Application/Hardware.cpp b/Software/VNA_embedded/Application/Hardware.cpp index 3858b72..2406f54 100644 --- a/Software/VNA_embedded/Application/Hardware.cpp +++ b/Software/VNA_embedded/Application/Hardware.cpp @@ -236,6 +236,7 @@ void HW::SetIdle() { Trigger::SetInput(false); FPGA::AbortSweep(); FPGA::SetMode(FPGA::Mode::FPGA); + FPGA::DisableAllInterrupts(); FPGA::DisableHardwareOverwrite(); FPGA::Enable(FPGA::Periphery::SourceChip, false); FPGA::Enable(FPGA::Periphery::SourceRF, false); diff --git a/Software/VNA_embedded/Src/app_freertos.c b/Software/VNA_embedded/Src/app_freertos.c index c9d390c..94173c3 100644 --- a/Software/VNA_embedded/Src/app_freertos.c +++ b/Software/VNA_embedded/Src/app_freertos.c @@ -88,6 +88,54 @@ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackTy /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ +/* The prototype shows it is a naked function - in effect this is just an +assembly function. */ +void HardFault_Handler( void ) __attribute__( ( naked ) ); +void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress ) +{ + /* These are volatile to try and prevent the compiler/linker optimising them + away as the variables never actually get used. If the debugger won't show the + values of the variables, make them global my moving their declaration outside + of this function. */ + volatile uint32_t r0; + volatile uint32_t r1; + volatile uint32_t r2; + volatile uint32_t r3; + volatile uint32_t r12; + volatile uint32_t lr; /* Link register. */ + volatile uint32_t pc; /* Program counter. */ + volatile uint32_t psr;/* Program status register. */ + + r0 = pulFaultStackAddress[ 0 ]; + r1 = pulFaultStackAddress[ 1 ]; + r2 = pulFaultStackAddress[ 2 ]; + r3 = pulFaultStackAddress[ 3 ]; + + r12 = pulFaultStackAddress[ 4 ]; + lr = pulFaultStackAddress[ 5 ]; + pc = pulFaultStackAddress[ 6 ]; + psr = pulFaultStackAddress[ 7 ]; + + /* When the following line is hit, the variables contain the register values. */ + for( ;; ); +} + +/* The fault handler implementation calls a function called +prvGetRegistersFromStack(). */ +void HardFault_Handler(void) +{ + __asm volatile + ( + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r1, [r0, #24] \n" + " ldr r2, handler2_address_const \n" + " bx r2 \n" + " handler2_address_const: .word prvGetRegistersFromStack \n" + ); +} /* USER CODE END Application */ diff --git a/Software/VNA_embedded/Src/stm32g4xx_it.c b/Software/VNA_embedded/Src/stm32g4xx_it.c index b1e3206..fde49d0 100644 --- a/Software/VNA_embedded/Src/stm32g4xx_it.c +++ b/Software/VNA_embedded/Src/stm32g4xx_it.c @@ -85,17 +85,17 @@ void NMI_Handler(void) /** * @brief This function handles Hard fault interrupt. */ -void HardFault_Handler(void) -{ - /* USER CODE BEGIN HardFault_IRQn 0 */ - - /* USER CODE END HardFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_HardFault_IRQn 0 */ - /* USER CODE END W1_HardFault_IRQn 0 */ - } -} +//void HardFault_Handler(void) +//{ +// /* USER CODE BEGIN HardFault_IRQn 0 */ +// +// /* USER CODE END HardFault_IRQn 0 */ +// while (1) +// { +// /* USER CODE BEGIN W1_HardFault_IRQn 0 */ +// /* USER CODE END W1_HardFault_IRQn 0 */ +// } +//} /** * @brief This function handles Memory management fault. diff --git a/Software/VNA_embedded/VNA_embedded Debug into running system.launch b/Software/VNA_embedded/VNA_embedded Debug into running system.launch new file mode 100644 index 0000000..d8f4248 --- /dev/null +++ b/Software/VNA_embedded/VNA_embedded Debug into running system.launch @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +