This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UART read callback issue

Hi, I have develop an interface between TIVA and a wifi chip via UART.

I have tested the communication with the chip ( directly  w/o TIVA ) and it works fine.

This is my init:

UART_Params uartParams;

/* Enable and configure the peripherals used by the uart. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);


/* Initialize the UART driver */
UART_init();

/* Create a UART with data processing off. */
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_TEXT;
uartParams.readDataMode = UART_DATA_TEXT;
uartParams.readReturnMode = UART_RETURN_NEWLINE;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.parityType = UART_PAR_NONE;
uartParams.dataLength = UART_LEN_8;
uartParams.stopBits = UART_STOP_ONE;
uartParams.baudRate = 9600;

uartParams.readMode = UART_MODE_CALLBACK;
uartParams.writeMode = UART_MODE_CALLBACK;
uartParams.readCallback = &UART_Callbk_read;
uartParams.writeCallback = &UART_Callbk_write;

uartHandle = UART_open(MODESTONE_UARTWIFI, &uartParams);

When I call UART_write...I enter in the callback UART_Callbk_write. The wifi chip answers to that command but I never enter in UART_Callbk_read.

Does anyone see something wrong in my implementation? Any suggestions to debug this issue?

Thanks!!!

  • Hi,

    Moving your post to right forum to be better answered.

    Thanks & regards,
    Sivaraj K
  • Can you share the rest of your Board.c file?

    I suspect there are multiple configurations of PORT C pin 4.

    Alan
  • Alan, you were right. I had a timer set on the same pin, now it works!!!

    Thanks a lot.

    G

  • Sorry I got to conclusion too fast.
    I have fixed the issue with PC4 (it was used also as timer) , now I enter in the callback READ but only when I use UART_read(); My understanding of the driver is that I should enter in the callback when another module send TIVA something through the UART interface, for instance as answer to my commands....
  • My understanding is that In callback mode, the read callback function is only invoked if there is an outstanding UART_read() request. The callback function is NOT called for each character received unless a UART_read() call is incomplete.
  • Thanks Alan, 

    ...but lets say..I UART_write(something) , how to I check the answer? Do I have to UART_read() after the UART_write()? I thought the callback was supposed to manage the answer event....

    If this is not the way it works, the I will change strategy in my code.

    If somebody has other comments....

  • Yes, this is the way it works. In order for your read callback to get called, you must first invoke UART_read() to inform the driver about how many characters you want to read. When that number of characters have been delivered to the callback function, no further invocations of the callback function will occur until the next UART_read() call.

    Alan

  • Thanks Alan,
    I have modified the code, I call UART_write()....then I call the UART_read()...and I enter in the read callback...so so fare ok, but if I read the buffer in the read callback...I see the same data i wrote with UART_write() and not the actual data that should come from the UART connected wifi module...any idea why that happen?
  • When you say you "read the buffer in read callback", which buffer are you reading? It should be the same buffer you passed to UART_read(). Hopefully you are not using this same buffer for your UART_write() calls. Is it possible you are using function-local buffer rather than a global buffer?

    Please share the UART configuration section of your Board.c file. Also, which version of TI-RTOS are you using?

    Alan
  • Hi Alan, I try to share some code and hopefully it will be more clear...still trying to understand what I do wrong.
    Here the code:

    // board.c
    char UART_bufferwrite[255];
    char UART_bufferread[255];

    void UART_Callbk_read (UART_Handle handle, void *buffer, int size){

    readB = buffer;


    System_printf(readB);
    System_flush();

    }

    void UART_Callbk_write (UART_Handle handle, void *buffer, int size){

    readB1 = buffer;

    System_printf(readB1);
    System_flush();
    }


    void EK_TM4C123GXL_initUART()
    {
    UART_Params uartParams;

    /* Enable and configure the peripherals used by the uart. */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
    GPIOPinConfigure(GPIO_PC4_U4RX);
    GPIOPinConfigure(GPIO_PC5_U4TX);
    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);


    /* Initialize the UART driver */
    UART_init();

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_TEXT;
    uartParams.readDataMode = UART_DATA_TEXT;
    uartParams.readReturnMode = UART_RETURN_NEWLINE;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.parityType = UART_PAR_NONE;
    uartParams.dataLength = UART_LEN_8;
    uartParams.stopBits = UART_STOP_ONE;
    uartParams.baudRate = 9600;

    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.readCallback = &UART_Callbk_read;
    uartParams.writeCallback = &UART_Callbk_write;

    uartHandle = UART_open(MODESTONE_UARTWIFI, &uartParams);

    if (uartHandle == NULL) {
    System_abort("Error opening the UART");
    }else{

    MOdestoneUART_Handle = uartHandle;

    }

    }

    // this is a different file
    void AT_Base_Test(void){

    strcpy(UART_bufferwrite,"AT");
    strcat(UART_bufferwrite,"\r\n");
    UART_write(MOdestoneUART_Handle, &UART_bufferwrite[0],4);
    }


    // this is a different file
    case UART_TEST:
    bytesRead = UART_read(MOdestoneUART_Handle, UART_bufferread,10);
    if (bytesRead != UART_ERROR){
    StatusUARTread = UART_IDLE;
    }else{
    StatusUARTread = UART_FAIL;
    }
    break;



    with this SW ....I enter in both the UART_Callbk_write and UART_Callbk_read . The System_printf shows "AT" and "AT".
    AT // write callback
    AT // read callback

    Thanks for the support.

    Ok Now it is a while I have posted new information about this issue but I do not see any comment, suggestions, follow up from anybody.

    Alan, I am sure you are very busy or in vacation or I don't know but you asked additional information and I have provided them, I need to know if you are going to follow up with this and have the time to take a look or not..if you can it would be great if you can't..then please let me know and I will try other options. I do not want to sound rude, help is always appreciated but I need to move on.

    I have played with the initialization for a while by now, changed setting , tried several things...but I still have  the basic problem...I have to call UART_read() several time before I get the expected answer. 

    Thanks for your help

    TIRTOS_2_00_01_23

    G.

  • Ok, I have found out something new:


    For debug purposes I have changed the function:
    // this is a different file
    case UART_TEST:
    bytesRead = UART_read(MOdestoneUART_Handle, UART_bufferread,10);
    if (bytesRead != UART_ERROR){
    StatusUARTread = UART_TEST;
    }else{
    StatusUARTread = UART_FAIL;
    }
    break;


    In this way I keep calling UART_read every 50ms.
    This is the result:

    AT
    AT

    T

    T

    T

    T
    OK

    K

    K


    As you see...at certain moment I read "OK" which is what I was expecting....
    I still do not understand how I should manage timing, how do I know the answer has been received...and so I can read?

    Thanks
  • Another update...changing the 50ms to 1second....the output does not change still the same:

    AT
    AT

    T

    T

    T

    T
    OK

    K

    K

    any suggestions?

  • As soon as I use in UART_read()...I enter in the read callback...before I return from UART_read()...in the read I have a copy of the write buffer...so I read that.

    I need some help to understand what is going on.

    can you take a look to the additional information I wrote ? Any idea about what I do wrong?


    Thanks

  • Sorry for the long delay. Have you made any progress during my absence?

    I'm not sure I understand the context within which the UART_read() and UART_write() APIs are being called in.
    Are these called from within a task or within main()?

    Alan
  • It would be helpful if you removed the System_printf() and System_flush() from the write callback function so that we can know for certain what characters are being returned in the read callback.
  • Hi Alan, thanks for taking the time to answer.

    I give you some additional contest.

    1. I call both UART_write() and UART_read() in a task:

    void taskFxnPWR(UArg arg0, UArg arg1)
    {

    int i;

    while(1)
    {Semaphore_pend(semaphorePWR,BIOS_WAIT_FOREVER);
    switch(Status)

    2. In this task I have a logic model with different states. I first call UART_wtite() then I change state and perform the UART_read() in the next loop. I have tried to change the semaphore timer from 50ms to 1s...but the behavior does not change(same nomber of UART_read() to get the "OK"). It is task timer invariant.

    At the beginning I was calling the UART_Read() just once, now I keep calling it in the same state in every time I process the task and I noticed that after few calls i got the correct values in the buffer.

    3. Changing the initialization (TEXT to BINARY )process I was able to get rid of the 'T' letters and I think this was due to the process of CR but I still need to call UART_read() readfew times to get the correct answer. this behavior is persistent,

    Moreover I noticed that I enter in the callbackRead before I exit from the UART_Rear() and the value read is already in the callback buffer....


    I hope this helps you to understand what is going on.

    If you need more info, let me know.

    Thanks!!!!

    Gianluca

    P.S. : this is the situation at the moment:

    UART_wtite() --> AT
    UART_read() --> AT
    UART_read()
    UART_read()
    UART_read()
    ...
    UART_read() --> OK

    Regarding your last post, I did that long time ago but in the buffers I was reading exactly the same Characters I was displaying with the printf..so that is not making differences.

  • At first glance, it appears to me that the wifi device you're communicating with echos the 'AT' commands send to it and then issues a response. In the simplest case of the 'AT' command with no arguments, the device will respond with "AT\nOK\n".

    I'd like to see the actual task loop code that you're using to invoke UART_read() as well as the read callback function.
    You say you're blocking on a semaphore with a variable timeout (50ms or 1s). Is there any thread posting the semaphore?

    From your description of the loop, it sounds like you're calling UART_read() again before the previous UART_read() job is finished. Ordinarily, you pass UART_read() the number of characters you want to receive. Then, only when that number of characters have been received and placed in the buffer passed to UART_read() will the read callback function get called. Following the read callback, it is then safe to invoke UART_read() again to collect the next buffer of characters.

    I'm not sure if the behavior is well defined if you issue another UART_read() before the read callback has been invoked.

    Alan
  • Hi Alan, 

    "At first glance, it appears to me that the wifi device you're communicating with echos the 'AT' commands send to it and then issues a response. In the simplest case of the 'AT' command with no arguments, the device will respond with "AT\nOK\n".

    I agree, that is what it seems to me as well but, my wifi module is in a separate PCB and if I send the same command to the module using a putty app, I do not have echo.

    I'd like to see the actual task loop code that you're using to invoke UART_read() as well as the read callback function.
    You say you're blocking on a semaphore with a variable timeout (50ms or 1s). Is there any thread posting the semaphore?

    Here below the code:

    char AT_Base_Test_BUFFER[]="AT\r\n";

    void taskFxnPWR(UArg arg0, UArg arg1)
    {

    int i;

    while(1)
    {Semaphore_pend(semaphorePWR,BIOS_WAIT_FOREVER);

              // here I manage the UART read from GA112415
             switch(StatusUARTread){

    case UART_IDLE:
    break;
    case UART_TEST:
    break;
    case UART_AT_BASE_TEST:
            bytesRead = UART_read(MOdestoneUART_Handle, UART_bufferread, 20);
            if(bytesRead == 0){
               StatusUARTread = UART_AT_BASE_TEST;
            }else if (bytesRead > 0){
               StatusUARTread = UART_IDLE;
            }else{
              StatusUARTread = UART_FAIL;
            }
    break;

             default:
             break;
             }


             switch(StatusPWRModel)
             {
             case PWR_STATE_PWR_OFF:

               /* make sure power switch EN is off at sturt-up*/
                StatusPWRModel = PWR_STATE_STBY;

                UART_write(MOdestoneUART_Handle, AT_Base_Test_BUFFER,sizeof(AT_Base_Test_BUFFER));
               StatusUARTread = UART_AT_BASE_TEST;

               break;

    ```````}
    }

    void clockEventTaskPwr(){ // I tried 50ms....to1000ms

    Semaphore_post(semaphorePWR);
    }

    From your description of the loop, it sounds like you're calling UART_read() again before the previous UART_read() job is finished. Ordinarily, you pass UART_read() the number of characters you want to receive. Then, only when that number of characters have been received and placed in the buffer passed to UART_read() will the read callback function get called. Following the read callback, it is then safe to invoke UART_read() again to collect the next buffer of characters.

    I don't think I am calling UART_read() before the job is finished. I have break points set just when I return from UART_read() and in the call back(read). The sequence is:

    1) I call UART_write () 

    2) In the next loop(50ms or Xms it does not matter)  I call UART_read();

    3) before I stop at the break point after UART_read() I enter in the readCallback...the value in the buffer read(which is independent from buffer write) is already "AT"(the first time). It is like UART_read()...has copied the write buffer in the read buffer and enabled the callback read event before it returns. This happen no matter what number of characters I specify on the UART_read() call...20 in the software above.

    4) I stop at the breakpoint in the line after UART_read() ;

    5) normally at this point I should have done...but for debug purpose, I go back to 2) and read again... until StatusUARTread = UART_FAIL;

    I hope I added key information and you can continue helping me as you have done so far. Thanks again.

  • Hmm. I'll have to go over these results with one of the UART driver experts.

    Are you still putting the receive path in BINARY mode when the first invocation of the read callback returns only 'AT'? I mean, you've asked for 20 bytes in your UART_read() call, and the callback is giving you only 2 bytes?

    Can you share your entire Board.c file contents? Is there any chance that something is scribbling over the UART objects?

    Is it possible that your custom UART pin configuration commands have inadvertently connected the transmitter output to two pins, one of which is also the receiver input pin?

       /* Enable and configure the peripherals used by the uart. */
       SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
       GPIOPinConfigure(GPIO_PC4_U4RX);
       GPIOPinConfigure(GPIO_PC5_U4TX);
       GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    In the meantime, are you able to upgrade to a more recent version of TI-RTOS? The one you're building with is pretty old. The UART drivers have undergone a major overhaul in the last year that may have made this issue obsolete.

    I encourage you to upgrade to the latest 2.14 release available here:

        software-dl.ti.com/.../index.html

    Alan

  • Hi Alan,
    Unfortunately I am in business trip so I don't have access to the code right now.
    I will update the RTOS and provide the board.c as soon as I get back to the office but please in the meantime try to get the opinion from the driver expert.

    Thanks

    G.
  • Which Tiva device are you working with?

    Is this a custom board or a standard launchpad?

    Alan

  • Are you still putting the receive path in BINARY mode when the first invocation of the read callback returns only 'AT'? I mean, you've asked for 20 bytes in your UART_read() call, and the callback is giving you only 2 bytes?

    > Yes that is what happens

    Is it possible that your custom UART pin configuration commands have inadvertently connected the transmitter output to two pins, one of which is also the receiver input pin?

    > no this is not possible I have checked it out.

    Had you have a chance to discuss with the UART driver expert?

    I can share the board.c....but there is really not much more than what you already saw....