You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2022/09/29 19:12:11 UTC

[mynewt-core] 02/02: driver/pic32_eth: Add shell for ETH driver

This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 412af822ca0e0e1d641fcee72e49d9656eb5b341
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Mon Sep 26 23:25:23 2022 +0200

    driver/pic32_eth: Add shell for ETH driver
    
    Some basic commands to dump registers and
    see stats of ETH peripheral
---
 hw/drivers/lwip/pic32_eth/pkg.yml               |   3 +
 hw/drivers/lwip/pic32_eth/src/pic32_eth_shell.c | 309 ++++++++++++++++++++++++
 hw/drivers/lwip/pic32_eth/syscfg.yml            |   4 +
 3 files changed, 316 insertions(+)

diff --git a/hw/drivers/lwip/pic32_eth/pkg.yml b/hw/drivers/lwip/pic32_eth/pkg.yml
index e2c1ed794..43ab1781d 100644
--- a/hw/drivers/lwip/pic32_eth/pkg.yml
+++ b/hw/drivers/lwip/pic32_eth/pkg.yml
@@ -30,3 +30,6 @@ pkg.req_apis:
 
 pkg.init:
     pic32_eth_open: 'MYNEWT_VAL(PIC32_ETH_SYSINIT_STAGE)'
+
+pkg.init.PIC32_ETH_SHELL:
+    pic32_eth_shell_register: 1001
diff --git a/hw/drivers/lwip/pic32_eth/src/pic32_eth_shell.c b/hw/drivers/lwip/pic32_eth/src/pic32_eth_shell.c
new file mode 100644
index 000000000..10c6a438d
--- /dev/null
+++ b/hw/drivers/lwip/pic32_eth/src/pic32_eth_shell.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2022 Jerzy Kasenberg
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "syscfg/syscfg.h"
+#include "lwip/netif.h"
+#include "lwip/dhcp.h"
+#include "mn_socket/mn_socket.h"
+#include "pic32_eth/pic32_eth_priv.h"
+#include "parse/parse.h"
+
+#if MYNEWT_VAL(PIC32_ETH_SHELL)
+
+#include <shell/shell.h>
+#include <console/console.h>
+#include <pic32_eth/pic32_eth.h>
+
+static const struct shell_cmd_help pic32_eth_stats_help = {
+    .summary = "print eth stats counters",
+    .usage = "stats",
+    .params = NULL,
+};
+
+static const struct shell_cmd_help pic32_eth_phy_help = {
+    .summary = "read write phy registers",
+    .usage = "phy [0-31 [<reg_value]]",
+    .params = NULL,
+};
+
+static const struct shell_cmd_help pic32_eth_up_help = {
+    .summary = "turns eth interface on",
+    .usage = "up",
+    .params = NULL,
+};
+
+static const struct shell_cmd_help pic32_eth_down_help = {
+    .summary = "turns eth interface down",
+    .usage = "down",
+    .params = NULL,
+};
+
+static const struct shell_cmd_help pic32_eth_desc_help = {
+    .summary = "dump buffer descriptors",
+    .usage = "desc",
+    .params = NULL,
+};
+
+static const struct shell_cmd_help pic32_eth_dump_help = {
+    .summary = "dumps ETH registers",
+    .usage = "dump",
+    .params = NULL,
+};
+
+static int
+pic32_eth_down_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    (void)argc;
+    (void)argv;
+
+    struct netif *nif;
+    err_t err;
+
+    nif = netif_find("et1");
+    if (!nif) {
+        return MN_EINVAL;
+    }
+    if ((nif->flags & NETIF_FLAG_LINK_UP) == 0) {
+        dhcp_stop(nif);
+        netif_set_down(nif);
+    }
+    return 0;
+}
+
+static int
+pic32_eth_up_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    (void)argc;
+    (void)argv;
+
+    struct netif *nif;
+    err_t err;
+
+    nif = netif_find("et1");
+    if (!nif) {
+        return MN_EINVAL;
+    }
+    if (nif->flags & NETIF_FLAG_LINK_UP) {
+        netif_set_up(nif);
+        netif_set_default(nif);
+#if LWIP_IPV6
+        nif->ip6_autoconfig_enabled = 1;
+        netif_create_ip6_linklocal_address(nif, 1);
+#endif
+        err = dhcp_start(nif);
+        return err ? MN_EUNKNOWN : 0;
+    }
+    return 0;
+}
+
+static int
+pic32_eth_dump_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    (void)argc;
+    (void)argv;
+
+    streamer_printf(streamer, "   ETHCON1 0x%08" PRIx32 "\n", ETHCON1);
+    streamer_printf(streamer, "   ETHCON2 0x%08" PRIx32 "\n", ETHCON2);
+    streamer_printf(streamer, "   ETHTXST 0x%08" PRIx32 "\n", ETHTXST);
+    streamer_printf(streamer, "   ETHRXST 0x%08" PRIx32 "\n", ETHRXST);
+    streamer_printf(streamer, "    ETHHT0 0x%08" PRIx32 "\n", ETHHT0);
+    streamer_printf(streamer, "    ETHHT1 0x%08" PRIx32 "\n", ETHHT1);
+    streamer_printf(streamer, "   ETHPMM0 0x%08" PRIx32 "\n", ETHPMM0);
+    streamer_printf(streamer, "   ETHPMM1 0x%08" PRIx32 "\n", ETHPMM1);
+    streamer_printf(streamer, "   ETHPMCS 0x%08" PRIx32 "\n", ETHPMCS);
+    streamer_printf(streamer, "    ETHPMO 0x%08" PRIx32 "\n", ETHPMO);
+    streamer_printf(streamer, "   ETHRXFC 0x%08" PRIx32 "\n", ETHRXFC);
+    streamer_printf(streamer, "   ETHRXWM 0x%08" PRIx32 "\n", ETHRXWM);
+    streamer_printf(streamer, "    ETHIEN 0x%08" PRIx32 "\n", ETHIEN);
+    streamer_printf(streamer, "    ETHIRQ 0x%08" PRIx32 "\n", ETHIRQ);
+    streamer_printf(streamer, "   ETHSTAT 0x%08" PRIx32 "\n", ETHSTAT);
+    streamer_printf(streamer, "THRXOVFLOW 0x%08" PRIx32 "\n", ETHRXOVFLOW);
+    streamer_printf(streamer, "ETHFRMTXOK 0x%08" PRIx32 "\n", ETHFRMTXOK);
+    streamer_printf(streamer, "ETHFRMRXOK 0x%08" PRIx32 "\n", ETHFRMRXOK);
+    streamer_printf(streamer, "ETHSCOLFRM 0x%08" PRIx32 "\n", ETHSCOLFRM);
+    streamer_printf(streamer, "ETHMCOLFRM 0x%08" PRIx32 "\n", ETHMCOLFRM);
+    streamer_printf(streamer, "ETHFRMRXOK 0x%08" PRIx32 "\n", ETHFRMRXOK);
+    streamer_printf(streamer, " ETHFCSERR 0x%08" PRIx32 "\n", ETHFCSERR);
+    streamer_printf(streamer, "ETHALGNERR 0x%08" PRIx32 "\n", ETHALGNERR);
+    streamer_printf(streamer, " EMAC1CFG1 0x%08" PRIx32 "\n", EMAC1CFG1);
+    streamer_printf(streamer, " EMAC1CFG2 0x%08" PRIx32 "\n", EMAC1CFG2);
+    streamer_printf(streamer, " EMAC1IPGT 0x%08" PRIx32 "\n", EMAC1IPGT);
+    streamer_printf(streamer, " EMAC1IPGR 0x%08" PRIx32 "\n", EMAC1IPGR);
+    streamer_printf(streamer, " EMAC1MADR 0x%08" PRIx32 "\n", EMAC1MADR);
+
+    return 0;
+}
+
+static int
+pic32_eth_stats_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    (void)argc;
+    (void)argv;
+
+    streamer_printf(streamer, "oframe %d\n", (int)pic32_eth_stats.oframe);
+    streamer_printf(streamer, "odone %d\n", (int)pic32_eth_stats.odone);
+    streamer_printf(streamer, "oerr %d\n", (int)pic32_eth_stats.oerr);
+    streamer_printf(streamer, "iframe %d\n", (int)pic32_eth_stats.iframe);
+    streamer_printf(streamer, "imem %d\n", (int)pic32_eth_stats.imem);
+
+    return 0;
+}
+
+static void
+pic32_eth_phy_dump(struct streamer *streamer)
+{
+    int i;
+    int rc;
+    int phy_addr = MYNEWT_VAL(PIC32_ETH_0_PHY_ADDR);
+    uint16_t reg;
+
+    for (i = 0; i <= 6; i++) {
+        rc = pic32_eth_phy_read_register(phy_addr, i, &reg);
+        streamer_printf(streamer, "%d: %x (%d)\n", i, reg, rc);
+    }
+    for (i = 17; i <= 18; i++) {
+        rc = pic32_eth_phy_read_register(phy_addr, i, &reg);
+        streamer_printf(streamer, "%d: %x (%d)\n", i, reg, rc);
+    }
+    for (i = 26; i <= 31; i++) {
+        rc = pic32_eth_phy_read_register(phy_addr, i, &reg);
+        streamer_printf(streamer, "%d: %x (%d)\n", i, reg, rc);
+    }
+}
+
+static int
+pic32_eth_phy_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    int status;
+    int reg;
+    uint16_t regval;
+
+    if (argc == 1) {
+        pic32_eth_phy_dump(streamer);
+        return 0;
+    }
+    reg = (int)parse_ull_bounds(argv[1], 0, 31, &status);
+    if (status) {
+        streamer_printf(streamer, "Invalid register number.\n"
+                                  "Valid range 0-31\n");
+        return 0;
+    }
+    if (argc > 2) {
+        regval = (uint16_t)(uint16_t)parse_ull_bounds(argv[2], 0, 0xFFFF, &status);
+        if (status) {
+            streamer_printf(streamer, "Invalid register value.\n"
+                                      "Valid range 0-31\n");
+            return 0;
+        }
+        pic32_eth_phy_write_register(MYNEWT_VAL(PIC32_ETH_0_PHY_ADDR), reg, regval);
+    } else {
+        pic32_eth_phy_read_register(MYNEWT_VAL(PIC32_ETH_0_PHY_ADDR), reg, &regval);
+        streamer_printf(streamer, "0x%04x\n", regval);
+    }
+
+    return 0;
+}
+
+static int
+pic32_eth_desc_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    int i;
+    (void)argc;
+    (void)argv;
+
+    streamer_printf(streamer, "----------------RX_DESC-> %04X ---------\n", ETHRXST);
+    streamer_printf(streamer, "N  ADDR SOP EOP BYTES NPV EOWN DATA NEXT\n");
+    for (i = 0; i < PIC32_ETH_RX_DESC_COUNT; ++i) {
+        streamer_printf(streamer,
+                        "%02d %04x %d   %d  %6d %d   %d    %04x %04x\n", i,
+                        ((uint32_t)&pic32_eth_state.rx_descs[i]) & 0xFFFF,
+                        pic32_eth_state.rx_descs[i].hdr.SOP,
+                        pic32_eth_state.rx_descs[i].hdr.EOP,
+                        pic32_eth_state.rx_descs[i].hdr.BYTE_COUNT,
+                        pic32_eth_state.rx_descs[i].hdr.NPV,
+                        pic32_eth_state.rx_descs[i].hdr.EOWN,
+                        ((uint32_t)pic32_eth_state.rx_descs[i].data_buffer_address) & 0xFFFF,
+                        ((uint32_t)pic32_eth_state.rx_descs[i].next_ed) & 0xFFFF);
+    }
+    streamer_printf(streamer, "----------------RX_DESC-> %04X ---------\n", ETHTXST);
+    streamer_printf(streamer, "N  ADDR SOP EOP BYTES NPV EOWN DATA NEXT\n");
+    for (i = 0; i < PIC32_ETH_TX_DESC_COUNT; ++i) {
+        streamer_printf(streamer, "%02d %04x %d   %d  %6d %d   %d    %04x %04x\n", i,
+                        ((uint32_t)&pic32_eth_state.tx_descs[i]) & 0xFFFF,
+                        pic32_eth_state.tx_descs[i].hdr.SOP,
+                        pic32_eth_state.tx_descs[i].hdr.EOP,
+                        pic32_eth_state.tx_descs[i].hdr.BYTE_COUNT,
+                        pic32_eth_state.tx_descs[i].hdr.NPV,
+                        pic32_eth_state.tx_descs[i].hdr.EOWN,
+                        ((uint32_t)pic32_eth_state.tx_descs[i].data_buffer_address) & 0xFFFF,
+                        ((uint32_t)pic32_eth_state.tx_descs[i].next_ed) & 0xFFFF);
+    }
+
+    return 0;
+}
+
+static const struct shell_cmd pic32_eth_commands[] = {
+    SHELL_CMD_EXT("stats", pic32_eth_stats_cmd, &pic32_eth_stats_help),
+    SHELL_CMD_EXT("phy", pic32_eth_phy_cmd, &pic32_eth_phy_help),
+    SHELL_CMD_EXT("dump", pic32_eth_dump_cmd, &pic32_eth_dump_help),
+    SHELL_CMD_EXT("desc", pic32_eth_desc_cmd, &pic32_eth_desc_help),
+    SHELL_CMD_EXT("up", pic32_eth_up_cmd, &pic32_eth_up_help),
+    SHELL_CMD_EXT("down", pic32_eth_down_cmd, &pic32_eth_down_help),
+    { 0 },
+};
+
+static int
+pic32_eth_compat_cmd(const struct shell_cmd *cmd, int argc, char **argv, struct streamer *streamer)
+{
+    int rc;
+    int i;
+
+    if (argc < 2) {
+        rc = SYS_EINVAL;
+    } else {
+        for (i = 0; pic32_eth_commands[i].sc_cmd; ++i) {
+            if (strcmp(pic32_eth_commands[i].sc_cmd, argv[1]) == 0) {
+                rc = pic32_eth_commands[i].sc_cmd_func(argc - 1, argv + 1);
+                break;
+            }
+        }
+        /* No command found */
+        if (pic32_eth_commands[i].sc_cmd == NULL) {
+            streamer_printf(streamer, "Invalid command.\n");
+            rc = -1;
+        }
+    }
+
+    return rc;
+}
+
+static const struct shell_cmd pic32_eth_cmd = {
+    .sc_cmd = "eth",
+    .sc_cmd_ext_func = pic32_eth_compat_cmd,
+};
+
+void
+pic32_eth_shell_register(void)
+{
+    int rc;
+
+    rc = shell_register("eth", pic32_eth_commands);
+    rc = shell_cmd_register(&pic32_eth_cmd);
+
+    SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register eth shell");
+}
+
+#endif
diff --git a/hw/drivers/lwip/pic32_eth/syscfg.yml b/hw/drivers/lwip/pic32_eth/syscfg.yml
index f7623f089..371ed2b46 100644
--- a/hw/drivers/lwip/pic32_eth/syscfg.yml
+++ b/hw/drivers/lwip/pic32_eth/syscfg.yml
@@ -58,3 +58,7 @@ syscfg.defs:
         description: >
             Interface is up when opened.
         value: 1
+
+    PIC32_ETH_SHELL:
+        description: Enable shell commands.
+        value: 1