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.

Using UART0 and UART1 with DSPBIOS for DM6437

Hi,

I'm trying to use UART0 and UART1 for my application using DM6437.

1st I tried using it just as the example included in DVSDK files (uart_bios_dm6437_drv_lib.pjt) , and it works just fine.  I followed it as a reference including it in my own project and it does not work, it all works ok up to the point to where I use "GPIO_write( )" to send characters to UART0.. and right afterwards a verification of this operation is done:

    memcpy(TestStringStart,"UART Demo Starts  \r\nEnter 32 characters for read write test  :\r\n",SIZEOF_UART_STRING_START);
    memcpy(TestStringStop,"\r\nUART Demo End                  ",SIZEOF_UART_STRING_STOP);

    /*
     * Input buffer
     */
    buf.addr = TestStringStart;
    /*
     * Time out value
     */
    buf.timeout = SYS_FOREVER;
    /*
     * Length of data
     */
    len = SIZEOF_UART_STRING_START;
    status = GIO_write(hUart_OUT, &buf, &len);

    /*
     * Error status detection
     */
    if(!((status == IOM_COMPLETED)||(status == IOM_PENDING))){
        LOG_printf(&trace, "\r\nError: 0: Error from GIO_write for UART Tests Start string\n");
    }

In my project, the status is neither COMPLETED or PENDING.. I don't know why.
I included all necessary libraries as indicated in the example (  edma3 libs and Uart lib), initialized UART0 with the init function using DSPBIOS, created the UART0 user defined device within DSPBIOS, configured the UART through the devparams in interrupt mode, and left everything according to example..
In my proyect  code runs exactly as example up to the point where the 1st GIO_write is executed.... then the status returned is an error,.. and the characters I see in the serial port console ( in my pc) are incomplete.

What could be wrong ??  I even tried including the whole sample code in my proyect and running it exactly as the example, still,  the same problem. In the example I see the "interrupt" mode is configured.. however I don't see within the example's DSPBIOS configuration any hardware interrupt or event within ECM, configured to be used with the UART0.. so, how is it that works ? ( in the example I mean),  shouldn't a hardware interrupt be configured somewhere as well  ?

What i want in final terms... (after solving this problem ) is to use UART0 and UART1 in EDMA mode, so I don't have to create an ISR to be attended each time I receive or send 'n' characters,   I would like to use the DMA so it interrupts my program flow each 'n' bytes( let's say 256, a personal serial protocol frame size for a command)  and then process the frame, leaving hard work to DMA.

How can I implement this, or what literature should I consult to know how to use the UART0 in DMA mode ?  ( All necessary steps, including DSPBIOS special configurations, DMA channels and how to create them, connect them, configure them, etc etc).

Thank you very much I've been into this for days with no considerable progress!!!

  • rafael,

    rafael becerra said:
    ,.. and the characters I see in the serial port console ( in my pc) are incomplete.

    Can you describe more about what you see on the console output? That may answer a lot of questions.

    rafael becerra said:
    I even tried including the whole sample code in my proyect and running it exactly as the example, still,  the same problem. In the example I see the "interrupt" mode is configured.. however I don't see within the example's DSPBIOS configuration any hardware interrupt or event within ECM, configured to be used with the UART0.. so, how is it that works ?

    There are a variety of ways to configure interrupts. The ECM is not required, so perhaps the interrupt is configured directly as an HWI rather than using a combiner in the example?

    I will recommend doings your merging of projects the other way around. Start with the example project that works for your UARTs, and add you application project to that. This will mean entering the DSP/BIOS configurations as needed. You may be able to do a lot of that using text editing of the .tcf file, but be careful that you are not overwriting parts that were already defined and used for the example project.

    The UART User's Guide is the best place to look for information on how to use the EDMA3 with the UART peripheral. It describes the interaction in terms of when DMA events are generated.

    You may want to search the forum (red Search box) for others who have tried to use EDMA3 with UARTs. And you might also find some help on the TI Wiki Pages. I have not searched either ahead of you, but I hope you will find something helpful. I have discussed this with others in the past and I do not recall a perfectly clean way to use the EDMA3 for servicing a UART.

    You can "easily" setup a DMA channel for servicing the transmit side, since you know how much data you want to send and there are no decisions to be made at that point. But for the receive side, it would seem best to have a DMA channel setup to handle the FIFO-filled condition and then have the DSP get interrupted either after the FIFO has been read or just periodically to test if any data is in the receive buffer to be examined. If you have a fixed receive data count, then the DMA can be more suited for receive. But even just getting the data in every once in a while will be helpful to the DSP's load.

    Regards,
    RandyP

     

    Please reply back with more details about your application, or if you have solved the problem, reply back with your success story, too.

  • Can you describe more about what you see on the console output? That may answer a lot of questions
    *****************************************************************************************************************


    <- Yes, According to UART example in dvsdk, after the 1st I should see a message in UART console stating:
    "UART Demo Starts 
     Enter 32 characters for read write test: "

    After that, I'm supposed to type 32 characters in console, and right aftterwards UART would write them back as a data verification.
    If I debug step by step, These messages appear right after:

          status = GIO_write(hUart_OUT, &buf, &len);
           // Error status detection
          if(!((status == IOM_COMPLETED)||(status == IOM_PENDING))){
              LOG_printf(&trace, "\r\nError: 0: Error from GIO_write for UART Tests Start string\n");
          }

    In my application, the status returned by GIO_write is -2, which is "timeout", and gives the error shown above. And the only message that I see it appears
    in the console is " UART Demo Starts" without the 2nd line.

    Then, the code reaches a GIO_read:

          status = GIO_read(hUart_IN, &buf, &len);
          if(!((status == IOM_COMPLETED)||(status == IOM_PENDING))){
              LOG_printf(&trace, "\r\nError: Error from GIO_write for Test String\n");
          }

    Where, if I debug it step by step, the dsp remains cycled inside GIO_read until the 32 characters are typed... then the code moves forward..   is that because the UART is configured in Polling mode?
    In my application, GIO_read doesn't cycle and just returns a -2 status again.

    You can "easily" setup a DMA channel for servicing the transmit side, since you know how much data you want to send and there are no decisions to be made at that point. But for the receive side, it would seem best to have a DMA channel setup to handle the FIFO-filled condition and then have the DSP get interrupted either after the FIFO has been read or just periodically to test if any data is in the receive buffer to be examined. If you have a fixed receive data count, then the DMA can be more suited for receive. But even just getting the data in every once in a while will be helpful to the DSP's load.
    ****************************************************************************************************************************************************************************************
    --->
    How do I setup a DMA channel for servicing the transmit side ??
    (that's one of the main doubts.. the how to, which I don't find specifically in documentation)
    you mean adding it in DSPBIOS? same for receiving data in UART and settling another DMA channel for receive, is that done under a hardware interrupt ? ( configuring in DSPBIOS a hardware interrupt)

    That's exactly the idea of UART implementation I'm looking for, in fixed size packages just as you described, my questions are regarding the how to implement the DMA channels and relate them to UART, I mean having a similar process that describes how to add a PSP driver to the application through DSPBIOS but that explains how to include DMA and related to UART.

    What would be a single step by step procedure to perform the DMA channeling with UART ? maybe a very simple example that includes UART using DMA ???

    Thank you very much for your assistance !!

  • If I understand correctly, you have run the example application successfully but when you tried to copy the code into your application it is not working. When I have been faced with similar situations in the past, my approach is to first look over everything that I copied to see what I did not copy in case it was relevant, and second to start from the example project and copy in my application code to figure out when it quits working. You have a working example, so you know that it is possible to get this code to work, and now the difficult part is to figure out what is missing in the copy to your application. If you need to know what the GIO_* error codes are, we may need to request this thread to me moved to the BIOS forum for PSP support, or you can search the PSP documentation and code header files for error codes.

    In the Training section of TI.com, there is a training video set for the C6474. Even though this is not the same DSP you are using, the EDMA3/QDMA/IDMA Module will apply to your current questions. You can find the complete video set at http://focus.ti.com/docs/training/catalog/events/event.jhtml?sku=OLT110002 . This should help you understand a bit more about how to program the EDMA3 for working with the serial port. The examples will not be exactly what you would use for the UART, but they will be a good introduction.

    Regards,
    RandyP

  •  

    Hello, thank you very much for the tips and advices.

    I got UART to work in interrupt mode, I was forgetting for a moment that UART driver has to run within a TASK ( as it has a semaphore included in the driver). I assume that it's true since it worked when I did that change. Also, I had to use the  uart_bios_drv.lib  driver from the dvsk DEBUG folder, because the RELEASE folder didn't seem to work properly eventhough I rebuilt the library project.

    I implemented the UART in the following way:

    -  I have a task that writes a buffer to UART using GIO_write
    - I have another task that reads a buffer from UART using GIO_read
    - both tasks have the same priority

    Defining a tx buffer of 256 bytes, When writing a long message to UART ( say all 256 bytes) write task status becomes blocked as it completes the message in several executions.. (small parts of the message are sent and task is executed several times, I know this because I see terminal window filling up with my message characters in several task executions, while doing this the task status remains in blocked),    it is finally unblocked when the 256 bytes are sent , using GPIO_write to an UART object.

    Here's the code for my TX task:

    void ALV_UartTx(void)
    {
      // execute forever
      for ( ; ;)
     {
         if (TxStr[0] != NULL)        // verify if there is something to send
           {
             // Input buffer
                txbuf.addr = TxStr;
             // Time out value
              txbuf.timeout = SYS_FOREVER;
             // Length of data
             txlen = SIZEOF_UART_STRING_TX;
              txstatus = GIO_write(hUart_OUT, &txbuf, &txlen);

              // Error status detection
             if(!((txstatus == IOM_COMPLETED)||(txstatus == IOM_PENDING)))
                          {
                           printf("UART ERROR: 0: Error from GIO_write for UART TxStr\n");
                            }
                // there was no error, data was sent so mark tx buffer as clean
                 else
                 {
                     TxStr[0] = NULL;
                  }
        }
       // if there is nothing to send, just pass control to another task
       else
       {
        TSK_yield();
        }
    }

    Is this the normal behavior?  I know the UART driver uses a built-in semaphore which is involved into this.  But as soon as the code flow reaches the "GPIO_write" is the task supposed to be blocked until GPIO_write is done writing all bytes to UART ?

    shouldn't the task just pass the buffer to a lower level layer (which would be the one responsible to put all bytes to UART) and continue executing instead of blocking itself until all bytes are sent ?

    am I implementing UART driver the right way ?

  • Rafael,

    The hardware and BIOS issues were things I could help you with, but clarifications on the drivers will need to come from the BIOS forum. If you would, please re-post this latest post on the BIOS forum under the Embedded Software group. You might additinonally include a link back to here, if you think It could be helpful.

    Regards,
    RandyP