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.

RTOS/AM5728: Trouble changing UART instance

Part Number: AM5728

Tool/software: TI-RTOS

I've read through several threads including:

https://e2e.ti.com/support/arm/sitara_arm/f/791/p/675848/2495684?tisearch=e2e-sitesearch&keymatch=rtos%20am57%20uart%20pinmux#2495684

and

https://e2e.ti.com/support/arm/sitara_arm/f/791/t/689589?tisearch=e2e-sitesearch&keymatch=rtos%20am57%20uart%20pinmux

I'm using a custom board and pinmux configuration that enables UART's 3 and 5, it uses 3 by default. I can't seem to make any of my changes in the board library or driver files take effect. I've recompiled the board library by using "make board_lib_clean" and then "make board_lib". I then cleaned and recompiled my app but nothing changes.

int main(void)
{
    Task_Params taskParams;
    Task_Handle task;
    Error_Block eb;

    UART_Params params = {
        UART_MODE_CALLBACK,     /* readMode */
        UART_MODE_CALLBACK,     /* writeMode */
        SemaphoreP_WAIT_FOREVER,/* readTimeout */
        SemaphoreP_WAIT_FOREVER,/* writeTimeout */
        uartRxCb,             /* readCallback */
        uartTxCb,             /* writeCallback */
        UART_RETURN_FULL,     /* readReturnMode */
        UART_DATA_TEXT,       /* readDataMode */
        UART_DATA_TEXT,       /* writeDataMode */
        UART_ECHO_ON,        /* readEcho */
        115200,               /* baudRate */
        UART_LEN_8,           /* dataLength */
        UART_STOP_ONE,        /* stopBits */
        UART_PAR_NONE         /* parityType */
    };

    // initialize UART settings
    UART_init();
    uart_handle = UART_open(UART_INSTANCE, &params); // UART_INSTANCE=2 (UART3)

    // create UART messaging task
    Error_init(&eb);
    Task_Params_init(&taskParams);
    taskParams.instance->name = "uartTest";
    task = Task_create(uart_test, &taskParams, &eb);
    if (task == NULL) {
        System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }

    /* Start BIOS */
    BIOS_start();
    return (0);
}

In my code snippet, the only thing that will reliably change is the settings when I change the UART_INSTANCE in the UART_open call. It uses a different configuration depending on which number I pass, but it does not reflect any changes I make when I edit the file I thought the configuration is coming from, UART_soc.c. Here are the files I've edited but no changes are being reflected when I recompile my program and debug:

C:\ti\pdk_am57xx_1_0_10\packages\ti\board\src\{board}\{board}_pinmux.c

C:\ti\pdk_am57xx_1_0_10\packages\ti\board\src\{board}\boardPadDelayInit.c

C:\ti\pdk_am57xx_1_0_10\packages\ti\board\src\{board}\include\board_cfg.h

C:\ti\pdk_am57xx_1_0_10\packages\ti\drv\uart\soc\am572x\UART_soc.c

I'm trying to just change my instance to UART5 which in the pinmux file isassigned to pins F11(rx) and G10(tx). If I change UART_INSTANCE to reflect UART5 with UART_open, it appears to open correctly but I do not get any kind of signal from the expected source. That's when I just tried to "break" it and see which files it was actually pulling the configuration from, but I've been unsuccessful to this point.

Any suggestions as to what I may be doing wrong in terms of rebuilding the board_lib or why I can't seem to see any changes would be greatly appreciated.

  • The RTOS team have been notified. They will respond here.
  • Hi John,

    We recently went through the exercise of enabling UART5 with a customer using idkAM572x so I think that I have a fair idea the issue that you are running into may be due to UART5 clock being disabled but I can`t confirm not all the details are available in the code that you posted above.

    Can you confirm that you have a Board_init call in your code that sets up the clock and pin mux for the device. The UART driver is written independent of the SOC and relies on Board library to setup the clock and pinmux and relies on the UART_soc.c file for SOC IP related and interrupt configuration.

    The board library and it appears that only UART1, UART3 and UART9 clocks are enabled as these are the three debug UART instance on different TI evaluation platforms

    The following code needs to be added to the function Board_moduleClockInit() inside
    C:\ti\pdk_am57xx_1_0_9\packages\ti\board\src\<board>\ <board>_clock.c.

    // The following code has been added in order to enable the clock for UART 5.
    // This code has been added by me upon feedback from Carlo.
    CSL_FINST(l4PerCmReg->CM_L4PER_UART5_CLKCTRL_REG,
    L4PER_CM_CORE_COMPONENT_CM_L4PER_UART5_CLKCTRL_REG_MODULEMODE, ENABLE);
    while(CSL_L4PER_CM_CORE_COMPONENT_CM_L4PER_UART5_CLKCTRL_REG_IDLEST_FUNC !=
    CSL_FEXT(l4PerCmReg->CM_L4PER_UART5_CLKCTRL_REG,
    L4PER_CM_CORE_COMPONENT_CM_L4PER_UART5_CLKCTRL_REG_IDLEST));

    The other thing that I would like to confirm is more of a HW related question. UART5 TX and RX pin are muxed with different pins. Can you confirm that on your custom board you are using G17 and B24 and that in your pinmux . You have selected the right pin name when you selected UART5.

    Can you read back the value of the registers at following location if you are using above pins.
    // read CTRL_CORE_PAD_SPI2_D0, ball G17
    retVal = *(uint32_t *)0x4A0037C8;

    // read CTRL_CORE_PAD_SPI2_CS0 ball B24
    retVal = *(uint32_t *)0x4A0037CC;

    If you are not using those pins, please provide a read from the PAD register for those pins to confirm the muxmode is set correctly after you rebuilt the board library.

    Regards,
    Rahul
  • Hi Rahul,

    I confirmed in my <board>_clock.c file that the code you shared was already present in the file. For the Board_init, I'm calling it with the following configuration:

    Board_initCfg boardCfg;
    boardCfg = BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
    Board_init(boardCfg);

    For our board, UART5 is routed to pins F11 and G10. In the boardPadDelayInit.c file we have:

    /* UART5 - uart5_rxd on F11 - X_UART5 */
    {0x15DC, 0x50002, {0x0, 0, 0}, {0x0, 0, 0}, {0x0, 0, 0}},
    
    /* UART5 - uart5_txd on G10 - X_UART5 */
    {0x15E0, 0x10002, {0x0, 0, 0}, {0x0, 0, 0}, {0x0, 0, 0}},

    Then I verified the value in the registers by using your suggested method:

    // read CTRL_CORE_PAD_VOUT1_D0, ball F11
    retVal = *(uint32_t *)0x4A0035DC;
    
    // read CTRL_CORE_PAD_VOUT1_D1 ball G10
    retVal = *(uint32_t *)0x4A0035E0;

    And received back the values of 50002 and 10002.

    Then when I call UART_open for UART5, I check Hwi in the ROV and see that interrupt 137 has been triggered. Which I believe corresponds correctly to the UART_soc.c file. But I still don't have any activity coming from the expected board pin when I loop a UART_write.

    Thank you again for your help,

    John

  • Another thing I've noticed, I'm not sure if my call to Board_init is working properly. I tried changing the values in the boardPadDelayInit.c file and then rebuild the board_lib, but I do not see the value change in my program after Board_init is called.

    For example, I changed the existing value of register 0x4A0035DC which is 0x50002 to 0xC0002. In my program it initializes as 0x50002 and is never changed.

    /* UART5 - uart5_rxd on F11 - X_UART5 */
    {0x15DC, 0x50002, {0x0, 0, 0}, {0x0, 0, 0}, {0x0, 0, 0}},

    to

    /* UART5 - uart5_rxd on F11 - X_UART5 */
    {0x15DC, 0xC0002, {0x0, 0, 0}, {0x0, 0, 0}, {0x0, 0, 0}},

  • I'm sorry, another update. I've found that the Board_pinmuxConfig() function is returning BOARD_PINMUX_BAD_MEM_REGION on the section:
    /* Check to make sure IO Delay stack and functions are in local memory */
    if (((uint32_t) &ioStack >= 0x80000000) || ((uint32_t)BoardCtrlPadIoDelayConfig >= 0x80000000))
    return BOARD_PINMUX_BAD_MEM_REGION;

    &ioStack is showing a value 0x800229BC and BoardCtrlPadIoDelayConfig is 0x8001EE94.

    I believe that means that Board_init is returning without ever setting up the pinmux?

    Thanks,
    John
  • The check has been enforced because it is a device requirement to run the pin mux application code from OCRAM and not from DDR.  This means that your pinmux is not being applied.

    Please refer to the Application Integration for AM5x/DRA7x in the Processor SDK RTOS Board library documentation for guidance on this issue:

    In baremetal case with a linker cmd file:

    BOARD_IO_DELAY_CODE : {
    
       . = ALIGN(4);
       *(BOARD_IO_DELAY_CODE*)
    
    } > OCMC_RAM1
    
    BOARD_IO_DELAY_DATA : {
    
       . = ALIGN(4);
       *(BOARD_IO_DELAY_DATA*)
    
    } > OCMC_RAM1
    

    In a BIOS RTSC project with .cfg file:

    Program.sectMap["BOARD_IO_DELAY_DATA"] = "OCMC_RAM1";
    Program.sectMap["BOARD_IO_DELAY_CODE"] = "OCMC_RAM1";

  • Hi Rahul,

    Thank you for this information! My Board_init() function is working correctly after adding the Program.sectMAP lines to my .cfg file. I'm also able to successfully modify and initialize my UART settings with the UART_socGetInitCfg() and UART_socSetInitCfg() functions. But I'm still having trouble when using UART_INSTANCE = 4 (UART 5). Here's my updated initialization code:

    int main(void)
    {
        Task_Params taskParams;
        Task_Handle task;
        Error_Block eb;
    
        UART_Params params = {
            UART_MODE_CALLBACK,     /* readMode */
            UART_MODE_CALLBACK,     /* writeMode */
            SemaphoreP_WAIT_FOREVER,/* readTimeout */
            SemaphoreP_WAIT_FOREVER,/* writeTimeout */
            uartRxCb,             /* readCallback */
            uartTxCb,             /* writeCallback */
            UART_RETURN_FULL,     /* readReturnMode */
            UART_DATA_TEXT,       /* readDataMode */
            UART_DATA_TEXT,       /* writeDataMode */
            UART_ECHO_ON,        /* readEcho */
            115200,               /* baudRate */
            UART_LEN_8,           /* dataLength */
            UART_STOP_ONE,        /* stopBits */
            UART_PAR_NONE         /* parityType */
        };
    
        Board_initCfg boardCfg;
        boardCfg = BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
        Board_init(boardCfg);
    
        // initialize UART settings
        UART_socGetInitCfg(UART_INSTANCE, &uart_cfg); // UART_INSTANCE = 4
        UART_socSetInitCfg(UART_INSTANCE, &uart_cfg);
        UART_Params_init(&params);
    
        uart_handle = UART_open(UART_INSTANCE, &params);
    
        // create UART messaging task
        Error_init(&eb);
        Task_Params_init(&taskParams);
        taskParams.instance->name = "uartTest";
        task = Task_create(uart_test, &taskParams, &eb);
        if (task == NULL) {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
    
        /* Start BIOS */
        BIOS_start();
        return (0);
    }

    When it calls UART_write to UART 5 with these settings in my uartTest task, it errors out and exists the application. I've tried adding the LoggingSetup to my .cfg file, but I'm not sure where I should see the output.

    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    LoggingSetup.loadLogging = true;
    LoggingSetup.loadLoggerSize = 1024;
    LoggingSetup.mainLoggerSize = 327680;
    LoggingSetup.sysbiosLoggerSize = 327680;
    LoggingSetup.sysbiosSwiLogging = true;
    LoggingSetup.sysbiosHwiLogging = true;
    LoggingSetup.sysbiosSemaphoreLogging = true;
    LoggingSetup.loadTaskLogging = true;
    LoggingSetup.loadSwiLogging = true;
    LoggingSetup.loadHwiLogging = true;
    LoggingSetup.enableTaskProfiler = true;
    LoggingSetup.sysbiosHwiLoggingRuntimeControl = true;
    LoggingSetup.sysbiosSwiLoggingRuntimeControl = true;
    LoggingSetup.loggerType = LoggingSetup.LoggerType_STOPMODE;
    
    LoggingSetup.loadLoggingRuntimeControl = true;
    LoggingSetup.enableContextAwareFunctionProfiler = true;
    LoggingSetup.profileLogging = true;
    LoggingSetup.countingAndGraphingLogging = true;
    LoggingSetup.benchmarkLogging = true;
    LoggingSetup.snapshotLogging = true;

    Here's the screenshot of the error I receive from UART_write():

    Thank you,
    John

  • I believe one of my issues was with calling the BOARD_INIT_UART_STDIO with Board_init and calling UART_open again with the same instance number later on. I changed my initialization process to the following which appears to now allow the UART_write() to work successfully. But I still do not read any activity on UART5 when monitoring with a scope. Are there any other settings I may have missed somewhere that would allow reading/writing over UART5?

    Initialization code snippet:

        Board_initCfg boardCfg;
        boardCfg = BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_MODULE_CLOCK;
        Board_init(boardCfg);
    
        // initialize UART settings
        UART_socGetInitCfg(UART_INSTANCE, &uart_cfg);
        UART_socSetInitCfg(UART_INSTANCE, &uart_cfg);
        UART_Params_init(&params);
        UART_init();
    
        uart_handle = UART_open(UART_INSTANCE, &params);

  • The problem appeared to be hardware related. I tried running my application on another board and it worked great on both UART3 and UART5.

    Thank you again for the assistance!