The Rx interrupt has to be disabled during UART init. Otherwise, the execution of the firmware hanging.

Hello,

I'm working on a project which uses RA6M5 MCU. The FSP version is 3.5.0. The IAR version is 9.10.2.

There is a UART connected to a third party chip on the board. I found a problem: after the UART initialization, the execution never return from the next statement. After some retries, I disabled the Rx interrupt. Then it seems working. But I can't disable Rx interrupt forever. Is there a way to fix it? Could you please point out where the problem is? Here is the code:

sci_uart_instance_ctrl_t g_uart_ctrl;
baud_setting_t g_uart_baud_setting =
{
  .semr_baudrate_bits_b.abcse = 0,
  .semr_baudrate_bits_b.abcs = 0,
  .semr_baudrate_bits_b.bgdm = 1,
  .cks = 0,
  .brr = 53,
  .mddr = (uint8_t) 256,
  .semr_baudrate_bits_b.brme = false
};

const sci_uart_extended_cfg_t g_uart_cfg_extend =
{
  .clock            = SCI_UART_CLOCK_INT,
  .rx_edge_start    = SCI_UART_START_BIT_FALLING_EDGE,
  .noise_cancel     = SCI_UART_NOISE_CANCELLATION_DISABLE,
  .rx_fifo_trigger  = SCI_UART_RX_FIFO_TRIGGER_MAX,
  .p_baud_setting   = &g_uart_baud_setting,
  .flow_control     = SCI_UART_FLOW_CONTROL_RTS,
  .flow_control_pin = (bsp_io_port_pin_t) UINT16_MAX,
};

const uart_cfg_t g_uart_cfg =
{
  .channel       = 8,
  .data_bits     = UART_DATA_BITS_8,
  .parity        = UART_PARITY_OFF,
  .stop_bits     = UART_STOP_BITS_1,
  .p_callback    = isr_callback,
  .p_context     = NULL,         
  .p_extend      = &g_uart_cfg_extend,
  .p_transfer_tx = NULL, 
  .p_transfer_rx = NULL, 
  .rxi_ipl       = (12),
  .txi_ipl       = (12),
  .tei_ipl       = (12), 
  .eri_ipl       = (12),
  .rxi_irq       = VECTOR_NUMBER_SCI8_RXI,
  .txi_irq       = VECTOR_NUMBER_SCI8_TXI,
  .tei_irq       = VECTOR_NUMBER_SCI8_TEI,
  .eri_irq       = VECTOR_NUMBER_SCI8_ERI,
};

void uart_init()
{
  fsp_err_t err = FSP_SUCCESS;
  sci_uart_instance_ctrl_t * p_ctrl = &g_uart_ctrl;
  
  R_IOPORT_PinCfg(&gpio_ctrl, UART_TX_PIN, ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8));
  R_IOPORT_PinCfg(&gpio_ctrl, UART_RX_PIN, ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8));
  
  err = R_SCI_UART_Open(&g_uart_ctrl, &g_uart_cfg);
  if (FSP_SUCCESS != err)
  {
    tsPrintf("** uart_init: R_SCI_UART_Open API failed **\r\n");
    return;
  }
  
  p_ctrl->p_reg->SCR &= ~SCI_SCR_RIE_MASK;  // Have to disable the Rx interrupt
}

// Calling code
void func()
{
  . . .
  uart_init();
  
  memset(&buffer, 0, sizeof(buffer));  // <-- Never come back after this line if Rx interrupt not disabled at Line 60
  . . .
}

The behaviour is similar to this post(community.renesas.com/.../code-execution-never-finished-from-r_icu_externalirqenable-or-memset). The execution of memset() never returns if the Rx interrupt isn't disabled.

Thanks in advance!

  • Hello sir,

    Thanks for reaching out Renesas Engineering Community!

    Could you please share with me your configuration.xml file to check also the uart stack configurations and  your pins configurations?

    I tried to replicate your issue in both FSP 4.3.0 and 5.1.0  in IAR but did not face the same behavior. Could you please provide me more details to be able to replicate exactly your issue?

    Also please share with me some sample code? Are you only calling the Open API form UART driver, or any other API is called and it is not mentioned.

    Have you tried to test it in a newer FSP version?

    Best Regards,

    IK

  • Hi IK,

    Thank you very much for looking into the issue.

    After more investigation, it turns out I made a mistake by not cleaning the error condition in the ERI ISR. I overrided the ERI ISR provided by the driver. After cleaning the error condition in ERI, it seems working. Here is the code:

    void my_uart_eri_isr(void)
    {
      sci_uart_instance_ctrl_t * p_ctrl = &g_uart_ctrl;
    
      IRQn_Type irq = R_FSP_CurrentIrqGet();
    
      /* Clear error condition. */
      p_ctrl->p_reg->SSR &= (uint8_t) (~SCI_RCVR_ERR_MASK);
    
      rx_err(p_ctrl);
    
      ClearCurrentIrq(irq);
    }
    

    Thanks again. I appreicate it.

  • Hello pilot,

    Thanks for your feedback!

    I haven't seen your configurations.xml file yet to check what UART channel you have configured in the configuration.xml file but from your code I can see that you created a configuration structure which is used as the second argument of R_SCI_UART_Open () API and the channel configured is 8.

    But in case you have configured an other channel in stack properties let's say 0 and you want to change this to 8 in your code as you do, to avoid any issues on the operation of the uart, you can go to RASC in Interrupts tab and add all the events that are related to the UART driver and link them with specific interrupts.

    And in this case I would suggest you better to link them with the already existing ones isr routines as shown in the screenshot below. To avoid any issues like these in the future.

    These information from the interrupt Tab can be found in vector_data.h and vector_data.c and the definition of these isr functions are inside the UART code generated when you add the UART stack in stacks tab in RASC and the processes you are already doing in your own isr routines is already done in these ISRs generated  from the RASC. For the sci_uart_eri_isr:

    Let me also mark your answer as verified, since this might will help and other users who are following the same process as you and face similar issues.

    Best Regards,

    IK

  • Hi IK,

    Thank you so much for the info!

    We do use RASC to generate the driver configurations and use them in our project. But we don't have configurations.xml in our project. 

    Sure, please mark the answer as verified.

    Thanks again!