1 SCI_ - renesas/rx72n-envision-kit GitHub Wiki

Things to prepare

  • Indispensable
    • RX72N Envision Kit × 1
    • USB cable (USB Micro-B --- USB Type A) × 2
    • Windows PC × 1 unit

Prerequisite

Check circuit

    • SCI(Serial Communication Interface) has two UART interfaces of TXDx on transmit side and RXDx(X is channel number) on receipt side on data signal line, like P13/TXD2 and P12/RXD2 on the above circuit
    • Can be used as UART interface with flow control mechanism by adding CTS/RTS signal to TXDx and RXDx.
    • Also, can be used as a mode other than UART, such as I2C and SPI
    • In RX72n Envision Kit, channel2** of **SCI is connected to CN8 via USB-serial conversion chip, enabling UART communication between RX72N and PC via CN8 connector.
    • On the above circuit, CN8 can be connected to ESP32(WiFi module) according to SW3 setting.
      • This is a mechanism of updating ESP32 firmware and writing SSL certificate of the connection destination.
      • During regular system operation, without using this function, set SW3 to connect RX72N and CN8.
      • If you suspect that RX72N is not connected to CN8, check SW3 setting.
        • If SW3-2 is turned off, RX72N and CN8 are connected.
        • If SW3-2 is turned on, ESP32 are CN8 connected.
      • Besides, RX72N and ESP32 are connected with P30/RXD1, P26/TXD1, P31/CTS1# and P27_RTS# and have another process to write SSL certificate.
        • That is to say, except when ESP32 firmware is updated or SSL certificate is written, turn off SW3-2
      • For the application of ESP32, refer to ESP32 application page.

Set SCI driver software with Smart Configurator

Add component

    • Add two components as shown above.
      • r_sci_rx (As described in the above screenshot)
      • r_byteq *If r_sci_rx is not displayed, select "Basic setting" in " Select software component" window and check "display all FIT modules".

Set component

r_sci_rx

  • Perform SCI related settings (Use UART and SCI channel2)

    • Set Use ASYNC mode to Include(Select Synchronous mode(UART)), and set Include software support for channel 1 to Not, and set Include software support for channel 2 to Include.
  • Set to use SCI related pins (Use TXD2 of SC12 and RXD2)

r_byteq

  • None

r_bsp

  • Since UART transmit/receipt is used in more common c language software interface, (printf(), scanf(), etc.), change the input /output destination of the standard library with r_bsp.
    • Executing printf() with the software on PC leads to "printf()→C language standard library→"Text string is displayed on PC screen"
    • Executing printf() with the software on RX MCU leads to "printf()→C language standard library→Call charput() function of lowlvl.c within r_bsp →Output debug report of E1/E2 emulator" *As a result, printf() data reaches Renesas Debug Virtual Console window of e2 studio.
    • Default setting inputs/outputs via the interface of E1/E2 debugger as described above.
    • You can set to default when connecting debugger, when operating actual machine stand-alone (with debugger disconnected) there are many cases you want to connect actual machine with PC, too.
    • Perform the following setting with r_bsp
    • Performing the above setting will shift printf() data transmision process "printf()→C language standard library→Call charput() function of owlvl.c within r_bsp→my_sw_charput_function()"
    • The users can elaborate my_sw_charput_function() installment freely.
    • In RX72N Envision Kit, by installing my_sw_charput_function() with transmit function of UART mode of SCI channel2, connects the output of printf() to CN8, enabling communication between PC and UART.
    • Data output process of printf() this time is "printf()→C language standard library→Call charput() function of lowlvl.c within r_bsp→my_sw_charput_function()→R_SCI_Send(channel2, ...)->SCI2(TXD2) -> P13 -> CN8 -> USB cable -> PC(COM port) -> PC(Tera Term, etc.)"

Pin setting

    • Since RX72N MCU assigns multiple functions to one pin, it is necessary to perform the setting of which function should be used.
    • In RX72N Envision Kit, SCI performs UART control with two of P13(<-TXD2) and P12(<-RXD2).
    • Perform pin setting on Smart Configurator as described above and generate code as described above.
    • By reading board configuration file (BDF), "pin setting" on Smart Configurator is automated.

TeraTerm setting

Coding of main() function(In case of only transmission side)

  • Add code to rx72n_envision_kit.c as described below.
  • In this code output printf() to SCI channel2.
  • Installment of my_sw_charput_function() is "check transmission buffer is empty→Execute transmission→Exit without waiting for transmission completion"
  • Please note that all software execution other than interrupt processing is blocked during printf() execution.
  • To avoid this, directly handle R_SCI_Send() and callback(sci_callback) or use real time OS.
  • Assuming that the above mentioned is understood, printf() is used.
#include <stdio.h>

#include "r_smc_entry.h"
#include "platform.h"
#include "r_cmt_rx_if.h"
#include "r_sci_rx_if.h"

#include "Pin.h"
#include "r_sci_rx_pinset.h"

void main(void);
void cmt_callback(void *arg);
void sci_callback(void *arg);
void my_sw_charput_function(char *data);
char my_sw_charget_function(void);

static sci_hdl_t sci_handle;

void main(void)
{
    uint32_t cmt_channel;
    R_CMT_CreatePeriodic(10, cmt_callback, &cmt_channel);
    sci_cfg_t   my_sci_config;

    /* Set up the configuration data structure for asynchronous (UART) operation. */
    my_sci_config.async.baud_rate    = 115200;
    my_sci_config.async.clk_src      = SCI_CLK_INT;
    my_sci_config.async.data_size    = SCI_DATA_8BIT;
    my_sci_config.async.parity_en    = SCI_PARITY_OFF;
    my_sci_config.async.parity_type  = SCI_EVEN_PARITY;
    my_sci_config.async.stop_bits    = SCI_STOPBITS_1;
    my_sci_config.async.int_priority = 15; /* disable 0 - low 1 - 15 high */

    R_Pins_Create();
    R_SCI_Open(SCI_CH2, SCI_MODE_ASYNC, &my_sci_config, sci_callback, &sci_handle);
    R_SCI_PinSet_SCI2();

    printf("Hello World\n");

    while(1);
}

void cmt_callback(void *arg)
{
	if(PORT4.PIDR.BIT.B0 == 1)
	{
		PORT4.PODR.BIT.B0 = 0;
	}
	else
	{
		PORT4.PODR.BIT.B0 = 1;
	}
}

void sci_callback(void *arg)
{

}

void my_sw_charput_function(char *data)
{
    uint32_t arg = 0;
    /* do not call printf()->charput in interrupt context */
    do
    {
        R_SCI_Control(sci_handle, SCI_CMD_TX_Q_BYTES_FREE, (void*)&arg);
    }
    while (SCI_CFG_CH2_TX_BUFSIZ != arg);
    R_SCI_Send(sci_handle, (uint8_t*)&data, 1);
}

char my_sw_charget_function(void)
{
	return 0;
}

Coding of main() function (In case of aiming command response-style operation utilizing transmit/receipt)

  • Add code to rx72n_envision_kit.c as described bellow. *In this code, receive the input from SC12 with SCI2 interrupt by 1 byte, and when receiving a line feed code, set global variable flag to ON to detect on main() side.
  • Installment of my_sw_charget_function() shows "there is not any"
  • It can be described "enable to install my_sw_charget_function() and use scanf() and so on", however, in that case scanf() constantly waits for a input from users, therefore, when real time OS is not used, other software can never be moved. Accordingly, in this case it is not installed.
  • The installment here is when entering command, "hello", "Hello World" is returned as response
  • Because of sscanf() within main(), command and argument are stored in command variable and arg1 ~ arg4 respectively.
  • Command variable is passed to get_command_code() and converted to the constant value to be sifted out in switch-case.
  • To add a command, you can expand get_command_code() function and then expand switch-case in main()
#include <stdio.h>
#include <string.h>

#include "r_smc_entry.h"
#include "platform.h"
#include "r_cmt_rx_if.h"
#include "r_sci_rx_if.h"

#include "Pin.h"
#include "r_sci_rx_pinset.h"

#define COMMAND_UNKNOWN -1
#define COMMAND_HELLO 1

#define PROMPT "\nRX72N Envision Kit\n$ "

void main(void);
void cmt_callback(void *arg);
void sci_callback(void *arg);
void my_sw_charput_function(char *data);
char my_sw_charget_function(void);

static int32_t get_command_code(uint8_t *command);

static sci_hdl_t sci_handle;
static uint8_t sci_buffer[4096];
static uint8_t command[256];
static uint8_t arg1[256];
static uint8_t arg2[256];
static uint8_t arg3[256];
static uint8_t arg4[256];
static uint32_t sci_current_received_size;

static volatile uint32_t sci_command_received_flag;

void main(void)
{
    uint32_t cmt_channel;
    R_CMT_CreatePeriodic(10, cmt_callback, &cmt_channel);
    sci_cfg_t   my_sci_config;

    /* Set up the configuration data structure for asynchronous (UART) operation. */
    my_sci_config.async.baud_rate    = 115200;
    my_sci_config.async.clk_src      = SCI_CLK_INT;
    my_sci_config.async.data_size    = SCI_DATA_8BIT;
    my_sci_config.async.parity_en    = SCI_PARITY_OFF;
    my_sci_config.async.parity_type  = SCI_EVEN_PARITY;
    my_sci_config.async.stop_bits    = SCI_STOPBITS_1;
    my_sci_config.async.int_priority = 15; /* disable 0 - low 1 - 15 high */

    R_Pins_Create();
    R_SCI_Open(SCI_CH2, SCI_MODE_ASYNC, &my_sci_config, sci_callback, &sci_handle);
    R_SCI_PinSet_SCI2();

    printf("%s", PROMPT);
    while(1)
    {
        while(sci_command_received_flag)
        {
            if ( 0 != sscanf((char*)sci_buffer, "%256s %256s %256s %256s %256s", command, arg1, arg2, arg3, arg4))
            {
                switch(get_command_code(command))
                {
                    case COMMAND_HELLO:
                        printf("Hello World.\n");
                        break;
                    default:
                        printf("Command not found.\n");
                        break;
                }
            }
            sci_command_received_flag = 0;
            printf("%s", PROMPT);
        }
    }
}

void cmt_callback(void *arg)
{
    if(PORT4.PIDR.BIT.B0 == 1)
    {
        PORT4.PODR.BIT.B0 = 0;
    }
    else
    {
        PORT4.PODR.BIT.B0 = 1;
    }
}

void sci_callback(void *arg)
{
    sci_cb_args_t   *p_args;

    p_args = (sci_cb_args_t *)arg;

    if (SCI_EVT_RX_CHAR == p_args->event)
    {
        R_SCI_Receive(p_args->hdl, &sci_buffer[sci_current_received_size], 1);
        R_SCI_Send(sci_handle, (uint8_t*)&sci_buffer[sci_current_received_size], 1);
        if(((char)sci_buffer[sci_current_received_size - 1] == '\r') && ((char)sci_buffer[sci_current_received_size] == '\n'))
        {
            sci_buffer[sci_current_received_size + 1] = 0;
            sci_command_received_flag = 1;
            sci_current_received_size = 0;
        }
        else if(sci_current_received_size == (sizeof(sci_buffer) - 1)) /* -1 means string terminator after "\n" */
        {
            sci_current_received_size = 0;
        }
        else
        {
            sci_current_received_size++;
        }
    }
}

void my_sw_charput_function(char *data)
{
    uint32_t arg = 0;
    /* do not call printf()->charput in interrupt context */
    do
    {
        R_SCI_Control(sci_handle, SCI_CMD_TX_Q_BYTES_FREE, (void*)&arg);
    }
    while (SCI_CFG_CH2_TX_BUFSIZ != arg);
    R_SCI_Send(sci_handle, (uint8_t*)&data, 1);
}

char my_sw_charget_function(void)
{
    return 0;
}

static int32_t get_command_code(uint8_t *command)
{
    int32_t return_code;

    if(!strcmp((char*)command, "hello"))
    {
        return_code = COMMAND_HELLO;
    }
    else
    {
        return_code = COMMAND_UNKNOWN;
    }
    return return_code;
}
⚠️ **GitHub.com Fallback** ⚠️