2010-03-01 08:12 AM
fast way to disable interrupt
2011-05-17 04:41 AM
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.2011-05-17 04:41 AM
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); }2011-05-17 04:41 AM
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 again2011-05-17 04:41 AM
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. Thanks2011-05-17 04:41 AM
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? -Clive2011-05-17 04:41 AM
[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.
Fil2011-05-17 04:41 AM
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