UART4-7 usage on FreeRTOS: Rx interrupt triggered but no data in Rx buffer

I have a serial peripheral that I have been able to use successfully on UART3 in FreeRTOS on the M4, but when I try to use it on UART7 I get the following behavior:

  • The Rx interrupt is triggered normally
  • The Rx buffer contains only 0’s (data is expected; it is non-zero
    when using the UART3)

The ELF is loaded on the M4 using a Segger JLink debugger from Eclipse, so Linux is not yet started on the A7.

Here is the UART7 configuration, using DTE mode as recommended (excerpts from the pin_mux.c, hardware_init.c and uart_interrupt.c files):

RDC_SetPdapAccess(RDC, rdcPdapUart7, 3 << (BOARD_DOMAIN_ID * 2), false, false);
CCM_UpdateRoot(CCM, ccmRootUart7, ccmRootmuxUartOsc24m, 0, 0);
CCM_EnableRoot(CCM, ccmRootUart7);
CCM_ControlGate(CCM, ccmCcgrGateUart7, ccmClockNeededRunWait);

  IOMUXC_SW_MUX_CTL_PAD_SD1_DATA1 = IOMUXC_SW_MUX_CTL_PAD_SD1_DATA1_MUX_MODE(2);
  IOMUXC_SW_MUX_CTL_PAD_EPDC_DATA12 = IOMUXC_SW_MUX_CTL_PAD_EPDC_DATA12_MUX_MODE(3);

  IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1 = IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1_PE_MASK  |
                                    IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1_PS(3)    |
                                    IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1_HYS_MASK |
                                    IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1_DSE(0);
  IOMUXC_SW_PAD_CTL_PAD_EPDC_DATA12 = IOMUXC_SW_PAD_CTL_PAD_EPDC_DATA12_PE_MASK  |
                                      IOMUXC_SW_PAD_CTL_PAD_EPDC_DATA12_PS(3)    |
                                      IOMUXC_SW_PAD_CTL_PAD_EPDC_DATA12_HYS_MASK |
                                      IOMUXC_SW_PAD_CTL_PAD_EPDC_DATA12_DSE(0);

  IOMUXC_UART7_RX_DATA_SELECT_INPUT = IOMUXC_UART7_RX_DATA_SELECT_INPUT_DAISY(5);



  uart_init_config_t uart_7_initConfig = {
      .baudRate   = 115200u,
      .wordLength = uartWordLength8Bits,
      .stopBitNum = uartStopBitNumOne,
      .parity     = uartParityDisable,
      .direction  = uartDirectionTxRx
  };

  // Get current module clock frequency.
  uart_7_initConfig.clockRate  = get_uart_clock_freq(UART7);

  /* Initialise UART baud rate, bit count, parity, stop bit and direction. */
  UART_Init(UART7, &uart_7_initConfig);
  UART_SetModemMode(UART7, uartModemModeDte);

  // UART_SetInvertCmd(UART7, uartDirectionRx, 1);

  // Disable IR and RS-485 9 bit modes
  UART_SetIrDACmd(UART7, false);
  UART_SetMultidropMode(UART7, false);
  UART_SetRtsFlowCtrlCmd(UART7, 0);
  UART_SetCtsFlowCtrlCmd(UART7, 0);

  /* Set UART Interrupt priority */
  NVIC_SetPriority(UART7_IRQn, 5);

  UART_SetIntCmd(UART7, uartIntRxReady, true);
  UART_SetIntCmd(UART7, uartIntRxDataReady, false);

  UART_SetRxFifoWatermark(UART7, ALT_FIFO_LEN);

  /* Call core API to enable the IRQ. */
  NVIC_EnableIRQ(UART7_IRQn);

  /* Finally, enable the UART module */
  UART_Enable(UART7);

I had a similar issue on UART5. The only difference I can see with the upper UARTs is the fact that they do not have “native” pads; however since the interrupt is triggered I conclude that the pin mux is correct. Is there a missing configuration step for the upper UARTs to work?

Thanks!

Dear @davidbeaudettengc

We are currently pretty much loaded on support and cannot process the support requests as quickly as we would like.
On a first view I couldn’t see any error in your code.
You could try to activate UART5 under Linux or WinCE and readout all the relevant registers, in order to seek for any difference.

I will get back to you as soon as I find some time to dig into the issue. Please be patient.

Regards, Andy

Thanks Andy, it’s great that you will eventually take time to dig into this. In the meantime, I will post any new problem solving information I can gather.

In the end I have solved my problem by looking at the Rx register for the UART7. I observed there was a framing error, which explained why there was no (valid) data in the buffer. Framing error sounds like bad clock so I went back to the initialisation code for the clock and found out that one could not use the get_uart_clock_freq() function from clock_freq.c of the freertos_colibri_m4 repository for the upper UARTs as is, since only UART2 and UART3 are managed by the switch case.

Once I managed the upper UARTs in the switch case, the framing error was gone and the Rx buffer was filled as expected. Now I can start working!

Dear @davidbeaudettengc

Thank you for this feedback. I will add this extension to our repository.

Best Regards
Andy