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 GIO_submit Took All DSP Processing Time



Hi,

I am working with the EVMC6747 starter kit, CCS v3.3, DSP BIOS 5.33.05 and PSP 1.20.0.  My application has 7 tasks and they are all running well.  The application is currently use simple UART driver that write and read straight from UART control register with FIFO enable.  I was able to transmit data to the UART and captured from the PC at 115200 consistently through EVMC6747_UART_yyy functions provided by Spectrum Digital.  However, there are limitations with the FIFO for the Rx data.  I couldn’t get more than 16 bytes at a time therefore I switch to the UART EDMA.

I was told to use PSP 1.30.1 since it is newer than the version 1.20.0.  However, we already got the I2C, MSASP and AIC310 drivers working with PS 1.20.0 therefore I am not ready to the new version 1.30.1 if it is not absolutely necessary.  Please comment if version 1.30.1 made some critical fixes that I should not miss.

I was able to create GIO channels for both UART2 transmit and receive.  My problem is when I transmit the first packet of 51 bytes, the whole DSP load was consumed by the task that called GIO_submit.  No other task can execute base on my printf and the “Execution Graph”.  I looked in the documentations and there is nothing related about this matter.  I changed the GIO_submit() to asynchronous with a call back but that did not help.  Please comment on what is GIO doing with the task load.

I include my GIO_create and GIO_submit.  Please note that the UART transmission was completed.  The PC got all the data but all my tasks were hung.

// This function called by BIOS
void UartInit( void )
{
    Uart_init();
    uartParams = Uart_PARAMS;
    uartParams.hwiNumber = 9;
    uartParams.opMode = Uart_OpMode_DMAINTERRUPT;
    uartParams.rxThreshold = Uart_RxTrigLvl_1;
    uartParams.baudRate = Uart_BaudRate_115_2K;

    /* enable the uart instance in the PSC module  */
    Psc_ModuleClkCtrl(Psc_DevId_1, PSC_UART2_LPSC, TRUE);
}

// This function called by initialization
void UartCreateStreams( void )
{
    GIO_Attrs gioAttrs = GIO_ATTRS;
    Int32 echoTskStatus= 0;
    Uart_ChanParams chanParams;

    /*
     * Initialize channel attributes.
     */
    gioAttrs.nPackets = 2;

    chanParams.hEdma = hEdma;

    /* Initialize pinmux and evm related configurations */
    configureUart();

    // Initialize UART
    hUart_OUT = GIO_create("/UART0", IOM_OUTPUT, NULL, &chanParams, &gioAttrs);
    hUart_IN = GIO_create("/UART0", IOM_INPUT, &echoTskStatus, &chanParams, &gioAttrs);

    if((NULL == hUart_IN)||(NULL == hUart_OUT))
    {
        (void)printf("ERROR: Initialization of UART failed\n");
        return;
    }
}

// This function transmit UART data
void UartSend( uint8_t *data_, uint16_t dataLength_ )
{
    Int status =  0;

    memcpy( UartTxBuffer, data_, dataLength_ );

    TxCallbackFunction.fxn = (GIO_TappCallback)UartTxCallBack;
    TxCallbackFunction.arg = NULL;
    status = GIO_submit(hUart_OUT, IOM_WRITE, UartTxBuffer, (size_t *)&dataLength_, &TxCallbackFunction);
    if(!((status == IOM_COMPLETED)||(status == IOM_PENDING)))
    {
        (void)printf("GIO_write UART error\n");
    }
    else
    {
        (void)printf("GIO_write UART success...\n");
    }
}

Thanks,

Dennis Nguyen

  • Hi Dennis,

    Dennis Nguyen said:
    Please comment if version 1.30.1 made some critical fixes that I should not miss.
    I do not have PSP 1.30.00.01 installed, but looking at the Release Notes for 1.30.00 there was a bug fixed in this version which may have something to do with the issue you are facing. From the Release Notes,

    CQ SDOCM00060680: Loopback read-write test would hang in interrupt mode when tested using multiple task. This issue was because the ISR was not updating the interrupt status appropriately. This has been fixed.

    Files changed: ti\pspiom\uart\src\Uart.c

    If you are able I do suggest at least testing out the latest version to find out whether or not the same issue exists. Each PSP revision fixes a number of bugs so there is a chance that whatever is hindering your code from properly functioning has already been fixed.

    While you are checking into that I will peruse through the driver to see if I can find anything else that may be responsible for this behavior.

  • Hi Tim,

    TimHarron said:
    If you are able I do suggest at least testing out the latest version to find out whether or not the same issue exists. Each PSP revision fixes a number of bugs so there is a chance that whatever is hindering your code from properly functioning has already been fixed.

    I am hestitating to do the upgrade the PSP from 1.20.0 to 1.30.1 since it took a lot of work for us to move all TI files to our directory tree for source control management.  Sounds like I have no choice if PSP 1.30.1 fix the problem I am experiencing.  I used the new ti\pspiom\uart\src\Uart.c from SP 1.30.1 on top of PSP 1.20.0 and the changes are tremendous on the data structure therefore it is not do able.  Sounds like I have to spend the time for the PSP upgrade.

    Thanks,

    Dennis

  • TimHarron said:
    If you are able I do suggest at least testing out the latest version to find out whether or not the same issue exists.

    Hi Tim,

    I spent a few hours to upgrade from PSP 1.20.0 to 1.30.1.  I was excited when I found the hang problem fixed.  I notified my team to verify I2C, SPI and McASP to make sure that all peripherals have no side effect.  I then attempted to run more UART test.  The results were not too good and here are the facts:

    1. My base line is we were able to transmit 100 bytes every 120msec to UART2 at 115200 baud rate with direct writing to tarnsmitter holding register (THR).  i was able to run this load for many hours.

    2. I enable the UART EDMA and it ran fine for the first few minutes.  My application was configured with aynchronous with a call back for transmission.  After the first few minutes, I got the GIO_submit() returned IOM_ENOPACKETS(-3).  The UART sample code has gioAttrs.nPackets set to 2 and we used that to start with.  I changed this value to 10, I see IOM_ENOPACKETS less frequent but it still occured.  Please let me know what caused IOM_Packet allocation failed.  My application only send 1 packet at a time with a semaphore protection.  This is my code segment:

    void UartTxCallBack( void )
    {
        
    SEM_post( hUartSemHandle );
    }

    int16_t UartSend( uint8_t *data_, uint16_t dataLength_ )
    {
    #if 1
        
    int16_t status;

        
    memcpy( UartTxBuffer, data_, dataLength_ );

        
    status = GIO_submit(hUart_OUT, IOM_WRITE, UartTxBuffer, (size_t *)&dataLength_, NULL);
        
    if(!((status == IOM_COMPLETED)||(status == IOM_PENDING)))
        
    {
            
    (void)printf("GIO_write %d %d %s\n", status, dataLength_, data_ );
        
    }
    #else
        
    Int status =  0;

        
    SEM_pend( hUartSemHandle, 0 );

        
    memcpy( UartTxBuffer, data_, dataLength_ );

        
    TxCallbackFunction.fxn = (GIO_TappCallback)UartTxCallBack;
        
    TxCallbackFunction.arg = NULL;

        
    status = GIO_submit(hUart_OUT, IOM_WRITE, UartTxBuffer, (size_t *)&dataLength_, &TxCallbackFunction);
        
    if(!((status == IOM_COMPLETED)||(status == IOM_PENDING)))
        
    {
            
    (void)printf("GIO_write error status %d\n", status );
        
    }
    #endif
        
    return status;
    }

    3. I changed the UART send function to use synchronous method to workaround the IOM_ENOPACKETS issue.  During my load test, I got IOM_EBADIO(-1) from GIO_submit().  PLease comment what cause this return code.

    4. We spent way too much time on these UART EDMA issues and I would like to seek the backup plan.  I really like the  EVMC6747_UART.C from Spectrum Digital, it is small and it worked.  If possible, I would like to extend this handling to be able register Rx ISR.  When ever I have an incoming byte, the Rx ISR will put this byte to the buffer and process when the packet is filled up.  Please comment.

    Thanks,

    Dennis

     

  • Dennis,

    Dennis Nguyen said:
    Please let me know what caused IOM_Packet allocation failed

    Packet allocation can fail if the packets that are queued to the GIO layer have not been returned back by the lower layer (driver), and the number of packets that GIO can hold for this channel has reached the limit. But in the scenario you explain, only one packet is sent every time and this should not occur. What is the context of UartSend() function -is it TSK context?I guess it is , but just being sure.

    I do not see the complete code, but curiously how could SEM_pend pass without the callback being called (and thus the packet not returned). Can you please explain on this one - may be more clarity with snippets. What I mean is that uartSend is pending on semaphore that is released by the callback (which means the queued packet is returned by the GIO layer). Thus, you are serially waiting for completion of every packet, ENOPACKETS condiotion "should" not be reached.

    Dennis Nguyen said:
    During my load test, I got IOM_EBADIO(-1) from GIO_submit().  PLease comment what cause this return code

    There only a few places in the driver code where IOM_EBADIO is returned. This is usually because of channel errors. Can you check if you have any errors indicated in the status registers? Or perhaps a break points at these places could help.