CH32V003 - Hardware Fault Interrupt when using TIM2 periodic interrupt - Page 1
Forum section: electronics / general

author: quevedo
author_rank: Newbie
timestamp: November 02, 2023, 08:39:44 pm
content: Hello MCU loversI am starting to experiment with RISC-V, so I decided to get some devboards with the CH32V003 MCU. As I am used to work with Eclipse, I decided to try the official MounRiver Studio IDE. I started with some basic polling UART, and then I moved to a periodical interrupt in TIM2 toggling a GPIO output with a LED.I found an example code at:https://pallavaggarwal.in/2023/09/21/ch32v003-programming-gpio-as-output/I made a few changes to toggle a LED inside the Timer handler, but when trying to run the code (in debug mode), a "Hardware Fault" exception is thrown when the Handler is called. I even removed all GPIO config, leaving the program like the original one, just adding a variable increment inside the handler (see attached main.c).I checked the functions to configure the timer and the ISR, as well as the flag cleaning function, they look OK.I see 2 hypotheses for the problem: either there is a software bug in the functions that I could not find, or there is a hardware bug in my MCUs (I tried running the program in 2 boards, same result).Any ideas?

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 02, 2023, 09:17:16 pm
content: Maybe?https://www.reddit.com/r/RISCV/comments/126262j/notes_on_wch_fast_interrupts/

author: rhodges
author_rank: Frequent Contributor
timestamp: November 02, 2023, 11:10:43 pm
content: I just added this to one of my programs:Code:void TIM2_IRQHandler(void){}And the resulting assembly language is:Code:00000276 <TIM2_IRQHandler>:276: 8082 retYou need to tell gcc that this is an interrupt handler. Something like this:Code:void SysTick_Handler(void) __attribute__((interrupt));void SysTick_Handler(void){SysTick->SR = 0;timer_ms();clock_ms++;if (clock_ms < 100)return;clock_ms -= 100;timer_10();}

author: quevedo
author_rank: Newbie
timestamp: November 03, 2023, 01:39:55 pm
content: Prototyping the handler with the specification "__attribute__((interrupt))" just did the trick! Thank you!

author: HwAoRrDk
author_rank: Super Contributor
timestamp: November 03, 2023, 02:15:47 pm
content: Note if you're using the WCH MounRiver IDE and compiler, you should really be using__attribute__((interrupt("WCH-Interrupt-fast")))instead.Otherwise, if you use regular__attribute__((interrupt), while it will work, if HPE is not turned off (default is on with WCH startup code) then you'll get the CPU registers saved/restored twice in your ISR (once by HPE, once by code generated by the compiler), which is a waste of time.

author: rhodges
author_rank: Frequent Contributor
timestamp: November 03, 2023, 03:02:06 pm
content: Yes, I agree. In my case, I decided to use "any" gcc version and modified startup_ch32v00x.S to not enable HPE. This might be from code you posted.Code:/* Only enable nesting, not HPE */li t0, 0x2csrw 0x804, t0I might enable HPE some day and use "naked" interrupt handlers, and end them with inline assembly "mret". This was discussed on another thread, and I think Bruce said it was dangerous. I would visually inspect the assembly output to verify them. But for now, I am staying with standard interrupt handlers.