i.MX6UL UART Sends, But Does Not Receive

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

i.MX6UL UART Sends, But Does Not Receive

跳至解决方案
1,116 次查看
dennis_jelcic
Contributor I

We have created a project using example code in the SDK for a UART device driver.  The example simply receives characters, and sends back whatever is received.  We connected a terminal program to the serial port on our test board.  We are able to compile and run the code.  The example successfully sends characters from our test board to the terminal program on a PC.  However, the example code does not receive characters sent by the terminal program.  The "Ready To Read" flag never goes high.  We have tried both the "interrupt" version and the "polled" version of the example code, with the same failure in either case.

The terminal program we are using to do the testing appears to be configured properly (115200 bps, 8, N, 1, no flow control).

Here is the information regarding our environment and hardware.

Software:  IAR EW 8.32.4
Example Program:  NXP UART device driver example program
Processor:  NXP MCIMX6G2CVM05AA
Processor Board:  NXP MCIMX6UL-CM
Baseboard:  NXP MCIMX6UL-BB

Could there be some configuration setting that is not set properly?

Any assistance would be greatly appreciated.

Thank you.

标签 (1)
标记 (1)
0 项奖励
回复
1 解答
1,028 次查看
igorpadykov
NXP Employee
NXP Employee

Hi Dennis

issue may be casued by Daisy Chain settings, like described in sect.30.5.391

UART2_RX_DATA_SELECT_INPUT DAISY Register (IOMUXC_UART2_RX_DATA_SELECT_INPUT)

i.MX6UL Reference Manual.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

在原帖中查看解决方案

0 项奖励
回复
2 回复数
1,028 次查看
dennis_jelcic
Contributor I

Hi Igor,

Thank you very much for your reply.  It pointed me in the right direction, and I was able to get the example to work.

However, the way that the example was coded did not work without modification.  This is a standard example for a polling uart in the 2.2 version of the SDK.  I will describe what I discovered, and what I modified, in hopes that it will help someone else who may struggle with a similar problem.


The file pin_mux.c contains a function named BOARD_InitPins().  Here is what the original function looks like:


    void BOARD_InitPins(void) {                                /*!< Function assigned for the core: Cortex-A7[ca7] */
        IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0U);
        IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX,
                            IOMUXC_SW_PAD_CTL_PAD_DSE(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
        IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0U);
        IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,
                            IOMUXC_SW_PAD_CTL_PAD_DSE(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
    }


There are two calls to IOMUXC_SetPinMux(), one for the receive (RX) pad, and one for the transmit (TX) pad.  The IOMUXC_SetPinMux() function has six parameters, as follows:

    static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
                                        uint32_t muxMode,
                                        uint32_t inputRegister,
                                        uint32_t inputDaisy,
                                        uint32_t configRegister,
                                        uint32_t inputOnfield)

The first call to IOMUXC_SetPinMux() initializes the RX pad using a macro named IOMUXC_UART1_RX_DATA_UART1_RX, which is defined in fsl_iomuxc.h as:

    0x020E0088U, 0x0U, 0x020E0624U, 0x3U, 0x020E0314U

Here is the definition of each parameter in the IOMUXC_UART1_RX_DATA_UART1_RX macro:

    0x020E0088U   - address of the IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA control register
    0x0U                  - the MUX_MODE (ALT Mode) to be used for the pad = set to ALT0 - UART1_RX
    0x020E0624U   - address of the IOMUXC_UART1_RX_DATA_SELECT_INPUT daisy register
    0x3U                  - the DAISY value to be used for the pad = UART1_RX_DATA_ALT0
    0x020E0314U    - address of the IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA SW PAD control register


OK, so far, so good.  The problem comes in second call to IOMUXC_SetPinMux(), which initializes the TX pad using the definition of the macro named IOMUXC_UART1_TX_DATA_UART1_TX, which is defined in fsl_iomuxc.h as:

    0x020E0084U, 0x0U, 0x020E0624U, 0x2U, 0x020E0310U
    
Here is the definition of each parameter in the IOMUXC_UART1_TX_DATA_UART1_TX macro:

    0x020E0084U - address of the IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA control register
    0x0U               - the MUX_MODE (ALT Mode) to be used for the pad = set to ALT0 - UART1_TX
    0x020E0624U - address of the IOMUXC_UART1_RX_DATA_SELECT_INPUT daisy register
    0x2U                - the DAISY value to be used for the pad = UART1_TX_DATA_ALT0
    0x020E0314U  - address of the IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA SW PAD control register

THE THIRD AND FOURTH PARAMETERS ARE WRONG!  As I understand it, the Daisy register is designed to select an INPUT to a module.  However, the second macro is defining an OUTPUT (TX) pad, and is changing the SAME Daisy register as the RX macro did.  So this macro is changing (redefining) the Daisy value to point to the TX pad after the previous macro set the Daisy register to point to the RX pad.  As a result, this example never receives any characters input by a user in a terminal program, because the uart module is expecting input from the TX pad.

Since the macro appears to be incorrect, I modified the second function call to IOMUXC_SetPinMux() to use the actual address values, and I made sure to set the same value for the Daisy register as was used in the first call to IOMUXC_SetPinMux().  Here is what it looks like:

    void BOARD_InitPins(void) {                                /*!< Function assigned for the core: Cortex-A7[ca7] */
        IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0U);
        IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX,
                            IOMUXC_SW_PAD_CTL_PAD_DSE(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);

    //  IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0U);
        IOMUXC_SetPinMux(0x020E0084U, 0x0U, 0x020E0624U, 0x3U, 0x020E0310U, 0U);
        IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,
                            IOMUXC_SW_PAD_CTL_PAD_DSE(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
                            IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
    }


It appears that this error is propagated to the other UART (UART2-UART5) definitions as well.

The lesson learned here is that you cannot assume that pad configurations are correct.  You have to check these definitions to make sure they are configured properly.


Thanks again for your suggestion Igor.  It was helpful in solving this problem.

Regards,
Dennis

0 项奖励
回复
1,029 次查看
igorpadykov
NXP Employee
NXP Employee

Hi Dennis

issue may be casued by Daisy Chain settings, like described in sect.30.5.391

UART2_RX_DATA_SELECT_INPUT DAISY Register (IOMUXC_UART2_RX_DATA_SELECT_INPUT)

i.MX6UL Reference Manual.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复