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 operation in Direct Boot Mode

Other Parts Discussed in Thread: TMS320C6424

Hi,

On the TMS320C6424 EVM I'm using UART0 for simple serial comms.  The peripheral works fine if the board is started with the ROM bootloader enabled.  However, if I do a direct boot (BOOTMODE[3:0] = 0100b & FASTBOOT = 0, or BOOTMODE[3:0] = = 1001b &  FASTBOOT == 1) the UART spits out garbage.  It seems like the ROM bootloader is doing something my code isn't?  I  verified the AUX_CLK is running from the PLL and the PSC has the peripheral powered up with the clock enabled before the code below is executed.  The ROM bootloader version is 0x00010400.  Any thoughts would be appreciated.

uart0 initialization code:

    CSL_UartRegsOvly uartOvly = (CSL_UartRegsOvly)CSL_UART_0_REGS;

 

    Uint32 divisor = 27000000 / ( baudrate * 16 );

 

    uartOvly->PWREMU_MGMT = 0;     // Reset UART TX & RX components

 

    _wait( 100 );

 

    /* Set the baud rate */

    CSL_FINS(uartOvly->DLL, UART_DLL_DLL, divisor);

    CSL_FINS(uartOvly->DLH, UART_DLH_DLH, (divisor >> 8) );

 

    /* Enable FIFO mode */

    CSL_FINST(uartOvly->FCR, UART_FCR_FIFOEN, DISABLE);

    CSL_FINST(uartOvly->FCR, UART_FCR_FIFOEN, ENABLE);

 

    /* Clear Rx and Tx FIFOs */

    CSL_FINST(uartOvly->FCR, UART_FCR_RXCLR, CLR);

    CSL_FINST(uartOvly->FCR, UART_FCR_TXCLR, CLR);

 

    /* DMA mode disabled */

    CSL_FINST(uartOvly->FCR, UART_FCR_DMAMODE1, DISABLE);

 

    /* Set the trigger level to 4 chars */

    CSL_FINST(uartOvly->FCR, UART_FCR_RXFIFTL, CHAR4);

 

    /* Enable Receiver data available interrupt and character timeout indication */

    CSL_FINST(uartOvly->IER, UART_IER_ERBI, ENABLE);

 

    /* Enable Receiver line status interrupt */

    CSL_FINST(uartOvly->IER, UART_IER_ELSI, ENABLE);

 

    /* Disable transmitter holding register empty interrupt */

    CSL_FINST(uartOvly->IER, UART_IER_ETBEI, DISABLE);

 

    /* Break control disabled */

    CSL_FINST(uartOvly->LCR, UART_LCR_BC, DISABLE);

 

    /* Stick Parity disabled */

    CSL_FINST(uartOvly->LCR, UART_LCR_SP, DISABLE);

 

    /* Parity is disabled */

    CSL_FINST(uartOvly->LCR, UART_LCR_PEN, DISABLE);

 

    /* 1 stop bit */

    CSL_FINST(uartOvly->LCR, UART_LCR_STB, 1BIT);

 

    /* Autoflow control disabled */

    CSL_FINST(uartOvly->MCR, UART_MCR_AFE, DISABLE);

 

    /* Loop back disabled */

    CSL_FINST(uartOvly->MCR, UART_MCR_LOOP, DISABLE);

 

    /* Tx on */

    CSL_FINST(uartOvly->PWREMU_MGMT, UART_PWREMU_MGMT_UTRST, ENABLE);

 

    /* Rx on */

    CSL_FINST(uartOvly->PWREMU_MGMT, UART_PWREMU_MGMT_URRST, ENABLE);

 

    /* Emulation Stop */

    CSL_FINST(uartOvly->PWREMU_MGMT, UART_PWREMU_MGMT_FREE, RUN);   

  • Can you determine if the garbage is sent out in response to your UART0 initialization code or if it starts before that? You could put in a long delay prior to the initialization code to find that out. Or try running the same code from RAM in No Boot mode from the emulator, but be sure to remove the GEL file or at least get rid of any initialization from the GEL file, such as in the OnTargetConnect function.

  • Careful with those CSL register macros.  I see some incorrect usage due to a somewhat odd implementation of our UART peripheral.

    Here's a screenshot from the UART guide:

    So as you can see, you don't want to do read-modify-write (e.g. "FINS") operations on the THR and FCR registers because those are write-only registers.  The read will be reading back a different register, modifying it, and then writing the value to another register!

  • Do you have software anywhere that sets VDD3P3V_PWDN = 0?

  • Thank you guys.  It's working now.

    It was only spitting out the garbage when I tried to transmit from the UART after my initialization code (I removed my transmit code and I didn't see any garbage to be sure it was my code causing it).

    VDD3P3V_PWDN was being set (by the Spectrum Digital BSL EVM6424_setupPinMux function).

    The issue was as Brad pointed out my usage of the CSL register macros on write only registers.  I just set the values in those registers and it's working now.  I do like the CSL macros for code clarity but I'll watch out for this in the future.

    Thanks!

  • Excellent job getting it working. And thank you for letting us know..

    There are other CSL macros that you may find more practical for some cases and still give you the code clarity. The example below will run significantly faster than the CSL_FINST macros, although speed is usually not an issue during configuration.

        /* Enable FIFO mode, leaving reset values in other fields */
        uartOvly->FCR =
                        CSL_FMK (UART_FCR_RXFIFTL, 0) ||
                        CSL_FMK (UART_FCR_DMAMODE1, 0) ||
                        CSL_FMK (UART_FCR_TXCLR, 0) ||
                        CSL_FMK (UART_FCR_RXCLR, 0) ||
                        CSL_FMKT(UART_FCR_FIFOEN, ENABLE);

        /* Set Rx trg lvl, DMAmode, clear Tx & Rx FIFOs */
        uartOvly->FCR =
                        CSL_FMKT(UART_FCR_RXFIFTL, CHAR4) ||
                        CSL_FMKT(UART_FCR_DMAMODE1, ENABLE) ||
                        CSL_FMKT(UART_FCR_TXCLR, CLR) ||
                        CSL_FMKT(UART_FCR_RXCLR, CLR) ||
                        CSL_FMKT(UART_FCR_FIFOEN, ENABLE);

    I am not sure why you are disabling the DMAMODE1 bit. It should always be written as 1 per the UART User's Guide.

  • Thanks.  Yes the CSL_FMK macros will improve code clarity v.s. just setting the hex values.

    As for the DMAMODE1 bit in FCR, if I'm not using EDMA transfers why does this have to be set?  I know spruen6c.pdf says:

    "DMA MODE1 enable if FIFOs are enabled. Always write 1 to DMAMODE1. After a hardware reset, change DMAMODE1 from 0 to 1. DMAMOD1 = 1 is a requirement for proper communication between the UART and the EDMA controller. 0 DMA MODE1 is disabled. 1 DMA MODE1 is enabled."

    But why send the events to the EDMA controller if I'm using programmed I/O?

  • UART User's Guide said:
    Always write 1 to DMAMODE1.

    You do not always get direction this clear. The statement of the intended function of the DMAMODE1 bit for EDMA communication adds confusion for a case like yours where you will not be using EDMA. But it does not say to write 1 do DMAMODE1 only if you are using EDMA, it says to always write 1 to DMAMODE1.

    If it hurts your operation with programmed I/O, then please report that to this forum. But if you do not find a negative impact, please write 1 to this bit so you will minimize the chances of problems in the future. I doubt it will hurt your operation, though.

  • "The statement of the intended function of the DMAMODE1 bit for EDMA communication adds confusion for a case like yours where you will not be using EDMA."

    Indeed, it does add confusion.  The trouble is, that the confusion it adds is such that even a TI employee with "guru" status is not really sure how it will affect programmed I/O.   I would really appreciate it if someone can dispel this confusion, to make sure this will not introduce some hidden bug in our system.

    So...5 years have passed, and I am just wondering if there is now a clearer answer.  I see three possibilities:

    1) For programmed I/O, the DMAMODE1 bit should be 0, or at least can be 0 with no problems caused

    2) For programmed I/O, the DMAMODE1 bit must be 1, and as a result, it will send signals to the EDMA controller, but you do not have to worry about this

    3) For programmed I/O, the DMAMODE1 bit must be 1, and as a result, it will send signals to the EDMA controller, and to make sure this does not cause problems, you have to make sure of the following:  (TI guru, please fill in the blank)

    Actually, the best answer would be an exact explanation as to why or when the DMAMODE1 bit must be 1....and if it must always be 1, why not just build it that way in hardware, or at least have that as the reset value?

  • DMAMODE1 relates to the timing of the DMA event generation.  A value of zero corresponds to single-character transfer mode.  A value of one corresponds to the multi-character mode.  Only multi-character mode is validated, tested, and supported and so therefore we say to always write one to the bit.

    Michael Greenspan said:
    2) For programmed I/O, the DMAMODE1 bit must be 1, and as a result, it will send signals to the EDMA controller, but you do not have to worry about this

    This is mostly correct (i.e. it is the most accurate of your 3 statements).  With DMAMODE1 = 1, the UART will send events to the DMA if the FIFO is enabled when the programmed threshold is reached.  If you're not using DMA then none of this likely matters all that much.  The main point here is that we require you to use the device in a mode of operation that has been validated and tested.  So whether you're using DMA or not, you must set this bit.