Quellcode durchsuchen

feat(port): add ra8p1 support

Signed-off-by: sakumisu <1203593632@qq.com>
sakumisu vor 1 Monat
Ursprung
Commit
06f9c0898a
3 geänderte Dateien mit 215 neuen und 63 gelöschten Zeilen
  1. 1 1
      README.md
  2. 1 1
      README_zh.md
  3. 213 61
      port/netdev_renesas.c

+ 1 - 1
README.md

@@ -104,7 +104,7 @@ Generating C code...
 ## Support Boards
 
 - HPM6750EVK2/HPM6800EVK/**HPM5E00EVK**(hybrid internal)
-- RT-Thread RZN2L-EtherKit
+- RT-Thread RZN2L-EtherKit/RA8P1 Titan Board
 
 ## Contact
 

+ 1 - 1
README_zh.md

@@ -104,7 +104,7 @@ Generating C code...
 ## 支持的开发板
 
 - HPM6750EVK2/HPM6800EVK/**HPM5E00EVK**(hybrid internal)
-- RT-Thread RZN2L-EtherKit
+- RT-Thread RZN2L-EtherKit/RA8P1 Titan Board
 
 ## 联系
 

+ 213 - 61
port/netdev_renesas.c

@@ -8,22 +8,95 @@
 #include "ec_master.h"
 
 ec_netdev_t g_netdev;
+#if !defined(SOC_SERIES_R7KA8P1) && !defined(SOC_SERIES_R9A07G0)
+#error "Ethercat master only supports for R7KA8P1 and RZN2L"
+#endif
 
-#if defined(BSP_MCU_GROUP_RZT2M) || defined(BSP_MCU_GROUP_RZN2L)
-#define ETHER_BUFFER_PLACE_IN_SECTION BSP_PLACE_IN_SECTION(".noncache_buffer.eth")
-#else
-#define ETHER_BUFFER_PLACE_IN_SECTION
+#if !defined(CONFIG_EC_PHY_CUSTOM)
+#error "CONFIG_EC_PHY_CUSTOM must be defined for Renesas MCUs"
 #endif
 
-__attribute__((__aligned__(32))) uint8_t tx_buffer[CONFIG_EC_MAX_ENET_TXBUF_COUNT][1536] ETHER_BUFFER_PLACE_IN_SECTION;
+#if defined(SOC_SERIES_R7KA8P1)
+#define ETHER_BUFFER_PLACE_IN_SECTION BSP_PLACE_IN_SECTION(".ram_nocache")
 
-extern uint32_t SystemCoreClock;
+#define ETHER_EVENT_INTERRUPT ETHER_EVENT_RX_COMPLETE
 
-#define PING_PORT_COUNT (3) ///< Count of port
+#define R_ETHER_Open          R_RMAC_Open
+#define R_ETHER_Write         R_RMAC_Write
+#define R_ETHER_Read          R_RMAC_Read
+#define R_ETHER_LinkProcess   R_RMAC_LinkProcess
+#define R_ETHER_BufferRelease R_RMAC_BufferRelease
 
-static uint8_t g_link_change = 0; ///< Link change (bit0:port0, bit1:port1, bit2:port2)
-static uint8_t g_link_status = 0; ///< Link status (bit0:port0, bit1:port1, bit2:port2)
-static uint8_t previous_link_status = 0;
+void rmac_phy_target_rtl8211_initialize(rmac_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_RMAC_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_RMAC_PHY_Read(phydev, RTL_8211F_LCR_ADDR, &val1);
+    val1 |= (1 << 5);
+    val1 |= (1 << 8);
+    val1 &= (~(1 << 9));
+    val1 |= (1 << 10);
+    val1 |= (1 << 11);
+    R_RMAC_PHY_Write(phydev, RTL_8211F_LCR_ADDR, val1);
+
+    /* set led1(green) EEE LED function disabled so it can keep on when linked */
+    R_RMAC_PHY_Read(phydev, RTL_8211F_EEELCR_ADDR, &val2);
+    val2 &= (~(1 << 2));
+    R_RMAC_PHY_Write(phydev, RTL_8211F_EEELCR_ADDR, val2);
+
+    /* switch back to page0 */
+    R_RMAC_PHY_Write(phydev, RTL_8211F_PAGE_SELECT, 0xa42);
+}
+
+bool rmac_phy_target_rtl8211_is_support_link_partner_ability(rmac_phy_instance_ctrl_t *p_instance_ctrl,
+                                                             uint32_t line_speed_duplex)
+{
+    FSP_PARAMETER_NOT_USED(p_instance_ctrl);
+    FSP_PARAMETER_NOT_USED(line_speed_duplex);
+
+    /* This PHY-LSI supports half and full duplex mode. */
+    return true;
+}
+
+/* Multi-PHY support structures */
+typedef struct {
+    rmac_phy_instance_ctrl_t *p_ctrl;
+    uint8_t port_bit;
+    const char *name;
+} phy_port_info_t;
+
+static const phy_port_info_t phy_ports[] = {
+    { &g_rmac_phy0_ctrl, 0x01, "PHY0" },
+    { &g_rmac_phy1_ctrl, 0x02, "PHY1" }
+};
+
+#define PHY_PORTS_COUNT (sizeof(phy_ports) / sizeof(phy_ports[0]))
+
+#elif defined(SOC_SERIES_R9A07G0)
+
+#if !defined(CONFIG_EC_TIMESTAMP_CUSTOM)
+#error "CONFIG_EC_TIMESTAMP_CUSTOM must be defined for R9A07G0"
+#endif
+
+#define ETHER_BUFFER_PLACE_IN_SECTION BSP_PLACE_IN_SECTION(".noncache_buffer.eth")
+
+#define status_ecsr           status_link
+#define ETHER_EVENT_INTERRUPT ETHER_EVENT_SBD_INTERRUPT
+
+#define R_ETHER_Open          R_GMAC_Open
+#define R_ETHER_Write         R_GMAC_Write
+#define R_ETHER_Read          R_GMAC_Read
+#define R_ETHER_LinkProcess   R_GMAC_LinkProcess
+#define R_ETHER_BufferRelease R_GMAC_BufferRelease
 
 static int phy_rtl8211f_led_fixup(ether_phy_instance_ctrl_t *phydev)
 {
@@ -63,13 +136,31 @@ void ether_phy_targets_initialize_rtl8211_rgmii(ether_phy_instance_ctrl_t *p_ins
     phy_rtl8211f_led_fixup(p_instance_ctrl);
 }
 
+#define PHY_PORTS_COUNT (3) ///< Count of port
+
+#endif
+
+__attribute__((__aligned__(32))) uint8_t tx_buffer[CONFIG_EC_MAX_ENET_TXBUF_COUNT][1536] ETHER_BUFFER_PLACE_IN_SECTION;
+
+extern uint32_t SystemCoreClock;
+
+static uint8_t g_link_change = 0; ///< Link change (bit0:port0, bit1:port1, bit2:port2)
+static uint8_t g_link_status = 0; ///< Link status (bit0:port0, bit1:port1, bit2:port2)
+static uint8_t previous_link_status = 0;
+
 ec_netdev_t *ec_netdev_low_level_init(uint8_t netdev_index)
 {
     fsp_err_t res;
 
     EC_ASSERT_MSG(g_ether0_cfg.zerocopy == ETHER_ZEROCOPY_ENABLE, "zerocopy must be enabled");
-
-    res = R_GMAC_Open(&g_ether0_ctrl, &g_ether0_cfg);
+    EC_ASSERT_MSG(g_ether0_cfg.multicast == ETHER_MULTICAST_DISABLE, "multicast must be disabled");
+    EC_ASSERT_MSG(g_ether0_cfg.promiscuous == ETHER_PROMISCUOUS_ENABLE, "promiscuous must be enabled");
+    EC_ASSERT_MSG(g_ether0_cfg.num_tx_descriptors == CONFIG_EC_MAX_ENET_TXBUF_COUNT, "num_tx_descriptors must be the same as \
+        CONFIG_EC_MAX_ENET_TXBUF_COUNT");
+    EC_ASSERT_MSG(g_ether0_cfg.num_rx_descriptors == CONFIG_EC_MAX_ENET_RXBUF_COUNT, "num_rx_descriptors must be the same as \
+        CONFIG_EC_MAX_ENET_RXBUF_COUNT");
+
+    res = R_ETHER_Open(&g_ether0_ctrl, &g_ether0_cfg);
     if (res != FSP_SUCCESS)
         EC_LOG_ERR("R_ETHER_Open failed!, res = %d", res);
 
@@ -85,9 +176,69 @@ ec_netdev_t *ec_netdev_low_level_init(uint8_t netdev_index)
         EC_WRITE_U16(&tx_buffer[i][12], ec_htons(0x88a4));
     }
 
+    res = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
+    if (res != FSP_SUCCESS) {
+        EC_LOG_ERR("R_GPT_Open failed!, res = %d", res);
+    }
+
     return &g_netdev;
 }
 
+#if defined(SOC_SERIES_R7KA8P1)
+void ec_netdev_low_level_poll_link_state(ec_netdev_t *netdev)
+{
+    fsp_err_t res;
+    uint8_t port;
+    uint8_t port_bit;
+    uint8_t status_change;
+    uint32_t phy_data;
+    uint8_t current_link_status = 0;
+    uint8_t i;
+
+    res = R_ETHER_LinkProcess(&g_ether0_ctrl);
+
+    /* Check link status for all PHY ports */
+    for (i = 0; i < PHY_PORTS_COUNT; i++) {
+        res = R_RMAC_PHY_Read(phy_ports[i].p_ctrl, 0x1, &phy_data);
+        if (res == FSP_SUCCESS) {
+            if (phy_data & 0x04) /* PHY Basic Status Register Link Status bit */
+            {
+                current_link_status |= phy_ports[i].port_bit; /* Port link up */
+            }
+
+            status_change = previous_link_status ^ current_link_status;
+            if (status_change & phy_ports[i].port_bit) {
+                g_link_change |= phy_ports[i].port_bit;
+            }
+        } else {
+            EC_LOG_ERR("%s PHY_Read failed!, res = %d", phy_ports[i].name, res);
+        }
+    }
+
+    /* Update global link status */
+    g_link_status = current_link_status;
+
+    /* Process link changes for all ports */
+    for (port = 0; port < PHY_PORTS_COUNT; port++) {
+        port_bit = phy_ports[port].port_bit;
+
+        if (g_link_change & port_bit) {
+            /* Link status changed */
+            g_link_change &= (uint8_t)(~port_bit); /* change bit clear */
+
+            if (g_link_status & port_bit) {
+                /* Changed to Link-up */
+                netdev->link_state = true;
+            } else {
+                /* Changed to Link-down */
+                netdev->link_state = false;
+            }
+        }
+    }
+
+    previous_link_status = g_link_status;
+}
+#elif defined(SOC_SERIES_R9A07G0)
 void ec_netdev_low_level_poll_link_state(ec_netdev_t *netdev)
 {
     fsp_err_t res;
@@ -96,11 +247,9 @@ void ec_netdev_low_level_poll_link_state(ec_netdev_t *netdev)
     uint8_t port_bit = 0;
 
     res = R_GMAC_LinkProcess(&g_ether0_ctrl);
-    if (res != FSP_SUCCESS)
-        EC_LOG_ERR("R_ETHER_LinkProcess failed!, res = %d", res);
 
     if (0 == g_ether0.p_cfg->p_callback) {
-        for (port = 0; port < PING_PORT_COUNT; port++) {
+        for (port = 0; port < PHY_PORTS_COUNT; port++) {
             res = R_GMAC_GetLinkStatus(&g_ether0_ctrl, port, &port_status);
             if (FSP_SUCCESS != res) {
                 /* An error has occurred */
@@ -122,7 +271,7 @@ void ec_netdev_low_level_poll_link_state(ec_netdev_t *netdev)
     previous_link_status = g_link_status;
 
     if (FSP_SUCCESS == res) {
-        for (port = 0; port < PING_PORT_COUNT; port++) {
+        for (port = 0; port < PHY_PORTS_COUNT; port++) {
             port_bit = (uint8_t)(1U << port);
 
             if (g_link_change & port_bit) {
@@ -140,6 +289,7 @@ void ec_netdev_low_level_poll_link_state(ec_netdev_t *netdev)
         }
     }
 }
+#endif
 
 EC_FAST_CODE_SECTION uint8_t *ec_netdev_low_level_get_txbuf(ec_netdev_t *netdev)
 {
@@ -150,7 +300,7 @@ EC_FAST_CODE_SECTION int ec_netdev_low_level_output(ec_netdev_t *netdev, uint32_
 {
     fsp_err_t res;
 
-    res = R_GMAC_Write(&g_ether0_ctrl, tx_buffer[netdev->tx_frame_index], size);
+    res = R_ETHER_Write(&g_ether0_ctrl, tx_buffer[netdev->tx_frame_index], size);
     if (res != FSP_SUCCESS) {
         return -1;
     }
@@ -167,14 +317,14 @@ EC_FAST_CODE_SECTION int ec_netdev_low_level_input(ec_netdev_t *netdev)
     uint8_t *buffer;
     uint32_t len = 0;
 
-    res = R_GMAC_Read(&g_ether0_ctrl, (void *)&buffer, &len);
+    res = R_ETHER_Read(&g_ether0_ctrl, (void *)&buffer, &len);
     if (res != FSP_SUCCESS) {
         return -1;
     }
 
     ec_netdev_receive(netdev, buffer, len);
 
-    R_GMAC_BufferRelease(&g_ether0_ctrl);
+    R_ETHER_BufferRelease(&g_ether0_ctrl);
 
     return 0;
 }
@@ -196,18 +346,20 @@ void timer0_esc_callback(timer_callback_args_t *p_args)
 void ec_htimer_start(uint32_t us, ec_htimer_cb cb, void *arg)
 {
     fsp_err_t fsp_err = FSP_SUCCESS;
-    uint32_t count = us * (SystemCoreClock / 1000000); // 400MHz, 1us = 400 ticks
+    timer_info_t time_info;
+
+    R_GPT_InfoGet(&g_timer0_ctrl, &time_info);
+    uint32_t count = us * (time_info.clock_frequency / 1000000);
 
     g_ec_htimer_cb = cb;
     g_ec_htimer_arg = arg;
 
-    fsp_err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
     fsp_err |= R_GPT_CounterSet(&g_timer0_ctrl, 0);
     fsp_err |= R_GPT_PeriodSet(&g_timer0_ctrl, count);
     fsp_err |= R_GPT_Start(&g_timer0_ctrl);
 
     if (fsp_err != FSP_SUCCESS) {
-        EC_LOG_ERR("R_GPT_Open failed!, res = %d", fsp_err);
+        EC_LOG_ERR("ec_htimer_start failed!, res = %d", fsp_err);
     }
 }
 
@@ -216,6 +368,44 @@ void ec_htimer_stop(void)
     R_GPT_Stop(&g_timer0_ctrl);
 }
 
+void user_ether0_callback(ether_callback_args_t *p_args)
+{
+    rt_interrupt_enter();
+
+    switch (p_args->event) {
+        case ETHER_EVENT_LINK_ON:                          ///< Link up detection event/
+            g_link_status |= (uint8_t)p_args->status_ecsr; ///< status up
+            g_link_change |= (uint8_t)p_args->status_ecsr; ///< change bit set
+            break;
+
+        case ETHER_EVENT_LINK_OFF:                            ///< Link down detection event
+            g_link_status &= (uint8_t)(~p_args->status_ecsr); ///< status down
+            g_link_change |= (uint8_t)p_args->status_ecsr;    ///< change bit set
+            break;
+
+        case ETHER_EVENT_WAKEON_LAN: ///< Magic packet detection event
+        /* If EDMAC FR (Frame Receive Event) or FDE (Receive Descriptor Empty Event)
+        * interrupt occurs, send rx mailbox. */
+        case ETHER_EVENT_INTERRUPT: ///< BSD Interrupt event
+        {
+            while (ec_netdev_low_level_input(&g_netdev) == 0) {
+            }
+            break;
+        }
+
+        default:
+            break;
+    }
+
+    rt_interrupt_leave();
+}
+
+uint32_t ec_get_cpu_frequency(void)
+{
+    return SystemCoreClock;
+}
+
+#if defined(SOC_SERIES_R9A07G0)
 volatile uint64_t mtu3_overflow_count = 0;
 
 void g_mtu3_callback(timer_callback_args_t *p_args)
@@ -263,42 +453,4 @@ EC_FAST_CODE_SECTION uint64_t ec_timestamp_get_time_us(void)
 {
     return ec_timestamp_get_time_ns() / 1000ULL;
 }
-
-void user_ether0_callback(ether_callback_args_t *p_args)
-{
-    rt_interrupt_enter();
-
-    switch (p_args->event) {
-        case ETHER_EVENT_LINK_ON:                          ///< Link up detection event/
-            g_link_status |= (uint8_t)p_args->status_link; ///< status up
-            g_link_change |= (uint8_t)p_args->status_link; ///< change bit set
-            break;
-
-        case ETHER_EVENT_LINK_OFF:                            ///< Link down detection event
-            g_link_status &= (uint8_t)(~p_args->status_link); ///< status down
-            g_link_change |= (uint8_t)p_args->status_link;    ///< change bit set
-            break;
-
-        case ETHER_EVENT_WAKEON_LAN: ///< Magic packet detection event
-        /* If EDMAC FR (Frame Receive Event) or FDE (Receive Descriptor Empty Event)
-         * interrupt occurs, send rx mailbox. */
-        case ETHER_EVENT_SBD_INTERRUPT: ///< BSD Interrupt event
-        {
-            while (ec_netdev_low_level_input(&g_netdev) == 0) {
-            }
-            break;
-        }
-        case ETHER_EVENT_PMT_INTERRUPT: ///< PMT Interrupt event
-            break;
-
-        default:
-            break;
-    }
-
-    rt_interrupt_leave();
-}
-
-uint32_t ec_get_cpu_frequency(void)
-{
-    return SystemCoreClock;
-}
+#endif