1 2 Previous Next 18 Replies Latest reply on Nov 23, 2014 3:31 PM by ki.leung

    Receiving packet via UART interrupt


       I have been using state machines to date on the PIC processor to receive Asynchronous serial data. These relied on a timeout between bytes to know when packet has stopped transmission.


      With the PSOC, I am having trouble with the timers to implement this strategy and also have been advised to do less within the interrupt.


      What do you do for receiving Asynchronous data with interrupt? 


      Would you for instance:


      Change packet structure to have exclusive start and stop delimiters (adding overhead as data would need to be sent as ASCII hex).


      Start with an emppty buffer and simply poke each incoming byte into the buffer abd increment buf ptr.


      In main code, check the buffer and if first character is not start delimiter then reset start ptr to beginning.


      If start delimiter IS found then check data for end delimiter.


      If End delimiter found then found then parse data. (probably use circular buffer to kep incoming bytes happening while processing the received packet (as long as it is process before overwriting as buffer rolls over). I expect buffer shjould be greater than 2 packet lengths.


      If this is a typical method for handling data, how do you cope with data overuns and new valid data coming in after the overrun. Do you simply leave the UART to pack bytes into the circular buffer and in main code parse from Buffer TAIL until Head - looking for start byte? 


      Finally, Do you set a flag to indicate Start delimiter or do you just repeat search for start and then end every time round the main code?


      An example would be much appreciated if anyone has one.

        • 1. Re: Receiving packet via UART interrupt

          There are plenty of concepts for protocolls. Stricted is the OSI-model


          Smaller implementations are not too difficult to implement, but there is rarely a "best" solution.


          Basic concept usually is a "Circular Buffer" filled by the interrupt handler.


          For completion you need a function that tells if the buffer is empty and a function that returns the actual char of the buffer and advances to the next char.


          This ensures that you receive all characters (when the buffer is large enough)




          Lead-in characters, timeouts, fixed length messages and decoding you may use at your need and are handled during the main-loop.





          • 2. Re: Receiving packet via UART interrupt

             Thanks Bob,


            I will look at something like below 




            If circ buffer NOT full (ie. Tail_Ptr != Head_Ptr-1)


                Add data to circular buffer


                INC head ptr




                Head_Ptr = Tail_Ptr;  {circ buffer = empty)


                FRAMECOMPLETE = false


               State MAchine = IDLE




            Receive frame()  -> State machine that;


               Checks for data in circ buffer if circ buffer not empty (ie: Head Ptr != Tail_Ptr)


               Removes data to memory buffer


               INC Tail Ptr


               SET FRAMECOMPLETEt flag if whole packet received.


               Reset to IDLE state and set data ptr = 0 if main buffer = FULL or START delimiter found before frame complete


            Process frame() -> If the packet received flag set then process the packet and clear the flag

            • 3. Re: Receiving packet via UART interrupt

               I still have a bit of uncertainty using the UART. (Intterupt on single RX bytes)




              1. The examples show only UART_Getchar() used to read bytes in the interrupt with no handling for overruns or clearing the rx buffer etc.If the result of getchar is non-zero, doesd this mean data is valid and there are no errors and once read, you can continuiung gathering data? 


              2. I have followed the advice of using a circular buffer to get incoing bytes. I then pop them into a working buffer in the main loop. This all works ok. However, to parse the data, I need to look for command strings within the packet (using strstr) but can strstr handle the buffer without null terminator? ie. Do I have to add a '\0' to the last byte of my working buffer (to make into a string) every time I pass the loop and check for packet arrived?


              3. Some packet formats have the same delimiters throughout the string. Like SMS has \n\rOK\n\r or "CMT:....\n\r\n\r


              My current application will send a command to SMS and then wait for a timeout period for a response. While waiting for response, the working buffer must be being built from the circular buffer and comparison on each time around the loop for the string "OK". This may work for the short simple response but I also get unsolicited messaged (text received) and need to process the string. Would I then look for the expected string start characters "CMT" and THEN scan for \n\r characters to know where packet ends?



              • 4. Re: Receiving packet via UART interrupt

                Your question can be re-formed into "How to write a parser". This is programming technique which is far beyond what can be done in a developer forum, I think you will have to read a book about that.




                Parsers principially divide the input stream into "symbols" which can be defined in BNF. Then you "only" need a program that parses your input by the rules given by BNF. Have a look into Unix's "yacc" and "lex" program which you can get in source freely.





                • 5. Re: Receiving packet via UART interrupt



                  That brings up an interesting point. Where can I find guidelines for the forums to better understand the intended scope of them? 


                  My initial assumption was the forums consisted of a bunch of users that worked on various projects (commercial and hobby) and were asking questions of the community in the hope someone else had encountered something similar to save each having to "reinvent the wheel".


                  Do you mean my question was utside the scope of ALL forums on this site or just THIS forum? In which case, my question would be "which is the most appropriate forum".


                  some of my questions come about because I had implemented things differently in the microcontroller environment and now I am faced with a range of components that I have not yet fully become accustomed to.


                  At first, I ask a question relating to some technical hitch I encounter while attempting to port code from my previous projects across to the PSOC environment. However, when I ask the question I often receive another question that raises further issues.


                  For instance. I was having trouble getting the timers working to signal end of UART packets. When asking how to use the timers as I wanted to use them, I was asked Why not use a circular buffer, you should do the processing out of the interrupt where possible (keep it small). So, I branched off in this direction and now having trouble understanding whether I need to add a NULL terminator on every pass of the parser in order to do a strstr search. 


                  The same occurred with the PWM drive of a full bridge 125 kHz modulated signal I was attempting to write in code to ensure there was no cross conduction. Then I was asked why I did not use a PWM. It seems reasonable if someone has experience doing it this way to listen to them. However, I could not see from the PWM waveforms how I could control the 4 driver signals of my bridge. Now I am left wondering how to work that one out or going back to the original methid and not knowing why I am having troubles with the timer.


                  These seem like recursive issues to me. A question leads to a question that leads to a new method that leads to more questions as I am unfamiliar with the new method.


                  As I have routines already running on the microcontrolle rprojects, the original methods worked ok. The issue is now trying to get them running on the PSOC environment. I find overall that the community is very helpful and willing to answer questions (for this I am appreciative). But when a question is answered by another question or a generic remark like "read the manual", "do a google search" I am left a bit frustrated as I would usually done those first and the reason I am now asking is because I either could not understand the material I found or it did not appear relevant to my situation.

                  • 6. Re: Receiving packet via UART interrupt

                    I tried to do something similar for protocol DCON
                    see the project  ICP_DAS.cywrk.Archive.zip
                    at  this page:    ICP-DAS  simulators.
                    Sometimes I additionally  use the  two functions (attached below).

                    • 7. Re: Receiving packet via UART interrupt



                      during my IT education I learnt a lot of math, statistics, compiler build, 5 different programming languages, 3 assemblers and how to handle a neutron generator (no joke). This was a 3 1/2 year education but it did not end with that. So, just to say it with other words: Give it some time!


                      You will never find a forum answering all your questions but you will always find one that answers some of them. As a matter of fact, you will have to go through them and decide what it may be good for. Google is a good step to get hands on the forums.


                      Another approach (which I do prefer) is: Getting hands on a book describing the matter I am interested in. This could be the base of a good library and the foundation of good knowledge.


                      This forum, the CDC, is mostly able to help you to circumvent the difficulties a complex chip (as a PSoC is) has got. Understanding and handling of more than 100 implementations of hardware and software components is a big job and all of the contributors here are together able to manage that.


                      Basic programming techniques which can be described in less than 10 lines of pseudo-code you can lookup everywhere. There are websites for C-libraries and code for many different purposes you will just have to search for. Of course someone in this community might know an example code, so do not hesitate to ask questions.





                      • 8. Re: Receiving packet via UART interrupt

                        Here is a more extensive ap note/project on motor driving and protection -




                        www.cypress.com/    AN75813




                        Regards, Dana.

                        • 9. Re: Receiving packet via UART interrupt



                          Maybe you are correct. Given the complexity of this hardware, I may have selected the wrong platform for my projects.


                          Though I did have to contend with low level register setup for the PIC microcontroller solution, I had very little trouble getting UARTS and Bit-Bashed ports running.


                          Fortunately, I still have PCBs in stock and the development tools to work with the PIC. The real thing that interested me with the PSOC was the programmable architecture. However, I don't have anough time for a steep learning curve to figure out issues like not being able to debug with the timer interrupt running and having trouble getting timeouts running with UART reception.


                          Thanks for the "heads up". This saves me a lot more pain than I was prepared for.

                          • 10. Re: Receiving packet via UART interrupt

                            Yes, you learnt to solve some of your issues the "hard way", but I can assure you that errors in the components are rare. I experienced that the Cypress datasheets are mandantory to read while programming one of the components.


                            And when you review the solution for your timeout of the UART receiver that couldn't have been too complicated, just a hardware timer that is stopped and re-started in the rx-interrupt.


                            Working with PSoCs is quite different from working with PICs, it will take some time until you are "thinking PSoC" and finding your personal project balance between hardware and software solution.





                            • 11. Re: Receiving packet via UART interrupt

                              For people that had been working with register based and port based microcomputer, PSoC needs some time to get used to, it takes a while to have our team to get around telling people port3.4 and port2.6 can be used together as a 2 bit port. As suggested by Bob, one needs to think differently, I think the closer way is considering you have a CPU with a CPLD in the same chip

                                  For your timer issue. I use timer for timeout between bytes and timeout between packets, Not so sure what your issue is.   
                                  We suggest circular buffer because it is easy to work with, however, it doesn’t mean you need to change it especially if you already have a working solution.   
                                  For the parser issue, If you only has a few keywords, a switch or some if statement can do the job. If you already have that workout with your PIC project, there is no reason you need to change it.   
                                  One big advantage with PSoC is you can change hardware internally without having to re-design the PCB, whether it is an error of the original design or some late requirement change.   
                              • 12. Re: Receiving packet via UART interrupt

                                I also would like to see some better documentation on this.


                                The  Data Sheet for this component IS vague and difficult to understand. It gives you a single very simplistic example that would never be used in normal programming. There is also a sample project that is also too simplistic and dosent show real world usage.


                                Most other MCU manufactures provide you with a basic API to parse the data coming off their UARTS. It would be nice to see one here too.


                                I use the PSOC-4's and 5's for some products but a better understanding of the UART and parsing its data would open up many more doors.


                                Any info or book recommendations on this subject would be greatly appreciated by me and im sure by others too..

                                • 13. Re: Receiving packet via UART interrupt

                                  In the world of embedded processors the parsing of an input stream is rather unusual. Moreoften a communication link between two devices is opened and a protocol is used to communicate with each other. This can be done rather simple, because a "device" does not need to talk in many different "sentences" from which each one can be distinguished at a very early stage of transmission.


                                  I did not find any ambiguities or unprecise terms in the UART documentation, if you can highlight any, I am quite sure that Cypress is thankfully willing to correct that.





                                  • 14. Re: Receiving packet via UART interrupt

                                     I even have trouble reading a simple Digital input pin array.


                                    I dropped a Digital Input onto the workspace 


                                    Set up Number of Pins = 6


                                    Named component "DigIn"


                                    Set Contigious OFF so I could 


                                    Set to show as bus 




                                    The datasheet states that you can read the current values for all pins in the component using PinName_Read();


                                    portval = DigIn_Read();


                                    But Digin_Read() is not recognised, I get "impicit declaration of function" error, Digin does not appear in the autocomplete list.


                                    The auto complete shows DigIn_0 to DigIn_5 but these do not have read functions available either.


                                    Have I missed something real obvious in the datasheet? 

                                    1 2 Previous Next