Changing UART cfg to temporary struct results in truncated write packets

I have a problem where my S5's uart driver is being told to send 1029 bytes but it's only sending 16. I'm using the HAL driver, not the framework. The background is, my S5 firmware is set up to talk over SCI_9 to a vendor-provided device with an ARM MCU running vendor firmware. The vendor set up the device to communicate using our SLIP protocol at 115200 bps.  This works fine. The problem is that my S5 firmware has to run flash update to this device, in its "boot mode".  To enter boot mode you hold a special pin low and cycle the RST pin low to high.  Once in boot mode, the vendor's ARM MCU takes over and expects to communicate using a different (non-SLIP) protocol. (It happens to be the Ymodem protocol).  This means I have to change to a different receive callback function that uses the vendor's protocol.

In principle I know how to do this, and it is working to some degree.  When we put the target MCU in boot mode, I copy my g_uart_sci9_cfg structure from flash to SRAM, to the structure g_uart_sci9_cfg_temp. I then assign the new callback to this structure:
g_uart_sci9_cfg_temp.p_callback = uart_callback_sci9_temp.  

I then close the running uart driver and open it with the same p_ctrl structure but the new p_cfg structure.  I'm tracing the comms and I see properly formatted packets coming back from the vendor device.

The problem is that when I attempt to send a 1029-byte packet from the S5, it only sends 16 bytes.  I looked at the data returned from the getInfo() api, and it says the write limit is 0xFFFFFFFF bytes.  When using the original SCI_9 uart driver from flash, I'm able to send packets up to our max (288 bytes) with no issues. Posting here hoping that I missed something obvious.  The 16 bytes makes me think it could be FIFO related.  Thank you.

tom

  • Hi Tom,

    0xFFFFFFFF for max write would indicate no DTC being used. Is there any transfer still going on when driver is closed?

    Regards
  • In reply to Renesas Karol:

    Hi Karol,
    Yes, we intentionally don't use DTC in normal operation since we use MMF in our application. Before closing the driver and reopening it with the temporary cfg struct, the code blocks and waits for the mutex associated with SCI_9. When it gets the mutex it performs the close, copy cfg, and open. There should not be any comm in progress when the SCI is closed, since the mutex at that point is owned by the thread doing the flash update preps.
  • In reply to tclong:

    I did a member by member comparision of the const cfg struct for SCI_9, vs the sram copy. they are member for member identical except for the callback assignment, which was expected.
  • In reply to tclong:

    Hello Tom,

    Can you do the same comparison after 16 bytes are sent out? In ISR-transfer setup especially, the driver relies heavily on the information in the control block to send and receive data. The issue sounds like something in the control block has been overwritten by another part of the application.

    Regards
  • In reply to Renesas Karol:

    Hi Karol,
    The temporary CONFIG structure does not change after the 16 bytes are sent. However, there is a change in the CONTROL structure as you suspected. I clipped the relevant parts here. The first clip shows all members. The other clips only show the members that changed after sending the 16 bytes. The final clip shows something about repeating 200 times, and 1008 bytes for transmit.

    Control block before shift to temporary cfg:
    ----------------------------------------------------------
    g_uart_sci9_ctrl sci_uart_instance_ctrl_t {...} 0x20053990
    channel uint8_t 9 '\t' 0x20053990
    fifo_depth uint8_t 16 '\020' 0x20053991
    rx_transfer_in_progress uint8_t 0 '\0' 0x20053992
    data_bytes uint8_t 1 '\001' 0x20053993
    bitrate_modulation uint8_t 1 '\001' 0x20053993
    open uint32_t 0x53434955 (Hex) 0x20053994
    p_transfer_rx const transfer_instance_t * 0x0 <__Vectors> 0x20053998
    p_transfer_tx const transfer_instance_t * 0x0 <__Vectors> 0x2005399c
    p_tx_src const uint8_t * 0x0 <__Vectors> 0x200539a0
    tx_src_bytes uint32_t 0 0x200539a4
    rxi_irq IRQn_Type 0x33 (Hex) 0x200539a8
    txi_irq IRQn_Type 0x35 (Hex) 0x200539a9
    tei_irq IRQn_Type 0x34 (Hex) 0x200539aa
    eri_irq IRQn_Type 0x32 (Hex) 0x200539ab
    p_callback void (*)(uart_callback_args_t *) 0x3093d <user_uart_callback_sci9> 0x200539ac
    p_context const void * 0x8e740 <g_uart_sci9> 0x200539b0
    *p_context const void -113 0x8e740
    p_reg void * 0x40070120 0x200539b4
    *p_reg void -113 0x40070120
    p_extpin_ctrl void (*)(uint32_t, uint32_t) 0x0 <__Vectors> 0x200539b8

    Control block after copying cfg to temporary cfg:
    ----------------------------------------------------------------
    g_uart_sci9_ctrl sci_uart_instance_ctrl_t {...} 0x20053990
    p_tx_src const uint8_t * 0x0 <__Vectors> 0x200539a0
    tx_src_bytes uint32_t 0 0x200539a4
    p_callback void (*)(uart_callback_args_t *) 0x3093d <user_uart_callback_sci9> 0x200539ac

    Control block after close/open with temporary cfg (assigns callback uart_callback_sci9_temp):
    -----------------------------------------------------------------------------------------------------------------------------
    g_uart_sci9_ctrl sci_uart_instance_ctrl_t {...} 0x20053990
    p_tx_src const uint8_t * 0x0 <__Vectors> 0x200539a0
    tx_src_bytes uint32_t 0 0x200539a4
    p_callback void (*)(uart_callback_args_t *) 0x77985 <uart_callback_sci9_temp(uart_callback_args_t*)> 0x200539ac

    Control block after SENDING the 16 bytes:
    ---------------------------------------------------------
    g_uart_sci9_ctrl sci_uart_instance_ctrl_t {...} 0x20053990
    p_tx_src const uint8_t * 0x200551b7 <yBlock+19> 'í' <repeats 200 times>... 0x200539a0
    tx_src_bytes uint32_t 1008 0x200539a4
    p_callback void (*)(uart_callback_args_t *) 0x77985 <uart_callback_sci9_temp(uart_callback_args_t*)> 0x200539ac
  • In reply to tclong:

    For this test I sent a data packet consisting of 1024 0xED characters. The data buffer address is yBlock+3. So yBlock+19 is pointing to the byte after the first 16 bytes.
  • In reply to tclong:

    Hi Tom,

    The control block looks fine. Does you application do anything with the interrupts during the transmission?

    Regards
  • In reply to Renesas Karol:

    I don't believe we are doing anything with the interrupts during these tests.

    I saw a different post where Gary J addressed a similar problem someone had, they were using the framework with TX_NO_WAIT which caused their write packet to truncate at 16 bytes. I'm using the HAL driver, which doesn't use that parameter, but this sure looks similar.
    renesasrulz.com/.../uart-array-truncation-issue
  • In reply to tclong:

    Hello Tom,

    UART Framework read/write calls are blocking by design. By specifying immediate timeout, insufficient time is given for UART peripheral to complete the transaction and transfer is aborted prematurely. I wouldn't expect this to be an issue when using UART HAL driver because its calls are non-blocking and interrupt should always arrive after completion of the transfer, unless communicationAbort is invoked.

    The next step in tracking this issue would be to check the UART registers to see if anything obvious can be spotted (like TE or TIE bit not set).

    Regards
  • In reply to Renesas Karol:

    Hi Tom-
    Let us know if you discovered what the underlying issue was and how to solve it. It would be helpful to share the solution with the community.

    Thanx,
    Warren
  • In reply to WarrenM:

    Hi Warren,
    I have not solved this problem, I had to move on to something else. I plan to return to it, hopefully soon.
    Thank you,