CommunityGD32Cores / ArduinoCore-GD32

Arduino core for GD32 devices, community developed, based on original GigaDevice's core
Other
85 stars 33 forks source link

EXTI GPIO: cannot assign callback to same pin number on different ports (GD32F130) #105

Open robcazzaro opened 1 year ago

robcazzaro commented 1 year ago

It looks as if the gpio_interrupt_enable() function overwrites pre-existing values when called with the same pins on different ports (e.g. PA15, PB15, PC15). gpio_exti_infor[EXTI_NUMS] can only hold an interrupt and callback to a pin number, not the port/pin combination

If you use the program below

#include <Arduino.h>

void doA()
{
  Serial.println("A15");
}
void doB()
{
  Serial.println("B15");
}
void doC()
{
  Serial.println("C15");
}

void setup()
{
  Serial.begin(9600);
  pinMode(PA15, INPUT_PULLUP);
  pinMode(PB15, INPUT_PULLUP);
  pinMode(PC15, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PA15), doA, CHANGE);
  attachInterrupt(digitalPinToInterrupt(PB15), doB, CHANGE);
  attachInterrupt(digitalPinToInterrupt(PC15), doC, CHANGE);
}

void loop()
{
while (true)
  ;
}

The only callback is to function doC(). PA15 and PB15 don't seem to even generate an interrupt (EXTI4_15_IRQHandler() in gpio_interrupt.c). I'm not even sure if this is a GD32 architecture limitation or a limitation in the GD32 Arduino core. The Gigadevice SPL seems to have a call void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) to configure port and pin. and the EXTISS3 register can contain PA15, PB15 and PC15 (but possibly one at a time, not sure)

Is it possible to attach separate interrupts to identical pin numbers on different ports, or is it a hard GD32 limitation?

Assuming it's a limitation of the GD32F130, should the Arduino core flag the issue somehow to help the user avoid mistakes?

For what is worth, I'm using a Bluepill board with the STM32 replaced by a GD32F130C8, and everything seems to work well (I had to lift pins 35 and 36, connected to VSS and VDD on the STM32, but PF6 and PF7 on the GD32... should probably also disconnect pins 5 and 6 to free up PF0 and PF1 from the 8MHz oscillator, but I simply avoid using PF0 and PF1 for now)

maxgerhardt commented 1 year ago

STM32 had the same limitation with each pin across all ports sharing one EXTI interrupt. So, PA15, PB15, PC15 etc., they will all try and use use the EXTI15 interrupt line / resource, of which there is only one. So, an interrupt can't senisbly be registered, they all have to be on unique pin numbers (0-15), but the port (A, B, C, ..) doesn't matter. I'll double check this in the datasheet.

robcazzaro commented 1 year ago

The more I look into this, the more I think that there can be only one interrupt per pin number, as you say and I suspected. The way to think of the multiplexer, is that line 15 can be triggered by pin 15 on any of the possible ports (PA, PB, PC etc)

I found this https://community.st.com/t5/stm32-mcu-products/handling-multiple-interrupts-on-same-exti-line-in-stm32/m-p/512077, apologies for not searching more on the STM32 before opening this issue. The STM32 datasheet is a bit clearer in this regard.

In a way, it's a good thing to be aware of, and hopefully will help other people in the future. I'll leave it to you to decide if you want to leave it open as a reminder to document this, or to code in a way to warn the user when an interrupt is re-allocated. As far as I'm concerned, this issue is closed. Thanks for your time and comments