RTS/CTS Hardware flow with UART Module

Although there is only one physical pin per SCI/UART channel for RTS/CTS, you can do full RTS/CTS flow control.  First select Custom in the pins configurations for the SCI channel and select a pin for CTS_RTS_SS.  

Then, in Threads tab select the UART module and set the CTS/RTS Selection to CTS.  This assigns the CTS_RTS_SS pin to CTS operation.  Next, set the External RTS Operation to Enabled and "Name of UART callback function for RTS external pin..." to a user defined callback to process RTS events.  You have to use a GPIO (configured as output) for RTS and control it in the user callback.  

  • Hello

    Thanks for the post it really helped me. 

    I'm trying to make use of RTS/CTS i have done everything as mentioned. I'm getting error in UART thread stack for saying "Receive Transfer cannot be used (must be NULL) if RTS callback is used". I have attached screenshots of my error and pin configurations. 

    Hot to fix this issue and assign a gpio pin to RTS.

     

    If possible help me with any working example or any step by step tutorial to configure RTS/CTS.

     

     

    My Pin configurations

     

    Please help,

     

    Thanks in advance.

  • In reply to Sree:

    Hi Sree,

    You should remove the underlying Transfer Driver. The first one is for transmission, the second is for reception and this one should be removed. In most cases in SSP drivers and frameworks, Transfer Drivers are optional.

    Regards,
    adboc

  • In reply to adboc:

    Hi adboc,

    Thank you for your valuable inputs. I have removed second Transfer driver. But now i'm unable to debug as i'm getting no source available error.

    I'm sorry if i sound noob. I'm new to renesas platform and also to uart. 

     

    Please help me with any example in which rts and cts are used. 

    Im trying to test with ftdi chip connected to pc, if rts cts works with ftdi i have to test with barcode scanner. Please help me with your valuable inputs.

     

     

    Thanks in advance.

     

     

  • In reply to Sree:

    Hi Sree,

    I guess you've defined uart_rts_event_callback? Do you use any printf-like function in this callback?

    There some information regarding hardware flow control in SSP User's Manual. The HTML version is likely to be found (if the checkbox has been marked when installing the SSP) in C:\Renesas\Synergy\SSP_Documentation. There should be ZIP file, extract it and open the .html file. Section User Guides > HAL Layer > UART Driver contains useful information. The PDF version is also available in Synergy Gallery: synergygallery.renesas.com/.../archive

    Regards,
    adboc

  • In reply to adboc:

    Hello adboc,

    I have followed the above post and define the uart_rts_event_callback ? (I have not put anything in this function as of now, i assume this function i must use to send data)

    In the above post:
    Next, set the External RTS Operation to Enabled and "Name of UART callback function for RTS external pin..." to a user defined callback to process RTS events.
  • In reply to Sree:

    Hi Sree,

    Yes, you have to define uart_rts_event_callback, this name is provided in the configuration settings of the UART Driver.

    The signature for this function should look like:

    void uart_rts_event_callback (uint32_t channel, uint32_t level);

    According to the SSP User's Manual:

    "Pointer to the user callback function to control external GPIO pin control used as RTS signal.

    Parameters

       [in] channel The UART channel used.

       [in] level When level is 0, assert RTS. When level is 1, deassert RTS."

    So you should control the GPIO you would like to use as RTS pin. Please remember to configure the pin as an output. To control this pin, use the IO Port Driver added to each Synergy application by default.

    For example:

    #define RTS_PIN (IOPORT_PORT_02_PIN_01)  // set RTS pin

    void uart_rts_event_callback (uint32_t channel, uint32_t level)
    {
        if (level == 0)
        {
            g_ioport.p_api->pinWrite(RTS_PIN, IOPORT_LEVEL_HIGH);
        }
        else
        {
            g_ioport.p_api->pinWrite(RTS_PIN, IOPORT_LEVEL_LOW);
        }
    }

     

    Regards,
    adboc

  • In reply to adboc:

    Hi,

    I tried the RTS callback above with SSP v.1.6.0.

    I wasn't able to get it to work until I inverted the pin levels in the callback.

    Callback as written above:

    Callback inverted:

    Is it correct to invert the RTS pin and is the latter behavior as expected? Signals in the pictures named according to MCU pins.

     

    Edit: the UART HAL Module guide (R11AN0085EU0101) Figure 11 has somewhat similar picture to the inverted callback above and the sample code related to that application note also has the polarity of the pin "inverted".

  • In reply to adboc:

    Using the configuration above, I can't make the callback firing except I when the CTS/RTS selection is set to CTS.
    How can I control the RTS pin in the callback?

    I am using the latest e2 Studio and SSP.


    Thanks.

  • In reply to Copper:

    Hi Cooper,

    In the callback you need to assert the RTS pin state using the pinWrite API. For example:

    void g_uart0_rts_callback(uint32_t channel, uint32_t level)
    {
        SSP_PARAMETER_NOT_USED(channel);
        g_ioport.p_api->pinWrite(IOPORT_PORT_04_PIN_04, (ioport_level_t) level);
    }

    Where my RTS signal is on port 4 pin 4.

    -Gary
  • In reply to garyj:

    Hi Gary,
    The problem is the call back never fire and thus, I can't control the pin in the callback function
  • In reply to Copper:

    Cooper,

    The callback is used if the CTS/RTS selection is set to CTS and the External RTS Operation is enabled in the UART Driver properties .

    -Gary
  • In reply to garyj:

    Gary,

    the SSP saying that : The callback function argument "@ref level" refers to the signal level on the RTS pin for the selected
    SCI channel.

    Is the RTS pin selected in the peripheral configuration like below?

     

    Look like the diagram below showing RTS and CTS are 2 GPIO pins. Is it correct? 

     

    The level in the callBack is always LOW.

    void uart_RTS_callBack(uint32_t channel, uint32_t level)
    {

    SSP_PARAMETER_NOT_USED(channel);


    if (level)
        g_ioport.p_api->pinWrite(IOPORT_PORT_03_PIN_03, IOPORT_LEVEL_HIGH);

    else
       g_ioport.p_api->pinWrite(IOPORT_PORT_03_PIN_03, IOPORT_LEVEL_LOW); 

    }

     

     

    Thanks.

  • In reply to Copper:

    IOPORT_PORT_03_PIN_03 is not a GPIO pin, it is configured as the SCI CTS pin. The RTS pin will need to be a different pin, and configured as a GPIO.
  • In reply to Jeremy:

    Thank Jeremy for your reply.
    I have tried to use a GPIO pin in the callback, but the level in the call back always LOW. Do you have any advise?
  • In reply to Copper:

    CTS is not a GPIO, it is configured as a peripheral pin, and directly controlled by the SCI HW, the CTS pin is P3_03 :-

     

    RTS pin needs to be a different pin, configured as a GPIO, and controlled by the callback. E.g. assuming that P3_04 is used as the RTS GPIO :-

     

    #define RTS_GPIO_PIN   IOPORT_PORT_03_PIN_04

    void uart_RTS_callBack(uint32_t channel, uint32_t level)

    {

    SSP_PARAMETER_NOT_USED(channel);

    if (level)

       g_ioport.p_api->pinWrite(RTS_GPIO_PIN   , IOPORT_LEVEL_HIGH);

    else

      g_ioport.p_api->pinWrite(RTS_GPIO_PIN   , IOPORT_LEVEL_LOW);

    }