I see, that is good to know.
Everything works if the DMA ISR does not send any event but breaks otherwise. The event listener has a stack size of 1024, all other threads (not doing much, really) mostly 256 or 1024.
DMA complete ISR -> mailbox post -> SV#8 Topic is solved
Moderators: RoccoMarco, barthess
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: DMA complete ISR -> mailbox post -> SV#8
I suggest to selectively disable parts of your application until you find the one that triggers the problem.
Giovanni
Giovanni
Re: DMA complete ISR -> mailbox post -> SV#8
Switching off all other threads does not even help! Interesting.
Only tcp_sender is active, which receives the event.
Now, the stack trace is very short. After only 14 steps, it stops. I am bothered by VectorB0, is that an exception?
Only tcp_sender is active, which receives the event.
Now, the stack trace is very short. After only 14 steps, it stops. I am bothered by VectorB0, is that an exception?
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: DMA complete ISR -> mailbox post -> SV#8
Vector B0 is associated to an USART if I remember well, the list in on the STM32 Reference Manual.
Giovanni
Giovanni
Re: DMA complete ISR -> mailbox post -> SV#8
Ok, thank you. I will have a look.
I have another question, though. I give the DMA a callback function to call on transfer complete. Do I have to treat it just like an ISR?
More specifically, do I need to put
CH_IRQ_PROLOGUE()
and
CH_IRQ_EPILOGUE()
inside the handler? I suppose that this is not an actual ISR but a callback called from the DMA ISR.
Thanks,
Adrian
I have another question, though. I give the DMA a callback function to call on transfer complete. Do I have to treat it just like an ISR?
More specifically, do I need to put
CH_IRQ_PROLOGUE()
and
CH_IRQ_EPILOGUE()
inside the handler? I suppose that this is not an actual ISR but a callback called from the DMA ISR.
Thanks,
Adrian
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: DMA complete ISR -> mailbox post -> SV#8 Topic is solved
Hi,
Callbacks must not use macros, just plain functions, macros must be placed only in ISR top level function.
Giovanni
Callbacks must not use macros, just plain functions, macros must be placed only in ISR top level function.
Giovanni
Re: DMA complete ISR -> mailbox post -> SV#8
Thanks, that seems to be it! It does not run into the exception handler anymore. Events work fine now, too.
One last question: The dmaStreamAllocate expects an IRQ priority MASK. However, there are no macros for DMA priority masks. I just give it the number "3". Is that ok? What range of numbers is allowed? I know that 0 and 1 shall not be used.
Thanks again,
Adrian
Here is the complete code for configuring input capture with DMA. I use this for capturing a parallel 16 bit external ADC input. The input capture unit triggers on the ADC sampling clock and requests the DMA to collect the input data from a chosen port (16 bit parallel input in my case).
First, the ICU configuration structure:
It also enables the request for the DMA in the timer. I use timer 1 channel 2 for DMA 2 stream 2.
The following goes in my main() function and starts the ICU and DMA. It also contains the DMA config.
I use a circular DMA with two memory buffers between which the DMA switches each time. They are called mem0 and mem1.
ADC_SAMPLES is #define(d) to 1024 in my case
This is the DMA transfer complete handler that is called on DMA complete interrupt:
It also sends some events to other parts of my application. Be sure to initialize the event source first if you want to use something similar.
One last question: The dmaStreamAllocate expects an IRQ priority MASK. However, there are no macros for DMA priority masks. I just give it the number "3". Is that ok? What range of numbers is allowed? I know that 0 and 1 shall not be used.
Thanks again,
Adrian
Here is the complete code for configuring input capture with DMA. I use this for capturing a parallel 16 bit external ADC input. The input capture unit triggers on the ADC sampling clock and requests the DMA to collect the input data from a chosen port (16 bit parallel input in my case).
First, the ICU configuration structure:
It also enables the request for the DMA in the timer. I use timer 1 channel 2 for DMA 2 stream 2.
Code: Select all
/**
* Configuration structure for the input capture unit (ICU)
*/
ICUConfig icucfg = {
ICU_INPUT_ACTIVE_HIGH,
40000000, /** 40 MHz ICU clock frequency. */
NULL,
NULL,
NULL,
ICU_CHANNEL_2,
/** DIER Register for enabling CH2 request on DMA */
STM32_TIM_DIER_UDE | TIM_DIER_CC2DE
};
The following goes in my main() function and starts the ICU and DMA. It also contains the DMA config.
I use a circular DMA with two memory buffers between which the DMA switches each time. They are called mem0 and mem1.
ADC_SAMPLES is #define(d) to 1024 in my case
Code: Select all
/*****************************************************************************
* Configure ICU and DMA for ADC capturing
*/
/**
* Start ICU (input capture unit) for DMA request generation
*
* The ADC clock signal is sampled by this ICU.
*/
icuStart(&ICUD1, &icucfg);
icuStartCapture(&ICUD1);
/**
* Allocate stream, dma_complete_handler is called in case of a complete
* DMA transaction
*/
dmaStreamAllocate(STM32_DMA2_STREAM2,
3,
(stm32_dmaisr_t)dma_complete_handler,
(void *)STM32_DMA2_STREAM2);
/**
* Set the DMA source address, GPIO port J
*/
dmaStreamSetPeripheral(STM32_DMA2_STREAM2, &GPIOJ->IDR);
/**
* Set the DMA destination addresses. This can be configured as a double
* buffer DMA, so two buffers are specified
*/
dmaStreamSetMemory0( STM32_DMA2_STREAM2, mem0);
dmaStreamSetMemory1( STM32_DMA2_STREAM2, mem1);
/**
* Size of one complete DMA transaction in samples of 16 bit
*/
dmaStreamSetTransactionSize( STM32_DMA2_STREAM2, ADC_SAMPLES );
/**
* DMA configuration:
* - Priority 0 (Very high 3..0 Low)
* - Half word transfer size (16 bit)
* - Circular DMA mode
* - Direction: Peripheral to memory
* - Increase memory pointer automatically
* - Enable DMA transfer complete interrupt
* - Select channel 6 (DMA 2, Stream 2, Tim1Ch2)
* - Dual buffer mode, switches between two memories
*/
dmaStreamSetMode( STM32_DMA2_STREAM2,
STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD |
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_P2M |
STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC |
STM32_DMA_CR_CHSEL(6) | STM32_DMA_CR_TCIE |
STM32_DMA_CR_DBM );
/**
* enable the stream
*/
dmaStreamEnable(STM32_DMA2_STREAM2);
/**
* End configure DMA
****************************************************************************/
This is the DMA transfer complete handler that is called on DMA complete interrupt:
It also sends some events to other parts of my application. Be sure to initialize the event source first if you want to use something similar.
Code: Select all
/**
* Process DMA complete interrupt
*
* Detects, which memory was last filled with data. Starts processing and
* transmission to host PC.
*
*/
void dma_complete_handler(stm32_dma_stream_t * dmastp, uint32_t flags)
{
(void) flags;
/**
* Current buffer is Memory 0
*/
if((dmastp->stream->CR & DMA_SxCR_CT) == 0)
{
chSysLockFromISR();
chEvtBroadcastFlagsI(&dma_event_source, DMA_MEM0_READY);
chSysUnlockFromISR();
}
/**
* Current buffer is Memory 1
*/
else
{
chSysLockFromISR();
chEvtBroadcastFlagsI(&dma_event_source, DMA_MEM1_READY);
chSysUnlockFromISR();
}
dmaStreamClearInterrupt(dmastp);
}
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: DMA complete ISR -> mailbox post -> SV#8
Hi,
That "mask" is a documentation leftover from an old version, valid values are 2..15.
Giovanni
That "mask" is a documentation leftover from an old version, valid values are 2..15.
Giovanni
Who is online
Users browsing this forum: No registered users and 20 guests