12 Replies Latest reply on Nov 11, 2015 12:54 PM by user_78878863

    UART Clarifications

    asaf_yaniv_1514006

      1. When I use buffer greater than 4 bytes, is your interrupt routine fires upon arrival of the first byte and move that byte to the RAM buffer thus applying byte-by-byte interrupt based transfer of bytes from the FIFO to the RAM?

         

      Or, is it waiting for 4 bytes (thus stalling my program until all 4 bytes received) and operate as a 4 bytes interrupt based transfer of bytes from the FIFO to the RAM? in that case the "Byte Received interrupt" fires every 4 bytes for a long message?

         

      2. If i want to use the On Byte Received interrupt as well, which will run first, your routine or my (please refer to both modes of using interrupts- in the interrupt C file and in the main)?  

         

      3. Please describe 5 bytes transfer delay times:
      how long do i have to wait between the time the interrupt fires and the time the first byte readable in the RAM buffer? how long do i have to wait for the next byte to be ready in the RAM buffer and so on.

         

      4. Can i create a counter which will fire an interrupt after n bytes received in the RAM buffer? (how do I wire such counter to the UART?) 

         

      5. Is there an option to create a "FIFO empty interrupt" for RX?

         

      6. Is it possible to create UART with more than 4 bytes HW buffer (so my SW routine will not be interrupted until i want to check the buffer)?

         

      7. Just to clear- all functions (both TX and RX) are going for the FIFO buffer in case of under 4 bytes buffer, and for the RAM buffer only (ignoring the existence of a FIFO buffer) for buffers over 4 bytes. please confirm.

         

      Thanks in advance,

         

      Asafya

        • 1. Re: UART Clarifications
          user_1377889

          1. The chars go into a hardware FIFO from where the internal interrupt picks them up as long as FIFO not empty putting them into a circular buffer of the given size.

             

           

             

          There are principally two different exclusive ways to handle receive, do not mix them!!!

             

          Let the internal interrupt handle everything. Polling UART_GetRxBufferSize() gives you the number of chars already in the buffer from which you can get them with UART_GetChar() from the buffer.

             

          Handle everything yourself, get interrupted at each byte received, handle errors and read from FIFO into your own circular buffer. It's a nice programming lesson when you've got the time...

             

           

             

          Interrupt handlers should be kept short, no polling, no delays. So a usual practice is

             

          1st: Remove the cause of the interrupt

             

          2nd: Set a global volatile variable to indicate what has happened.

             

          In your main-loop check that variable, act accordingly and reset it.

             

          What shall a FIFO empty interrupt be good for??? Most of the time the FIFO is empty, how will you remove that interrtupt cause????

             

           

             

          Bob

          • 2. Re: UART Clarifications
            user_78878863

            #6: since that hardware buffer is just 4 bytes, you can use the RX FIFO FULL interrupt. If you need a larger buffer, an internal ISR is used that transfer bytes from HW buffer to the software buffer.

               

            #4: AFAIK no. The PSoC4 SCB UART can create a FIFO level interrupt after n bytes, but not the PSoC5.

               

            #5: no, because its not needed. Your code that reads data from the buffer can just check whether the buffer is empty or not. No interrupt needed. ISRs are there to notify coure program that something has changed by hardware, but hardware cannot empty the RX buffer.

               

            #3: are you talking about RX or TX? On RX, the interrupt is fired when the first byte has arrived in the buffer, not before. The speed with which the buffer fills up depends on how fast data is sent to your PSoC.

               

            #7: no, with a buffer size larger than 4 the hardware UART still works solely with the HW FIFO. But there is an ISR that manages the transfer between the SW and the HW FIFO for you.

            • 3. Re: UART Clarifications
              asaf_yaniv_1514006

              Hi Bob,

                 

              a FIFO empty interrupt would give me an indication that your routine finished transferring a data packet from the FIFO to the SW buffer so i can start analyzing the data.

                 

              I am running 3 time critical (and very fast) UARTs and still wants the main to do some tasks during the small communication idle times. I wanted to avoid polling the UART_GetRxBufferSize() as it can't be done during a function (some of them are time consuming and hard to slice but can be interrupted) called from the main, and i would have to poll it for each UART after every line in the main.

                 

              i was looking for an interrupt based solution so while i'm analyzing (read, parse, analyze, respond)  UART1, i won't miss bytes coming on UART2 and UART3 . and analyze them (in the order they arrive) as soon as i finish with UART1. and continue to the main() as long as all 3 are silent.

                 

              i didn't want to mix them, i was just looking for that interrupt based solution and the "byte received interrupt" is the only interrupt available for me dealing with RX in UART.

                 

              will the circular buffer you suggested- one for each UART (did such things in the past so i forfeit the learning experience) be more or less process time-efficient than the internal interrupt routine?

                 

              and last, i will really like to hear more about how the internal interrupt works in case of a single byte in the FIFO and in case of 4 bytes in the FIFO (questions #1 and #3). thanks.

                 

              Thanks,

                 

              Asafya.

              • 4. Re: UART Clarifications
                asaf_yaniv_1514006

                Hi hli,

                   

                thanks for your response.

                   

                #6 is the RX FIFO FULL interrupt fires as soon as the 4th byte arrives? (so i have enough time to empty it before the 5th byte arrives)

                   

                #4 merd.

                   

                #5 when i do it from the main it is not responsive enough in my application while the byte received interrupt doesn't work well as it is too soon. that was the motivation behind question #4

                   

                #3 Sorry, RX. i was trying to understand the time frame (#3) and how is the internal interrupt mechanism is working (#1).
                how is it linked to my data rate? (or- please look at question #1)
                if there is only one byte. how much time will take the internal interrupt once fired to move it from the FIFO to SW buffer? is it 0.333 usec? will it stay there untill 4 bytes arrive? (again- question #1)
                knowing the time frame it takes for the internal interrupt to move byte(s) from HW FIFO to SW Buffer will help me designing my routine.

                   

                #7 Sorry, i wasn't clear, by "functions" i meant API functions. for example, when i execute UART_GetRxBufferSize() :
                for 4 bytes and under buffer it will show me the amount of bytes waiting in the FIFO HW Buffer
                for 5 bytes or more it will show me the amount of bytes waiting in the SW buffer (ignoring the existence of a FIFO buffer).
                please confirm.

                • 5. Re: UART Clarifications
                  asaf_yaniv_1514006

                  couple more questions for UART clarifications:

                     

                  8. Silly question, and yet to be sure- is the internal interrupt, in case of buffer bigger than 4 bytes, obey the priority I set for it in the interrupt priority tab (and not override me with the highest priority)?

                     

                  9. if I connected an external interrupt: RX_ISR to that UART (buffer is bigger than 4 bytes) it will always fire on byte received (please confirm), will it obey its priority (being different than the internal interrupt) so the following sequence can occur:
                  the internal interrupt will fire (priority 1),
                  another (unrelated) time consuming interrupt will fire (priority 2),
                  the internal interrupt will fire again (priority 1) (new byte recieved), 
                  and only than the RX_ISR interrupt (priority 3) fires.
                  please confirm. 
                  it will also answer question #2 above.

                  • 6. Re: UART Clarifications
                    user_1377889

                    Yes, some questions are silly ;-) Of course will the interrupt priority follow your assignments and not be changed.

                       

                    A simple test (Just setting the UART buffer to 5) shows that you cannot have both interrupts. Rx character received interrupt is no longer a choice.

                       

                    As I already told, all bytes from FIFO will be transferred to the buffer, so what you want to know when you ask "internal interrupt works in case of a single byte in the FIFO and in case of 4 bytes in the FIFO". The internal handling of the UART component does not differ from a self-written circular buffer algorithm (except that is is error-free).

                       

                    What is the baud rate of your UART channels?

                       

                     

                       

                    Bob

                    • 7. Re: UART Clarifications
                      asaf_yaniv_1514006

                      Hi Bob.

                         

                      thanks for your explanations. i have actually 5 UARTs 1Mbps each. and they can all transmit data to me simultaneously. am I asking too much of the PSoC 5?

                         

                      I tried the simple test you suggested, and I saw differently. i can have both interrupts.
                      I can't uncheck the dimmed "on byte received" interrupt but it is checked and i have interrupt terminal to which i can connect my external interrupt and have two interrupts visible under the interrupt tab (internal... and RX_isr), i even checked RX_isr during runtime and it fired.

                         

                      as such, let me ask you again if you can confirm or deny the possible sequence described in question #9

                         

                      As for question #4- can I connect the external RX_isr to the reset port of a counter to generate a delayed interrupt (better than polling buffer size in the main for me)?

                         

                      just to clear the internal mechanism- in a world with only one interrupt, it should function as a byte-by-byte (meaning every byte will fire the internal interrupt and it will move it to the SW buffer)
                      in case of several interrupts, the internal interrupt may be delayed and so the amount of bytes in the buffer when it fires will be moved to the SW buffer (Q#3: how much micro seconds it takes to move 4 bytes from the FIFO to the SW buffer?) and the interrupt will be cleared. the next byte will trigger the internal interrupt once more. please confirm.

                         

                      Thanks again for your time,

                         

                      Asafya

                      • 8. Re: UART Clarifications
                        user_342122993
                                Asafya, By now you likely have all information needed, it is time to test the code. 5x1Mbs is tight. Attached is another incarnation of a project for reading UART into circular buffer, based on Bob Marlowe's explanation above. Use it for testing, first one UART, then two simultaneously... Good luck!   
                        • 9. Re: UART Clarifications
                          user_1377889

                          5Mbaud divided by 12 (8 + start and stop-bits) will result in about 450k interrupts per second. That is more than tough! I really question if that could be performed. you will have to make a test. Use "Release" setting for optimization.

                             

                           

                             

                          Bob

                          • 10. Re: UART Clarifications
                            asaf_yaniv_1514006
                                    Thanks everyone for your help.   
                            • 11. Re: UART Clarifications
                              user_78878863

                              Its not only that you get 450kbytes per second (which means about 100k interrupts per second if you use the FIFO FULL). But you also need to process this data somehow...

                                 

                              I would try to use DMA to get the data into larger memory areas where processing might be faster and easier.

                              • 12. Re: UART Clarifications
                                asaf_yaniv_1514006
                                        Thanks. I did try to use DMA. Still learning how to do that. Although it is possible to get data from all UARTs simultaneously, I have a reasonable assumption that most of the time I will have no more than two which should allow me the processing time and I tried to keep it efficient (lookup table). Thanks again for your help.