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.