打印
[控制总线]

【EtherCAT开发】1、移植瑞萨官方EtherCAT IO例程到EtherKit开发板`

[复制链接]
329|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

[i=s] 本帖最后由 EPTmachine 于 2025-7-1 16:42 编辑 [/i]<br /> <br />

@21小跑堂 #申请原创#

1、硬件平台

EtherKit是瑞萨和RT-Thread联合推出的RZN2L开发板,芯片型号为R9A07G084M08GBG,带有EtherCAT从站控制器,可以作为EtherCAT从站控制芯片。以下为开发板的介绍页面。

https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/hw-board/rzn2l-etherkit/rzn2l-etherkit

2、官方EtherCAT IO工程

EtherCAT从站的IO控制是EtherCAT应用中的基础应用。RZN2L芯片有多款官方的开发板,开发板配置的例程可以作为应用开发的参考。CN032-GATEWAYREFZ RZ/N2L 远程 I/O 解决方案套件的链接如下。

https://www.renesas.cn/zh/design-resources/boards-kits/cn032-gatewayrefz#overview

在开发板的介绍页面可以下载示例程序以及使用说明。

demo_code.png

3、例程移植

基于fsp_rzn_v2.2.0移植官方的Remote IO例程到EtherKit开发板上。完成移植需要:

  • EtherKit开发板
  • Jlink调试器
  • 官方示例工程

RTThread为EtherKit开发板提供有不同的开发例程,工程中有RZN2L的引脚的配置,导出RT_Thread官方例程中引脚配置,用于在新的工程中配置芯片引脚。打开工程中的FSP工程配置文件,在Pins选项卡中导出引脚的配置文件,方便后续开发中的引脚配置。

3.1 工程创建以及外设配置

开发环境选择e2studio,fsp版本选择v2.0.0(使用v2.2.0也可以,可以移植成功),参考下载的示例工程说明书进行工程的移植。

demo_document_code.png

在e2studio中创建RZ/N芯片工程

RZ_project_create1.png

RZ_project_create2.png

指定工程名称

RZ_project_create3.png

选择开发板类型、启动方式、芯片型号以及编译器

RZ_project_create4.png

选择编译输出结果类型以及RTOS

RZ_project_create5.png

选择工程模板

RZ_project_create6.png

工程创建完成后,打开其中的configuration.xml文件进入FSP配置界面。

project_config1.png

在FSP配置界面中导入之前导出的EtherKit开发板的引脚配置,

import_pin_cfg.png

以这种方式导入到e2studio中,在生成代码时会出现配置变量重定义的错误,将原有的引脚配置删除掉。

delete_default_pincfg.png

在Stacks界面中的“NetWorking”一栏中添加EtherCAT从站的驱动,修改其中的默认参数。

ssc_config1.png

EtherKit开发板的网卡芯片为RTL8211F,设置用户自定义的驱动,并设置控制其的网络控制器通道以及定义初始化函数名称。

ssc_config2.png

修改网络控制器的配置模式

ssc_config3.png

同样地,修改网络控制器1的配置信息如下

ssc_config4.png

ssc_config5.png

添加用于周期控制的定时器,并设置定时器的中断优先级。

ssc_config6.png

完成配置后保存并生成代码。

3.2 生成从站代码、修改应用程序

根据示例程序的说明,需要使用SSC V5.13工程生成从站的EtherCAT代码。打开SSC工具,创建新的工程

SSC_Code1.png

导入示例工程中SSC配置文件

SSC_Code2.png

SSC_Code3.png

生成相应的EtherCAT从站配置代码。

SSC_Code4.png

SSC_Code5.png

示例程序中配套有相应的代码,由于使用的硬件不同,在移植时只需要其中的src文件夹下的代码即可。

demo_port1.png

demo_port2.png

在工程中添加"ETHERCAT_SSC_PORT_GMAC_MDIO_SUPPORT=1"宏定义以及相关的文件路径。

demo_port3.png

demo_port4.png

同时添加网卡接口芯片的初始化函数如下

void phy_rtl8211f_initial(ether_phy_instance_ctrl_t *phydev)
{
#define RTL_8211F_PAGE_SELECT 0x1F
#define RTL_8211F_EEELCR_ADDR 0x11
#define RTL_8211F_LED_PAGE 0xD04
#define RTL_8211F_LCR_ADDR 0x10

    uint32_t val1, val2 = 0;

    /* switch to led page */
    R_ETHER_PHY_Write(phydev, RTL_8211F_PAGE_SELECT, RTL_8211F_LED_PAGE);

    /* set led1(green) Link 10/100/1000M, and set led2(yellow) Link 10/100/1000M+Active */
    R_ETHER_PHY_Read(phydev, RTL_8211F_LCR_ADDR, &val1);
    val1 |= (1 << 5);
    val1 |= (1 << 8);
    val1 &= (uint32_t)(~(1 << 9));
    val1 |= (1 << 10);
    val1 |= (1 << 11);
    R_ETHER_PHY_Write(phydev, RTL_8211F_LCR_ADDR, val1);

    /* set led1(green) EEE LED function disabled so it can keep on when linked */
    R_ETHER_PHY_Read(phydev, RTL_8211F_EEELCR_ADDR, &val2);
    val2 &=  (uint32_t)(~(1 << 2));
    R_ETHER_PHY_Write(phydev, RTL_8211F_EEELCR_ADDR, val2);

    /* switch back to page0 */
    R_ETHER_PHY_Write(phydev, RTL_8211F_PAGE_SELECT, 0xa42);

    R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);

    return;
}

根据示例说明书,为了可以正常调试,需要在代码的 system_init函数中添加延时代码,添加的位置如下。

demo_port5.png

具体的代码为

#if 1
    __asm volatile (
        "    mov   r0, #0                               \n"
        "    movw  r1, #0xf07f                    \n"
        "    movt  r1, #0x2fa                        \n"
        "software_loop:                              \n"
        "    adds  r0, #1                                 \n"
        "    cmp   r0, r1                                 \n"
        "    bne   software_loop                  \n"
        ::: "memory");
#endif

由于硬件存在差异,控制从站IO引脚和数量不同,需要修改应用程序中的部分代码。

demo_port6.png

具体有以下几处: sampleios.c中修改IO控制的引脚

#if defined(BOARD_RZN2L_Gateway)
/** Array of DIP SW IOPORT pins. */
static const uint16_t g_sample_prv_dip_sws[] =
{
    (UINT16) BSP_IO_PORT_14_PIN_2, // SW2-1
    (UINT16) BSP_IO_PORT_16_PIN_3, // SW2-2
};
/** Array of LED IOPORT pins. */
static const uint16_t g_sample_prv_leds[] =
{
    (uint16_t) BSP_IO_PORT_14_PIN_0,   ///< RLED0 GREEN
    (uint16_t) BSP_IO_PORT_14_PIN_1,   ///< RLED1 GREEN
    (uint16_t) BSP_IO_PORT_14_PIN_3,   ///< RLED2 GREEN
};
#endif

simpleapp.c中注释掉未定义的IO控制函数调用。

void APPL_SetLed(UINT16 value)
{
    /* LED type structure */
    sample_leds_t leds = g_sample_leds;

    /* Holds level to set for pins */
    bsp_io_level_t pin_level[4];

    /* This code uses BSP IO functions to show how it is used.*/
    R_BSP_PinAccessEnable();
#if defined(BOARD_RZN2L_Gateway)
    pin_level[SAMPLE_LED_RLED0] = ((value & 1) ?  BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH);
    pin_level[SAMPLE_LED_RLED1] = ((value & 2) ?  BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH);
    pin_level[SAMPLE_LED_RLED2] = ((value & 4) ?  BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH);
//    pin_level[SAMPLE_LED_RLED3] = ((value & 8) ?  BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH);
#else
    pin_level[SAMPLE_LED_RLED0] = ((value & 1) ?  BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW);
    pin_level[SAMPLE_LED_RLED1] = ((value & 2) ?  BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW);
    pin_level[SAMPLE_LED_RLED2] = ((value & 4) ?  BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW);
    pin_level[SAMPLE_LED_RLED3] = ((value & 8) ?  BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW);
#endif
    R_IOPORT_PinWrite(&g_ioport_ctrl, (bsp_io_port_pin_t)leds.p_leds[SAMPLE_LED_RLED0], pin_level[SAMPLE_LED_RLED0]);
    R_IOPORT_PinWrite(&g_ioport_ctrl, (bsp_io_port_pin_t)leds.p_leds[SAMPLE_LED_RLED1], pin_level[SAMPLE_LED_RLED1]);
    R_IOPORT_PinWrite(&g_ioport_ctrl, (bsp_io_port_pin_t)leds.p_leds[SAMPLE_LED_RLED2], pin_level[SAMPLE_LED_RLED2]);
//    R_IOPORT_PinWrite(&g_ioport_ctrl, (bsp_io_port_pin_t)leds.p_leds[SAMPLE_LED_RLED3], pin_level[SAMPLE_LED_RLED3]);

    /* Protect PFS registers */
    R_BSP_PinAccessDisable();
}
/////////////////////////////////////////////////////////////////////////////////////////
/**
 \retuen   UINT16 DIP SW value. Low input level means ON.

 \brief    Get DIP SW
*////////////////////////////////////////////////////////////////////////////////////////
UINT16 APPL_GetDipSw(void)
{
    UINT16 u16DipSw;

    u16DipSw = 0;

    /* DIP SW type structure */
    sample_dip_sws_t dipsws = g_sample_dip_sws;

    /* This code uses BSP IO functions to show how it is used.*/
    R_BSP_PinAccessEnable();

    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_0]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_0]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x01;
    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_1]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_1]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x02;
//    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_2]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_2]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x04;
//    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_3]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_3]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x08;

#if defined(BOARD_RZT2M_RSK)
    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_4]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_4]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x10;
    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_5]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_5]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x20;
    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_6]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_6]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x40;
    if (R_BSP_FastPinRead(R_BSP_IoRegionGet((bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_7]), (bsp_io_port_pin_t)dipsws.p_sws[SAMPLE_DIPSW_7]) == BSP_IO_LEVEL_LOW) u16DipSw |= 0x80;
#endif

    /* Protect PFS registers */
    R_BSP_PinAccessDisable();

    return u16DipSw;
}

至此,示例工程的移植完成,编译正常通过后,即可下载到开发板进行调试。可用的工程可以参考附件工程。

4、程序运行

示例工程使用TWinCAT作为EtherCAT主站来控制从站。将示例代码中的从站配置文件复制到TWinCAT的EtherCAT目录中。

demo_Run_1.png

参考示例使用说明中的更新从站的EEPROM,详细的过程说明可以参考说明文档。

demo_Run_2.png

从站运行后,通过控制开发板上的按键,可以改变EtherCAT PDO Input的数据。

demo_Run_3.png

5、总结

EtherKit开发板的芯片是瑞萨RZN2L,瑞萨官方提供不同的开发板和例程,配套有具体的使用说明,在此基础上稍加修改即可移植EtherCAT应用代码,作为EtherCAT应用的一个参考。

upload 附件:RZN2L_etherkit_esc_io.zip

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

483

帖子

4

粉丝