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, ®);
+ 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, ®);
+ 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, ®);
+ 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, ®val);
+ 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