cancel
Showing results for 
Search instead for 
Did you mean: 

Waiting for Data with Interrupt

Just Matt
Associate III
Posted on February 04, 2014 at 22:53

Gents (and maybe Ladies),

My goal is to wait until a certain amount of data has been received. I have setup an interrupt (Can Bus) and when it is triggered it stuffs the message into an Array. I'm using the following code to wait until all the data is received. However, while in the loop, the CAN interrupt does not trigger. This loop is inside input interrupt, and is after the EXTI flag has been cleared. (There is an infinite loop in the main function) What is the best way to achieve this? Thanks! -Matt

int
recCount = CanDriver::CacheCount();
while
(recCount < 100)
{
recCount = CanDriver::CacheCount();
}

CanRxMsg RxMessageArray[200];
int
ArrayCounter = 0;
int
recCounter = 0;
extern
''C''
void
CAN1_RX0_IRQHandler(
void
)
{
GPIO_WriteBit(GPIOD, GPIO_Pin_3, Bit_SET);
CanRxMsg rxMessage;
CAN_Receive(CAN1, CAN_FIFO0, &rxMessage);
CanDriver::StuffCanMsg(rxMessage);
recCounter++;
CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
GPIO_WriteBit(GPIOD, GPIO_Pin_3, Bit_RESET);
}
void
CanDriver::StuffCanMsg(CanRxMsg RxMessage)
{ 
RxMessageArray[ArrayCounter++] = RxMessage;
}
std::vector<CanRxMsg> CanDriver::ReceiveCache(
bool
empty 
/*= true*/
)
{
std::vector<CanRxMsg> returnMessages;
returnMessages.assign(RxMessageArray, RxMessageArray + ArrayCounter);
if
(empty)
{
ArrayCounter = 0;
recCounter = 0;
}
return
returnMessages;
}
int
CanDriver::CacheCount()
{
return
recCounter;
}

#nvic #nvic
4 REPLIES 4
jpeacock2399
Associate II
Posted on February 05, 2014 at 16:26

What is the priority of the EXTI and CAN interrupts?  If EXTI is a higher priority then the CAN interrupt is never handled.

  Jack Peacock
Just Matt
Associate III
Posted on February 05, 2014 at 20:34

Hi Jack,

Thanks for the reply!

The EXTI is 2, and the CAN interrupt is 0.

I cant figure this one out. As the the EXTI flag is cleared as soon as the irq is handled.

-Matt
jpeacock2399
Associate II
Posted on February 05, 2014 at 23:12

The NVIC in the Cortex M supports nested interrupts.  It has nothing to do with the the interrupt request from the peripheral.  Once you enter an interrupt handler the NVIC blocks lower priority inteerupt requests until you exit the handler.  Higher priority requests can interrupt the handler, but make sure you have enough system stack to nest handler routines.

In general it's bad programming practice to put completion routines inside the interrupt handler.  Handlers should do the minimum amout of work to clear the request and set up a completion task that runs outside the interrupt structure.  Use the EXTI handler only to set a flag that you poll in the main program.  When you see the flag then do the CAN code you now have inside the EXTI handler.  That way you are not running at an elevated NVIC priority level.

The CAN interrupts should be at a higher priority than the EXTI.  Are you sure you have the NVIC configured correctly?  It's a non-trivial task when you implement nesting.

  Jack Peacock
Just Matt
Associate III
Posted on February 05, 2014 at 23:59

Thats for the reply! Thats an awesome idea! Typically (i'm a c# guy) i've handled the complete routine in the event handler. I will try the flag thing out later tonight and report back.

Thanks again!