|
|
@@ -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
|