# Serial Communication Rx ISR logic design

If im not wrong, an ISR is supposed to do minimal processing when it receives a data serially(via UART). Im planning on implementing such a protocol for communication between 2 systems via uart. This is a rough situation of how i plan on coding the ISR. Assume 2 system A & B where A is sending a message to B: Keyword is used to indicate start of message(Established-data/length cannot be the keyword). ChannelOK,Length of data,RxLength,RxData,Packet received flag in B's process are default 0.Length of data=no. of(all data)in bytes(ex:if all data=1,Length of data=1)

A's Process
Send Keyword
Send Length of data
Send all data

B's Process
Rx Interrupt
enter ISR
ISR: if(Received Byte == Keyword && !ChannelOK)
{
Set ChannelOK
}

if(ChannelOK && RxLength)
{
Set Length of data=received byte
ChannelOK=0
RxLength=0
}

if(Length of data != 0 && RxData)
{
Store Data
--Length of data
if(Length of data==0)
{
Set Packet received flag
RxData=0
}
}

if(ChannelOK)
{
Set RxLength
}

if(Length of data)
{
Set RxData
}
Reset to Interrupt Again


My doubt is: B has so many stuff to do in the ISR while A is sending continuously. Asumming A sends data at 7.5Mbps(11 bits per transfer), the ISR has to reset the interrupt ever (11/7.5M) seconds. This seems very very small. Will data be lost if i fail to reset the interrupt on time or will it be stored in the 16 byte FIFO so that an interrupt can be immediately triggered the second i reset the interrupt or must i slow down A Tx process by waiting for an ACK for each byte(slows down a lot)???

Im a newbie to ISR's.Please do help Any ISR designs or protocols for serial data communication would be useful

Thanks

• I can't make sense of the second half of your first paragraph. Commented Feb 12, 2016 at 11:47
• Keyword will be the a hex value like 0x5A. When the ISR sees this value only it will attempt to store the data following this. Example: 1st byte- 0x5A,2nd byte-3,3rd byte-0x12(cmd),4th byte-some status,5th byte-msg checksum. 0x5a can never be a data or length. It can only indicate the start of a message. Once a complete message is received it has to check for 0x5a to receive again Commented Feb 12, 2016 at 11:54
• You have 82.5 us for each byte... how long does the your main loop (assuming worst case) take to process everything?. if it 80 us or less then there should not be a problem. This is easy in assembler to estimate.. with higher languages you may have to look at simulating or (gasp!) instrumenting your code and actually measure the loop time (making sure your taking the longest paths through the code). Commented Feb 12, 2016 at 12:33
• How 82.5us? Thats the problem, I dont want to get down to the bare level of how long each instruction takes(though possible). I want to keep ISR as simple as possible so that the time saved in keeping ISR simple could be concentrated elsewhere Commented Feb 12, 2016 at 12:40

## 2 Answers

I will propose a method that you may find helpful with some modification to suit your needs.

In this method the ISR is so small , it only saves data in an array for later decoding in the main program , two counters are used to detect of received data and decoded data. offcourse you can use pointer instead of the counters.

   ISR:
{
Receivedbytes[i++]= Rxbuffer;
dataReceived++;
}

main:

void UARTdecode{

if (dataDecoded<dataRecived)
{
Received byte = Receivedbytes[j++];
///// where routine
if(Received Byte == Keyword && !ChannelOK)
{
Set ChannelOK
}
..
..
..
//// end of routine

dataDecoded+=x; (where x is the amount of data decoded or message length)
}

}


P.S:It is VERY IMPORTANT that i and j are declared as Static variables

You can also check arduino hardware serial library source code , it is open source and it uses ISR to receive data "HardwareSerial.h" in the installation directory

• So your saying i just copy the data in ISR to a buffer and do the entire processing written in my ISR in the main()? Commented Feb 12, 2016 at 12:17
• Finally I just check if dataDecoded = Length of data+2 Commented Feb 12, 2016 at 12:32
• yes ! if this is the answer you are looking for , but i still recommand that you take a look at arduino hardware serial library. and please note that the counters i mensioned are important because you have to know which characters in the array you have read and which you havenot . experiment with this and if you still have doubts , post them. Commented Feb 12, 2016 at 12:33
• Yes i agree that the counter values need to be static.Thanks :) il have a look at the library. Il Post here if any doubts Commented Feb 12, 2016 at 12:43
• This looks like a ring buffer implementation Commented Apr 12, 2016 at 6:17
B has so many stuff to do in the ISR

No, at least not if you architect the system right. I would keep any decoding logic out of the ISR. Usually my UART interrupt handler grabs the byte from the hardware, clears the interrupt condition, and stuffs the byte into a FIFO. The foreground code can take it from there. Make the FIFO large enough so that the foreground code can run in bursts and the FIFO doesn't overflow between bursts.

If there's just too much to do per byte, then you have a fundamental problem that firmware can't fix. You need a faster processor or slower communication.

• So your saying that i just copy the received data in the ISR to a global buffer{[RxBuffer[Loc++]} and reset the interrupt. In the main() I go & check if the value in RxBuffer[0] is the Keyword. If its the keyword,process RxBuffer[1]--RxBuffer[FinalLoc].If not,Clear the RxBuffer. But how do you know when the complete packet has arrived? By using something like a stack check algorithm where i initialize all loc of the RxBuffer to a defined const value(like keyword but diff value like 0xa5). If the value at RxBuffer[Length+1] != const value, message received. Else complete message not yet Rxd. Commented Feb 12, 2016 at 12:08