7 Replies Latest reply on Aug 26, 2014 7:41 AM by JoMe_264151

    UART packet timeout


       A short time ago I posted a question relating to setting up a time to determine when a packet has completed transmission.


      I would like to use a small state machine that resets the timer each time a byte is received and sets a flag when packet is complete. The pseudo code is what I think should work but I needed to know if it is ok to stop the UART interrupt inside a timer interrupt and whether resetting the timer period is ok inside an interrupt. I have not shown the init routines or exact syntax but kept it simple to show the concept. I am also not sure if I have to do some sort of read in timer isr to keep timer running.


      CY_ISR(TimerInterrupt)  //this routine fires when no bytes received for more than 20ms
          if(Mode == RECEIVING)  //only set flag if data reception has begin, else ignore timeout
            DatainBuf = true;  
            UART_Stop();  //stop UART to prevent state changing after timeout


          if(Mode == IDLE)  //reset stae machine, add incoing data to buffer and reset timer
             DatainBuf = false;
             Mode = RECEIVING;
             Ptr = 0
          ComBuf[Ptr] = UART_Read();

      ResetCom()  // call this before when ready to receive data
        Mode = IDLE;


      if(DatainBuf) ProcessCom();  /

















        • 1. Re: UART packet timeout

          There are some side-effects you should take into account:


          Declare your variables that are changed in the handlers as "volatile"


          There could fire an interrupt during execution of a handler. Depending on the given priority the behaving could be different. Better encapsulate with CyEnterCriticalSection() and CyExitCriticalSection():.


          Do not forget to remove the interrupt cause before exiting a handler even if the interrupt is not wanted!


          A Timer_WritePeriod() will not start the timer. The period should be fixed (Design or initialization).


          A different approach would be to use a count of the incoming characters. At timer TC look for != 0 and reset count.





          • 2. Re: UART packet timeout

            Why not use the tx_en output of the UART block as the input to a counter/capture component?

            • 3. Re: UART packet timeout

              We are talking about receiving bytes, not about sending. So the tx_en will not work here.





              • 4. Re: UART packet timeout

                You can consider using the RX_int or the RX_CLK to reset the timer, just make sure the timing/reset pulse width meets the spec.

                • 5. Re: UART packet timeout

                  My mistake. I misread the original question.




                  I can't think of an easy way to do this automatically since the hardware would have to understand what the end of packet looked like in order to trigger the capture. I think your software solution is the most straightforward way to do it, but as Bob said, mind your variables (and declare any global variable that an interrupt handler can change as "volatile") and you should have a working solution.

                  • 6. Re: UART packet timeout

                     Yes, I use Volatile variables that get modified in interrupts.


                    The Timer gets started with Timer_Start(), I am wanting to refresh the timer each time a UART byte is received (start the count again) to prevent it timeoing out unless no more characters are arriving. I have done this for quie some time using Mircochip controllers and found it worked well but not yet familiar with the PSOC timers to implement it straight off.


                    It would be great if the UART function had a timeout function you could set for no activity.


                    I could use an XON/XOFF type arrangement but the system is receiving data that does not have these dleimiters to mark the start and end of packet. 

                    • 7. Re: UART packet timeout

                      Providing the UART with a timeout will take a timer component and the needed underlying hardware, which is not wanted in all designs. You may of courde create a macro that contains all your needed components and use it in designs where that configuration is appropieat.


                      Restarting a timer in software best runs as a Timer_Stop(); Timer_Start();