Closed gagipro closed 1 year ago
This is PlatformIO-core dependent, we don't try and fix this or modify linking order in the core. So yes, if you do have weak functions (especially common for interrupt service routines) that are implemented in libraries, better set lib_archive = no
.
If you want a more concrete answer, I'll need to you to provide a concrete example that fails to link correctly.
This is PlatformIO-core dependent, we don't try and fix this or modify linking order in the core. So yes, if you do have weak functions (especially common for interrupt service routines) that are implemented in libraries, better set
lib_archive = no
.If you want a more concrete answer, I'll need to you to provide a concrete example that fails to link correctly.
Hello Max, it links but interrupt handlers never get triggered, i will try to make a custom link command to see if it changes something in the behavior and let you know.
Thanks a lot
objdump -d
the .elf
file and grep
for the interrupt function. If the whole function code is there for it, it's not a linking fault and the error is elsewhere. That's a 10 second way to eliminate it.
objdump -d
the.elf
file andgrep
for the interrupt function. If the whole function code is there for it, it's not a linking fault and the error is elsewhere. That's a 10 second way to eliminate it.
Thanks again Max, I´ll do it as soon as I´m in front of the pc.
Regards
objdump -d
the.elf
file andgrep
for the interrupt function. If the whole function code is there for it, it's not a linking fault and the error is elsewhere. That's a 10 second way to eliminate it.
ok did that and the whole TIMERx_IRQHandler for each declared TIMER are there, so the issue is somewhere else...
Do you have any clue why our TIMERs are not triggerd, I tried to implement also to decalre VTOR table without any luck...
thanks
Have you tried using one of the minimal GD32 SPL examples for your chip that use TimerX? https://github.com/CommunityGD32Cores/gigadevice-firmware-and-docs/tree/main/GD32F30x/GD32F30x_Firmware_Library_V2.1.4/Examples/TIMER
Have you tried using one of the minimal GD32 SPL examples for your chip that use TimerX? https://github.com/CommunityGD32Cores/gigadevice-firmware-and-docs/tree/main/GD32F30x/GD32F30x_Firmware_Library_V2.1.4/Examples/TIMER
Yes I tried same implementation but I only have the tft of my 3dprinter and I can print some variables, I don´t have a whole development environment.
It´s for this issue :
https://github.com/bigtreetech/BIGTREETECH-TouchScreenFirmware/issues/2391
here's the dump :
I tried also to add a solution I found in this document : https://community.platformio.org/t/custom-board-build-error-gd32f470-eval/29388/24
/ Vector Table base offset /
void SystemInit(void) { ... system_clock_config();
nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET);
nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET);
... }
without any luck of course
I can at least test on a GD32F303CC with a debugging probe. Do you have a minimal, stripped down project that tries to use Timerx that I can just test?
I can at least test on a GD32F303CC with a debugging probe. Do you have a minimal, stripped down project that tries to use Timerx that I can just test?
I have only this : https://github.com/ciotto/BIGTREETECH-TouchScreenFirmware/tree/MKS-GD-TFt28-debug/TFT/src/Libraries
perhaps you will see an issue directly.
So this is about TIMER2_IRQHandler
as defined in TFT\src\User\Hal\buzzer.c
?
So this is about
TIMER2_IRQHandler
as defined inTFT\src\User\Hal\buzzer.c
?
There is also a TIMER6 handler in os_timer.c but I tried to read flag and both don´t work.
What is the exact chip name written on your chip?
What is the exact chip name written on your chip?
Gd32f305vct6
I found this : GD32F303xx microcontrollers where the flash memory density ranges between 128 and 512 Kbytes are called High-density devices (GD32F30X_HD). GD32F303xx microcontrollers where the flash memory density is over 512 Kbytes are called Extra-density devices (GD32F30X_XD). GD32F305xx and GD32F307xx microcontrollers are called connectivity line devices (GD32F30X_CL).
Flash Memory 256K RAM 96K
so, with a Gd32f305vct6, it seems we are facing GD32F30X_CL...
Exactly. But this series does have Timer2 at least per the startup file. The address of the function (+1 for THUMB execution) also ends up in the vector table as I checked. So I think this is rather a problem in code than incapable hardware.
Exactly. But this series does have Timer2 at least per the startup file. The address of the function (+1 for THUMB execution) also ends up in the vector table as I checked. So I think this is rather a problem in code than incapable hardware.
Ok Max but if you have a look to the repo and the issue, you´ll see that we have no clue at all.
If we have a final binary firmware that works and a custom one, do you think it´s possible to isolate at least the offsets or differences between them?
Thanks in advance
Hi,
the vector table of the original firmware uses TIMER2
.
I flashed the 2 different examples but seems that TIMER2_IRQHandler
is never called.
@maxgerhardt you know if breakpoint works on interrupt?
Yes breakpoint works on interrupts.
What exact example are you flashing? Can you upload the project?
TIMER2_inputcapture
and TIMER2_pwminputcapture
. Is not so clean but you can find my tests on this branch, last 2 commits.
Thank you for your help!
This demo is based on the GD32307C-EVAL-V1.1 board, it shows how to use the TIMER peripheral to measure the frequency and duty cycle of an external signal.
Both example require an external signal that is fed into specific pins for the timer hardware to measure. How do you generate that signal?
Oh damn! There is an example that doesn't require an external signal?
The simplest possible example would be a periodic up or downcounter with a capture/compare interrupt. The examples in the SDK either don't use interrupt functions or do use interrupts but require external signals. I'll quickyl write the most basic example and test it.
But I can already tell you that timer interrupts 100% work. We use them in the ArduinoCore-GD32 to output PWM / call functions periodically.
See https://github.com/CommunityGD32Cores/gd32-pio-projects/blob/main/gd32-arduino-pwm-out/src/main.cpp and https://github.com/CommunityGD32Cores/ArduinoCore-GD32/blob/main/cores/arduino/gd32/timer.c.
Yes, probably there is some missing configuration in our project. If I find a working example I can try to find the differences.
Just to be sure, TIMERx interrupt can be triggered without an external signal?
Yes. You can just tell TIMERx to start counting up (using the system clock source diveded by a prescalar), and when the desired value is reached the channel can throw an interrupt. No external signal needed.
And as expected, in my minimal project, the Timer2 works just fine.
I will update the project shortly.
See https://github.com/maxgerhardt/gd32-spl-timer.
Some caveats for your project might be:
rcu_periph_clock_enable(RCU_TIMER2);
)nvic_irq_enable(TIMER2_IRQn, 2, 2);
)timer_interrupt_enable(timer_periph, TIMER_INT_CH0);
)timer_interrupt_flag_clear()
is not doneThe above example blinks the PC13 LED on a standard Bluepill board with a GD32F303CC. Make sure to select the GD32F305VC environment in the project environment selector in the bottom taskbar. These binaries are not compatible with each other, running a binary built for the F303CC will not work on a F305VC and vice-versa.
And remember that you can attach a debugger at any time and read out the peripheral registers for the RCU (clock unit), the timers (timer configuration, current count, active interrupt bits and masks), this should help you.
Thank you so much! Tomorrow I'll try.
I couldn't wait, it works! Tomorrow I try to compare your simple project with the BTT one.
Great to hear it works in the minimal example.
And also actually I've just read the F30x reference manual a bit to understand these timers better. In my example I'm "using" channel 0 interrupts, specifically the output compare function. This will trigger when the counter of the timer matches the value in the CH0VAL register. CH0VAL is by default 0 and is not explicitly initialized in the code. When the counting is started in the timer at count = 0 in an up-counter fashion, up until the value where 1000 milliseconds are expired, the up counter automatically reloads to 0 after expiring. This then lets the CH0VAL match the count and the hardware generates a channel 0 output compare interrupt.
This is a bit unusual to a channel timer like this, I think usually you would go via the "timer update" interrupt ("Once the counter reaches the counter reload value, the counter will start counting up from 0 again. The update event is generated at each counter overflow.."). This seems more natural than using channel 0.
When rewriting the code to use timer update interrupts it justs works as before: https://gist.github.com/maxgerhardt/92e320690fe4dafeefb4be938cef8a3e
Of course the timer can do more like direct PWM output on the dedicted TimerXChannelY pins per the datasheet, but the update timer interrupt is pretty universal and can trigger arbitrary GPIO pin toggles.
Great! This version works also with TIMER6
, the previous one doesn't work.
I moved also the example inside the BTT project but doesn't work.
This project uses a custom linker in order to relocate the firmware at address 0x08007000
and the example works only if I use 0x08000000
as base address.
So I supposed that on this version of the board, the bootloader never relocates the vector table.
I tried to call nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x7000);
but seems useless.
Have you experience with relocated vector tables?
So I supposed that on this version of the board, the bootloader never relocates the vector table.
So what's the value of SCB->VTOR
when the first instruction of your firmware (at 0x08007000) is executed? You do seem to have a SWD debugger like a STLink to check that or print it to make sure?
Do you have the bootloader binary of just a dump of the first 0x7000 bytes of flash of your board? Can you upload it?
Do you have the bootloader binary of just a dump of the first 0x7000 bytes of flash of your board? Can you upload it?
It´s possible to dump it with an stlink ?
Yes. Connect an ST-Link via GND, SWDIO and SWCLK to the board, power up the board regularly, use the ST-Link utility to connect to the chip, set start address 0x800000 and size 0x7000, width 8 bits, then File->Save File As -> flash.bin
Yes. Connect an ST-Link via GND, SWDIO and SWCLK to the board, power up the board regularly, use the ST-Link utility to connect to the chip, set start address 0x800000 and size 0x7000, width 8 bits, then File->Save File As -> flash.bin
Probably @ciotto will be able to do it when he see this message.
Thanks a lot for your help
Sorry, I'm not in front of my PC now, but I already dumped the bootloader and Is available here.
Dumped from address 0x0 with st-info.
Anyway, in BTT firmware SCB->VTOR is correctly setted to 0x08007000, I checked and the value is right.
So I supposed that on this version of the board, the bootloader never relocates the vector table.
So what's the value of
SCB->VTOR
when the first instruction of your firmware (at 0x08007000) is executed? You do seem to have a SWD debugger like a STLink to check that or print it to make sure?
with the stlink it's possible to trace this VTOR address on an original firmware?
bootloader only
it seems that in original firmware, there is something with PTR_USART2 after disabling irq and then reenabling irq after. I see no such things in our custom firmware...
I tried in main and also in SystemInit : __disable_irq(); SCB->VTOR = VECT_TAB_FLASH; __enable_irq();
but no luck
Hello @maxgerhardt it seems I manage to make timers works like this :
https://github.com/bigtreetech/BIGTREETECH-TouchScreenFirmware/issues/2391#issuecomment-1455162067
Do you think it´s normal behavior?
Thanks to explain to us if you understand please.
Still I have issue with usart, perhaps not initialized the correct gd32 way or missing reenabling some other interrupt after bootloader jump, if you have any idea.
Thanks in advance
@maxgerhardt Thanks Max, I solved it : set the pin remapping on right usart and now everything's ok.
Thanks a lot for your time.
Hello,
I saw many issues like those one : https://github.com/platformio/platform-ststm32/issues/468 https://github.com/platformio/platform-ststm32/issues/205
and I was wondering if someone knows if there can be same issue with : platform = https://github.com/CommunityGD32Cores/platform-gd32.git framework = spl
thanks in advance