cancel
Showing results for 
Search instead for 
Did you mean: 

fast way to disable interrupt

bruzzim
Associate II
Posted on March 01, 2010 at 17:12

fast way to disable interrupt

7 REPLIES 7
jpeacock23
Associate II
Posted on May 17, 2011 at 13:41

You can narrow the critical section to only disable the interrupt for the serial port rather than all interrupts.  That allows you to maintain response time for more critical interrupts. 

However you might have to watch for context changes if running an RTOS.  Switching to another task while serial interrupt is disabled might cause an overrun condition.

Posted on May 17, 2011 at 13:41

The following should be thread safe (ie not require interrupts to be disabled), but neither are re-enterant.

void QueuePush(QUEUE* pQueue, u8 Data)

{

  if ((pQueue->PushCount - pQueue->PopCount) < __RX_QUEUE_SIZE__)

  {

    pQueue->pBuffer[pQueue->Top++] = Data;

    if (pQueue->Top == __RX_QUEUE_SIZE__) pQueue->Top = 0;

    pQueue->PushCount++;

  }

  else

  {

    pQueue->Overflow++;

  }

}

u8 QueuePop(QUEUE* pQueue)

{

  BYTE Data;

  if (pQueue->PushCount == pQueue->PopCount) return(0);

  Data = pQueue->pBuffer[pQueue->Bottom++];

  if (pQueue->Bottom == __RX_QUEUE_SIZE__) pQueue->Bottom = 0;

  pQueue->PopCount++;

  return(Data);

}

u32 QueueDepth(QUEUE* pQueue)

{

  return(pQueue->PushCount - pQueue->PopCount);

}

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
bruzzim
Associate II
Posted on May 17, 2011 at 13:41

I tried your code and works better than mine, now I still miss some bytes, but much less. Now I have to understand why I miss bytes. The service routines works, all bytes get in but a few are lost somewhere.

Thanks again

bruzzim
Associate II
Posted on May 17, 2011 at 13:41

I tried to selectively disable interrupts but nothing changes. I partially solved the problem with the code suggested by Clive.

I dont' have RTOS, just my app.

Thanks

Posted on May 17, 2011 at 13:41

How are you determining a loss of characters? The code doesn't handle 'zero' bytes.

Does a count of received characters match those transmitted?

Is the data being extracted at a single point?

Are any characters being lost to overrun or framing errors?

Are you writing the data into flash? This stalls the processor and result in overruns.

Does increasing the CPU speed, or decreasing the baud rate improve the situation?

Are you using flow control?

-Clive

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
bruzzim
Associate II
Posted on May 17, 2011 at 13:41

[Q]  How are you determining a loss of characters? The code doesn't handle 'zero' bytes.

[Q] Is the data being extracted at a single point?

[A] I receive a fixed length message from UART2 and send it to

USART1. USART2 push bytes interrupt mode, the pop to USART2 is into

while (program control). The flow is something like this (simplified):

// interrupt routine

void USART2_IRQHandler(void) {

  uint8_t c;

  if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {

     c = (uint8_t)USART_ReceiveData(USART2);

     QueuePush(c);

  }

}

// main.c

while(1)

{

...

      while(QueueCheck())

      {

 Data = QueuePop();

       USART_SendData(USART1, Data);

      while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

      }

...

}

[Q] Does a count of received characters match those transmitted?

[A] The missing data get in from interrupt routine but they get lost

somewhere after: if I put a counter variable counting the number of

times USART2_IRQHandleri is called, I see that all data getting in.

[Q] Are any characters being lost to overrun or framing errors?

[A] I get all data from USART RX, is there chances to miss due to TX

overrun? Since I wait for FLAG_TC reset I think it could not be the

problem. What about framing error? Signal integrity is very good.

[Q] Are you writing the data into flash? This stalls the processor and result in overruns.

[A] No just echoing USART2 to USART1

[Q] Are you using flow control?

[A] No

[Q] Does increasing the CPU speed, or decreasing the baud rate improve the situation?

[A] I'm checking these. As first shot it seems not.

Thanks very much.

Fil

Posted on May 17, 2011 at 13:41

Ok.

Actually I was thinking of Rx overruns, where you get more data before the Rx data register is read. Your code won't catch, or clear this.

Specifically the data register needs to be read when ever you get

USART_FLAG_ORE

USART_FLAG_NE

USART_FLAG_FE

USART_FLAG_PE

to clear those states.

Depending on how things are sent the USART IRQ can be called from reasons other than the register being empty.

Your code looks to make sense, so can't see why things would go missing. I would probably look at TXE rather than TC. TC means the last bit of available data has hit the wire from the shifter, the transmitter can take a new character as soon as the buffer register has moved to the shifter.

-Clive

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..