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 PSP Driver: Read buffer length in timeout case ?

Hello, I'm trying to use UART with BIOS PSP Driver (v.  1.10.03) on chip C6424 .

 

To read from an UART input channel (with handle: hUart_in) I'm using the GIO function:

status = GIO_submit(hUart_in,IOM_READ,&buf,&len,NULL);

Where:

buf: is a struct that defines a pointer to the input buffer and a NON-INFINITE timeout;

len: represent the number (maximum) of bytes I want to read (i.e. size of input buffer)

 

My question is:

is there a way to have back from the GIO_submit() function (or other functions..) the number of bytes correctly received and putted into input buffer in the case of a timeout has occurred ? (so not all the requested "len" bytes has been received yet..)

 

Thanks

  • Andrea,

    I think what you are looking for can actually be found in the device object (in your case hUart_in). hUart_in->stats.rxBytes should keep track of the number of bytes received by the UART; however it looks like the driver simply adds the number of actual bytes received to a running total rather than replace it every time. I am not a driver expert so I am not sure if there is another (easier) place to look, but you may want to try comparing this value before and after a timeout occurs to see how much this value has changed. In most cases the difference should equal the length passed to the GIO_submit, but in the case of a timeout or some other error the difference may be less than the length.

  • After more analyzing my previous post is incorrect. I think the driver will need a slight tweak inside the dda_uartBiosIomLocal.c file. After the uart_io() function calls into _DDC_uartSubmitIoReq() the function should return with iop_ddc.xferActual equal to the number of actual bytes transfered. I think if you changed the driver code to look like the below that your application could access the hUart_in.syncPacket.arg variable to see the number of bytes actually transferred.

    // Inside uart_io()
            /* Submit IOP to DDC */
            status = _DDC_uartSubmitIoReq(&port->dda_PortObj.device.ddcObj,iop_ddc);
     
            /* Status returned by the DDC */
            if (PAL_SINPROGRESS == status)
            {
                if (port->uartParams.syncMode == (Bool)TRUE )
                {
                    /* Takes care of the time-out condition specified depending
                     * on the raed and write condition                      */
                    if ( (Uint32)iop_ddc->cmd == DDC_UART_IOCMD_WRITE )
                    {
                        status =  SEM_pend(port->dda_PortObj.device.hTxSemSync, iop_ddc->timeout);
                    }
                    else
                    {
                         status =  SEM_pend(port->dda_PortObj.device.hRxSemSync, iop_ddc->timeout);
                    }

                    packet->arg = ipo_ddc->xferActual; // I THINK this will store the byte count into the application-accessible packet 
     
                    if(TRUE != status)
                    {
                        /* Cancel IOP for any failure including Timeout error
                         * which is most expected */
                        PAL_osProtectEntry(PAL_OSPROTECT_INTERRUPT, &cookie);
                        status =_DDC_uartCancelIo(&port->dda_PortObj.device.ddcObj, iop_ddc);
                        PAL_osProtectExit(PAL_OSPROTECT_INTERRUPT, cookie);
     
                        /* Change the status to timeout */
                        status = IOM_ETIMEOUT;
                    }
                    else
                    {
                        status  = IOM_COMPLETED;
                    }
                }
            }

  • Thanks Tim for your answer,

    I think that your solution can be correctly applied to PSP driver version 0.6 (your code seems to come from that version).
    Since I'm working to PSP driver 1.10.03, I used your suggestions to found for that version a solution designed specifically for my needs.
    I made the following changes:

    -----------------------------------------------------------------------
    [new function implemented inside ddc_uart.c]

    Int32 PSP_uart_getActualSize(PSP_Handle handle)
    {
        DDC_uartIoHandle      ioHandle  = NULL;
        Int32                  actualSize = 0;

        ioHandle   = (DDC_uartIoHandle)handle;
        actualSize = ioHandle->activeIOP->xferRequest - ioHandle->bytesRemaining;

        return(actualSize);

    -----------------------------------------------------------------------
    [inside function uart_mdSubmitChan(), file dda_uartBios.c]

    // ...

    if (IOM_COMPLETED != IOMstatus)
    {
    chan->isSyncMode  = FALSE;
    /* Either IOP timedout or error occurred and the notifycallback released the semaphore so cancel the IOP */
    PAL_osProtectEntry(PAL_OSPROTECT_INTERRUPT, &cookie);

    packet->arg = PSP_uart_getActualSize(chan->ioHandle);  //NEW LINE ADDED !!!

    /* Cancel the current IO */
    result = PSP_uartIoctl(chan->ioHandle,PSP_UART_IOCTL_CANCEL_CURRENT_IO,NULL,NULL);

    // ...

    -----------------------------------------------------------------------
    [inside application]

    // ...

    status = GIO_submit(hUart_IN,IOM_READ,&buf,&len,NULL);
    //if status == IOM_ETIMEOUT, Actual size can now be obtained in that way:
    ActualSize = hUart_IN->syncPacket.arg;

    // ...

  • Hi Andrea,

    Sorry for using an archaic version of the PSP. It is the only one I had installed! Did adding the line I mentioned function properly? This could be something we suggest to the PSP folks if it worked out properly.