The attached project (UARTTest) has confounded me for days and I’m hoping that someone in the community can put fresh eyes on it and help me see the (probably obvious) error in my ways. Although part of a much larger project, I’ve isolated the troublesome bits in a simple-as-possible demonstration project.
I have a PSOC 5LP host that communicates via a single UART to a touchscreen display. The host sends commands to the display that the display confirms with one of 4 possible responses:
- “>” indicates SUCCESS.
- “!” indicates a SYNTAX ERROR
- “#” indicates a CRC ERROR
- ":" indicate human readable information (for debug).
For this test/demonstration I only want to SEND commands from the host, and wait for a SUCCESS response (indicated by the “>” prompt) before doing anything else.
When commands are RECEIVED asynchronously from the display as will be the case with user input, the host will dispatch each command to a unique handler that will respond by sending an instruction response (another command string) to the display, and again wait for the SUCCESS prompt before doing anything else.
For testing, I use a terminal emulator (RealTerm) to emulate the display. I have attached a screenshot of a complete session to illustrate how it works— and the problem.
The simple project attached initializes a UART then:
- The host SENDS a single command string to the display and waits for a SUCCESS response.
- I (as the display) send the SUCCESS response (“>” without quotes, followed by a CR).
- The host SENDS a second command string to the display and waits for a SUCCESS response.
- I send the SUCCESS response.
- The host SENDS a third command to the display and waits for a SUCCESS response.
- I send the SUCCESS response.
Up to this point, all works well and as intended. The host has no problem sending the commands strings out via the UART, and will wait indefinitely for the SUCCESS response before doing anything else. However, if I then send a command TO THE HOST from the display, things don’t work so well. Continuing…
- I send a command— “c1” (without quotes, followed by a CR).
- The ISR is triggered and the host sends an INCOMPLETE command string in response.
What I expect to be returned is “Response to Command 1\r”. Instead, all I get is the first 5 characters (“Respo”) and nothing else.
After that happens, the program appears to be dead. Nothing else happens. The host will not respond to any other prompts or commands. Pausing code execution with the debugger, I find program apparently stuck in the while() loop that waits for the SUCCESS response. This indicates that it is waiting for a success response for the command it didn’t finish sending.
OBSERVATIONS & QUESTIONS:
1) The documentation and code comments for the UART API function UART_1_PutString() (used in my function SendTXCommandWait() to send the command strings to the display) all say that UART_1_PutString() is a blocking function and will not return until the last character is sent. However, the code seems to continue executing and enters the while loop before the entire string is sent.
2) Because the program is then waiting for the SUCCESS response, it is acting as though the entire command has been sent, although it has not. Because it has not, no success response will ever come from the display.
3) I’ve suspected some interrupt might be interrupting the sending of the command, but the only interrupt I’ve implemented is the ISR for the UART RX. That doesn’t call SendTXCommandWait() until a complete and properly terminated command string has been received from the display, and no other RX occurs until after that command would be successfully sent and received by the display, so I don’t see how it can’t be the RX interrupt and I can’t figure out what else might be disrupting the sending.
If experience is a guide, the problem is ME. I’m a little afraid to even submit this because I don’t look forward to learning what amateurish error I’m committing. And yet, I’ve spent days (and long nights) trying to figure this out with no joy. I’d be grateful for any feedback and suggestions for what might be causing this behavior-- especially if it means (and I imagine it does) that I'm about to learn a really valuable lesson.
A FEW ADDITIONAL NOTES:
- I will add retries, timeouts, etc. and have, but removed them all the have a simpler example for troubleshooting.
- I use sprintf() to prepare commands sent from the host because although this example is much simpler, in the real application most of them are dynamically created and it allows me to parameterize and format them easily as they are constructed.
- UART is configured as 115200 baud, 8N1.
- All commands whether sent by the PSOC host or the display must be terminated with a Carriage Return (0x0D).