GPIO PAL callbacks stop working

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
TKorho
Posts: 18
Joined: Mon Sep 13, 2021 6:46 pm
Has thanked: 2 times
Been thanked: 1 time

GPIO PAL callbacks stop working

Postby TKorho » Wed Sep 22, 2021 5:09 pm

Hello!
This may be configuration problem, compilation problem, or plain stupidity from by part. Or it could be some sort of bug... I bet on my error.

I have an STM32 F4 Nucleo-64 program, that follows numerous SPI buses. Thus I cannot use ChibiOS HAL SPI, but am listening the different SPI buses with HAL GPIO PAL code.
I have 8+ SPI buses, and I try to interrupt (palEnableLineEvent(...) and palSettLineCallback(...)) each SCLK. In the interrupt callbacks I only read in the MOSI into my own (global) data structures. Later I process the data based on inactive CS lines for each SPI, and collect them for future use, in another normal priority thread. I am only the receiver, so there is no bit banging timing problems or anything. So far any data is cleanly and easily matching the SCLK speeds.(In fact I can even easily poll a single SPI with chThreadSleep without losing data.)

However I run into mystic problems, when some of the lines will not trigger. The callback simply will not trigger. For one or two of the SPIs. The rest will work perfectly. The mystic thing is that failing triggers change depending on declare order! But not obviously, usually it is the "oldest" SPIs that go passive, but not always. When I change the declare order, the working buses change also.

In a bit more detail: The PAL lines, and Callback declarations:

Code: Select all

static inline void setIOPinModes(Spi *spi){
  palSetLineMode(PAL_LINE(spi->latchPort,spi->latchPin),PAL_MODE_INPUT_PULLUP);
  palSetLineMode(PAL_LINE(spi->clockPort,spi->clockPin),PAL_MODE_INPUT_PULLUP);
  palSetLineMode(PAL_LINE(spi->mosiPort,spi->mosiPin),PAL_MODE_INPUT_PULLUP);
}
static inline void setPalEvents(Spi *spi,void (*cbPulseX)(void*)) {
  palEnableLineEvent(PAL_LINE(spi->clockPort, spi->clockPin),PAL_EVENT_MODE_FALLING_EDGE);
  palSetLineCallback(PAL_LINE(spi->clockPort, spi->clockPin),cbPulseX,NULL);
}

The SPIs be declared in the main()-function:

Code: Select all

// Set the GPIO lines
  setIOPinModes(&spi1);
  setIOPinModes(&spi2);
  setIOPinModes(&spi3);
  setIOPinModes(&spi4);
  setIOPinModes(&spi5);
  setIOPinModes(&spi6);
  setIOPinModes(&spi7);
  setIOPinModes(&spi8);

  // Set the GPIO / SPI SCLK interrupt events
  setPalEvents(&spi5,clockPulse5);
  setPalEvents(&spi6,clockPulse6);
  setPalEvents(&spi2,clockPulse2);
  setPalEvents(&spi4,clockPulse4);
  setPalEvents(&spi7,clockPulse7);
  setPalEvents(&spi8,clockPulse8);
  setPalEvents(&spi1,clockPulse1); // ODD order here is because I was debugging which lines are not working
  setPalEvents(&spi3,clockPulse3);

The interrupts (Callbacks) are handled simply like this:

Code: Select all

void clockPulse1(void *arg) {
   (void)arg;
   clockPulse(&spi1,readLatch(spi1.latchPort,spi1.latchPin),readMosi(spi1.mosiPort,spi1.mosiPin));
}

Code: Select all

/**
 * Receive clockPulse interrupt from SCLK, stores the bits into the
 * SPI structure data
 */
void clockPulse(Spi *spi, uint8_t latchStatus, uint8_t mosiState)
{
  if (latchStatus==CS_ACTIVE){
    chSysLockFromISR();
    spi->data[spi->clockCount/8]|=mosiState<<(7-(spi->clockCount%8));
    spi->clockCount++;
    chSysUnlockFromISR();
  }
}

I gather from this http://forum.chibios.org/viewtopic.php?f=3&t=4209&start=10#p40448 that reading some PAL lines in a callback is ok. I also wrote each callback fully open, without function calls, but it didn't make difference.
I have seen several forum threads about slightly similar problems with interrupts, but none seem to match enough for me to solve this.

The setPalEvents declare order somehow change which SCLKs can trigger, and which can not. It cannot be about overlapping calls or excess load, since I am testing this with single SPI source at this time: when I change the SPI bus, 6 or 7 of them work, but 1 or 2 (usually 2) will fail. The failing buses seem almost random. Or they get masked by later declarations?

==> Since I don't think the callbacks are too bloated, and 6 callbacks sound too small a restriction for the number of setLinePalCallbacks... What am I doing wrong? The failing lines simply wont' trigger. If I read or poll them, I can detect the value changing. But no Event Callback.
Is the main stack size too small? Based on some of the other threads I tried changing USE_PROCESS_STACKSIZE, but it doesn't help. I believe the callbacks are defined in main thread context, and thus are not dependent on PORT_INT_REQUIRED_STACK (which I do not understand anyway).
I paid extra attention to the SPI storage structure, and each of them are intact in memory, so it is not that they are corrupted/overflown during the declaration.

I do have CH_DBG checks active, except trace, since I do not know how to trace it. Nothing I can detect. Also the STM32 F4 MCU should not be limited by this amount of interrupts yet.
Thanks for any possible hints.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: GPIO PAL callbacks stop working

Postby Giovanni » Wed Sep 22, 2021 6:17 pm

Hi,

I don't know if this is your case but EXTI can only listen to one pin on one port, it is not possible, for example, to listen to pin 6 on both GPIOA and GPIOB at same time, it would be possible to listen to pin 12 on GPIOA and pin 6 on GPIOB.

Please look at the EXTI documentation on the STM32 RM and make sure your configuration does not fall in this case.

Giovanni

TKorho
Posts: 18
Joined: Mon Sep 13, 2021 6:46 pm
Has thanked: 2 times
Been thanked: 1 time

Re: GPIO PAL callbacks stop working

Postby TKorho » Wed Sep 22, 2021 6:54 pm

Lightning fast again! Thank you. :shock:

This must be right on the cause. Since I did catch a CH_DBG chSysHalt() due to "Channel already in use". Contrary to my earlier inability to detect DBG problems. After a confusing situation, I GDB Pause and see the Assert. None of the PAL lines are exactly overlapping, but there is a pin number doubled. Is it per Pin number on any port? Or only per only one Pin on each port? the latter is very limited on STM32 F4, with only limited (4?) ports.

Perhaps there could be a warning about limited number of chPalLineEvents in the documentation? And perhaps even default exception throw in CH_CFG_SYSTEM_HALT_HOOK when DBG enabled. Which I will add now for myself.

Off Topic
Thank you, Giovanni. Expertise at its finest. Is there a Patreon to contribute a wine bottle(s) or something?
And yes, there will be smallish licensing query later.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: GPIO PAL callbacks stop working

Postby Giovanni » Wed Sep 22, 2021 7:07 pm

It is: you cannot use the same pin number on multiple ports thus you can have up to 16 interrupt sources but not with the same pin number.

Giovanni

TKorho
Posts: 18
Joined: Mon Sep 13, 2021 6:46 pm
Has thanked: 2 times
Been thanked: 1 time

Re: GPIO PAL callbacks stop working

Postby TKorho » Wed Sep 22, 2021 7:34 pm

Check and "Score!". Just found the same EXTI information on the Playembedded Push-Buttons document. And the HW information from the STM32 documents (EXTI_FTSR register). Thank you. ;)

EDIT: Confirmed on Nucleo hardware.


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 13 guests