summaryrefslogtreecommitdiffstats
path: root/app/steth.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/steth.c')
-rw-r--r--app/steth.c366
1 files changed, 366 insertions, 0 deletions
diff --git a/app/steth.c b/app/steth.c
new file mode 100644
index 0000000..2aa847f
--- /dev/null
+++ b/app/steth.c
@@ -0,0 +1,366 @@
+#include <project.h>
+
+
+#define PHY PHY0
+
+#define TXEN GPIO11
+#define TXEN_PORT GPIOB
+
+#define TXD0 GPIO12
+#define TXD0_PORT GPIOB
+
+#define TXD1 GPIO13
+#define TXD1_PORT GPIOB
+
+#define RXD0 GPIO4
+#define RXD0_PORT GPIOC
+
+#define RXD1 GPIO5
+#define RXD1_PORT GPIOC
+
+#define CRS_DV GPIO7
+#define CRS_DV_PORT GPIOA
+
+#define MDIO GPIO2
+#define MDIO_PORT GPIOA
+
+#define MDC GPIO1
+#define MDC_PORT GPIOC
+
+#define REF_CLK GPIO1
+#define REF_CLK_PORT GPIOA
+
+#define NRST GPIO2
+#define NRST_PORT GPIOE
+
+
+#define DESC_SZ 32
+#define FRAME_SZ 1516
+
+#define TX_BUFS 4
+#define RX_BUFS 4
+
+#define ETH_BUF_LEN ((TX_BUFS+ RX_BUFS) * (DESC_SZ+FRAME_SZ))
+
+static int running;
+
+static uint8_t __attribute__ ((aligned (4))) eth_buf[ETH_BUF_LEN];
+
+static uint8_t sa[ETHARP_HWADDR_LEN] = { 0xc0, 0xf1, 0xee, 0xc0, 0xff, 0xee };
+
+extern uint32_t TxBD;
+extern uint32_t RxBD;
+
+
+
+bool
+phy_link_an_done (uint8_t phy)
+{
+ return eth_smi_read (PHY, PHY_REG_BSR) & PHY_REG_BSR_ANDONE;
+}
+
+
+
+static err_t
+steth_tx (struct netif *netif, struct pbuf *p)
+{
+#if 0
+ static uint8_t tx_buf[FRAME_SZ];
+ uint32_t len, left;
+
+ len = 0;
+ left = FRAME_SZ;
+
+ for (; p != NULL; p = p->next) {
+ uint32_t sz = (left > p->len) ? p->len : left;
+ memcpy (&tx_buf[len], (u8_t *) p->payload, sz);
+ len += sz;
+ left -= sz;
+ }
+
+ // usart6_write ("X", 1, 0);
+
+ // hexdump(tx_buf,len);
+
+ while (!eth_tx (tx_buf, len));
+
+#else
+
+ if (p->next) return ERR_IF;
+
+ while (!eth_tx (p->payload, p->len));
+
+#endif
+
+ {
+ static int tx_cnt = 0;
+ printf ("TX %d\r\n", tx_cnt++);
+ }
+
+ return ERR_OK;
+}
+
+static err_t
+steth_rx (void)
+{
+ //err_t err;
+ struct pbuf *p;
+ uint32_t len;
+#if 0
+ struct pbuf *q;
+ static uint8_t rx_buf[FRAME_SZ];
+
+ len = 0;
+
+ if (!eth_rx (rx_buf, &len, sizeof (rx_buf))) {
+ usart6_write ("?", 1, 0);
+ return ERR_OK;
+ }
+
+ /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
+ p = pbuf_alloc (PBUF_RAW, len, PBUF_POOL);
+
+ if (!p) {
+ usart6_write ("!", 1, 0);
+ return ERR_MEM;
+ }
+
+ len = 0;
+
+ for (q = p; q != NULL; q = q->next) {
+ memcpy ((u8_t *) q->payload, (u8_t *) & rx_buf[len], q->len);
+ len += q->len;
+ }
+
+#else
+ p = pbuf_alloc (PBUF_RAW, MTU, PBUF_POOL);
+
+ if (!p) return ERR_MEM;
+
+ len = 0;
+
+ if (!eth_rx (p->payload, &len, MTU)) {
+ pbuf_free (p);
+ return ERR_IF;
+ }
+
+ pbuf_realloc (p, len);
+#endif
+
+
+
+ // usart6_write (".", 1, 0);
+
+ {
+ static int rx_cnt = 0;
+ printf ("RX %d\r\n", rx_cnt++);
+ }
+
+
+ return if0.input (p, &if0);
+}
+
+
+
+static void
+steth_nis (void)
+{
+ if (eth_irq_ack_pending (ETH_DMASR_RS))
+ steth_rx();
+}
+
+void
+eth_isr (void)
+{
+}
+
+void
+steth_isr (void)
+{
+ // printf ("eth\r\n");
+
+ if (eth_irq_ack_pending (ETH_DMASR_NIS))
+ steth_nis();
+
+}
+
+
+err_t
+steth_lwip_init (struct netif *netif)
+{
+ LWIP_ASSERT ("netif != NULL", (netif != NULL));
+
+#if LWIP_NETIF_HOSTNAME
+ /* Initialize interface hostname */
+ netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+ netif->name[0] = 's';
+ netif->name[1] = 't';
+ /* We directly use etharp_output() here to save a function call.
+ * You can instead declare your own function an call etharp_output()
+ * from it if you have to do some checks before sending (e.g. if link
+ * is available...) */
+ netif->output = etharp_output;
+ netif->linkoutput = steth_tx;
+
+ /* set MAC hardware address length */
+ netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+ /* set MAC hardware address */
+ memcpy (netif->hwaddr, sa, ETHARP_HWADDR_LEN);
+
+ /* maximum transfer unit */
+ netif->mtu = 1500;
+
+ /* device capabilities */
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+
+ return ERR_OK;
+}
+
+
+void
+steth_init (void)
+{
+
+
+ MAP_AF (TXEN, GPIO_AF11);
+ MAP_AF (TXD0, GPIO_AF11);
+ MAP_AF (TXD1, GPIO_AF11);
+
+ MAP_AF (RXD0, GPIO_AF11);
+ MAP_AF (RXD1, GPIO_AF11);
+
+ MAP_AF (CRS_DV, GPIO_AF11);
+
+ MAP_AF (MDIO, GPIO_AF11);
+ MAP_AF (MDC, GPIO_AF11);
+
+ MAP_AF (REF_CLK, GPIO_AF11);
+
+ MAP_OUTPUT_PP (NRST);
+
+ SET (NRST);
+
+ /* The switch to RMII has be done with steth under reset, with no clock */
+
+
+ rcc_periph_clock_disable (RCC_ETHMACPTP);
+ rcc_periph_clock_disable (RCC_ETHMACRX);
+ rcc_periph_clock_disable (RCC_ETHMACTX);
+ rcc_periph_clock_disable (RCC_ETHMAC);
+
+ RCC_AHB1RSTR |= RCC_AHB1RSTR_ETHMACRST; /*Assert RESET */
+ delay_us (1);
+
+#ifndef SYSCFG_PMC_MII_RMII_SEL
+#define SYSCFG_PMC_MII_RMII_SEL (1UL << 23)
+#endif
+
+ SYSCFG_PMC |= SYSCFG_PMC_MII_RMII_SEL;
+
+ RCC_AHB1RSTR &= ~RCC_AHB1RSTR_ETHMACRST; /*De-sssert RESET */
+
+
+ rcc_periph_clock_enable (RCC_ETHMAC);
+ rcc_periph_clock_enable (RCC_ETHMACTX);
+ rcc_periph_clock_enable (RCC_ETHMACRX);
+ rcc_periph_clock_enable (RCC_ETHMACPTP);
+
+ eth_desc_init (eth_buf, TX_BUFS, RX_BUFS, FRAME_SZ, FRAME_SZ, 1);
+
+ /*MDC = HCLK / 102 (0b100) => 1.6MHz */
+ eth_init (PHY, 0x4);
+ eth_enable_checksum_offload();
+
+
+ printf ("Waiting for link\r\n");
+
+ while (!phy_link_isup (PHY));
+
+ phy_autoneg_enable (PHY);
+ printf ("Waiting for autonegociation\r\n");
+
+ while (!phy_link_an_done (PHY));
+
+ switch (phy_link_status (PHY)) {
+ case LINK_HD_10M:
+ case LINK_FD_10M:
+ ETH_MACCR &= ~ETH_MACCR_FES;
+ break;
+
+ default:
+ ;
+ }
+
+
+ switch (phy_link_status (PHY)) {
+ case LINK_HD_10M:
+ case LINK_HD_100M:
+ ETH_MACCR &= ~ETH_MACCR_DM;
+ ETH_MACCR |= ETH_MACCR_ROD;
+ break;
+
+ default:
+ ;
+ }
+
+ ETH_MACCR &= ~ETH_MACCR_RD;
+
+ eth_set_mac (sa);
+
+ nvic_disable_irq (NVIC_ETH_IRQ);
+
+ eth_irq_enable (ETH_DMAIER_NISE);
+ eth_irq_enable (ETH_DMAIER_RIE);
+ eth_irq_enable (ETH_DMASR_TS);
+ //
+ eth_start();
+
+
+ running++;
+
+ printf ("Running\n");
+
+}
+
+
+void
+steth_dispatch (void)
+{
+#if 0
+ uint32_t d, s;
+#endif
+
+ if (!running)
+ return;
+
+#if 0
+ printf ("Net:\r\n");
+ printf (" ETH_MACCR: %08" PRIx32 "\r\n", ETH_MACCR);
+ printf (" ETH_MACDBGR: %08" PRIx32 "\r\n", ETH_MACDBGR);
+ printf (" ETH_DMASR: %08" PRIx32 "\r\n", ETH_DMASR);
+ printf (" ETH_DMAIER: %08" PRIx32 "\r\n", ETH_DMAIER);
+ printf (" ETH_DMACHTDR: %08" PRIx32 "\r\n", ETH_DMACHTDR);
+ printf (" ETH_DMACHRDR: %08" PRIx32 "\r\n", ETH_DMACHRDR);
+
+
+ s = d = RxBD;
+
+
+ do {
+ printf (" %08" PRIx32 ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08"
+ PRIx32 "\r\n", d, ETH_DES0 (d), ETH_DES1 (d), ETH_DES2 (d),
+ ETH_DES3 (d));
+
+ d = ETH_DES3 (d);
+
+ } while (d != s);
+
+#endif
+
+ steth_isr();
+
+}
+