Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
DeHo_722036
Level 1
Level 1
First like received First like given

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.

SCENARIO:

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).

OBJECTIVE:

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.

DEMONSTRATION:

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).

Thank you!

Denver

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Since there has not been any correct answer,

I tried to study your code this morning.

The first thing I noticed was having DispatchCommand(RxStr)  in an ISR is troublesome,

so I only let set the flag "dispatch_command_flag" and let the main loop call DispatchCommand(RxStr) ;

Meantime, when I debugged your program,

the program was spending most of the time in SendTXCommandWiat(),

so I modified the function as follows

==================

void SendTXCommandWait( void )

{

    // Send prepared command (in cmdStr)

    UART_1_PutString( cmdStr );

    CyDelay(10) ; /* by moto */

    txCmdStatus = TX_COMMAND_STATUS_PENDING_RESPONSE;

   

    while ( txCmdStatus != TX_COMMAND_STATUS_RTS )

    {   

        switch(txCmdStatus) {

        case TX_COMMAND_STATUS_SUCCESS:

            txCmdStatus = TX_COMMAND_STATUS_RTS;

            break ;

        case TX_COMMAND_STATUS_PENDING_RESPONSE:

            cursor() ;

            // UART_1_PutString("Pending Response\n\r") ;

            // CyDelay(10) ;

            break ;

        case TX_COMMAND_STATUS_CRC_FAILED:

            UART_1_PutString("CRC Failed\n\r") ;

            CyDelay(10) ;

            break ;

        case TX_COMMAND_STATUS_SYNTAX_ERROR:

            UART_1_PutString("Syntax Error\n\r") ;

            CyDelay(10) ;

            break ;

        case TX_COMMAND_STATUS_RTS:

            UART_1_PutString("Status RTS received\n\r") ;

            break ;

        case TX_COMMAND_STATUS_RETRY:

            UART_1_PutString("Status Entry\n\r") ;

            break ;

        default:

            break ;

        }

    }

==================

Since TX_COMMAND_STATUS_PENDING_RESPONSE was most commonly stepped,

I introduced a cursor function, which will stay same place and show animated cursor to

let the user know that the program is waiting for you.

================

char pattern[] = { '|', '\\', '-', '/', '|', '\\', '-', '/' } ;

void cursor(void)

{

    static int phase = 0 ;

    UART_1_PutChar(0x08) ;

    UART_1_PutChar(pattern[phase]) ;

    CyDelay(100) ;

    phase = (phase + 1) % 9 ;

}

================

The result Tera Term log was

000-TeraTerm-log.JPG

I hope this can be a little hint for you šŸ˜‰

moto

View solution in original post

6 Replies