// initiate a soft reset (run code in spifi) when flag is set. void handleReset() { // note, none of this soft reset code works. There is some kind of issue with the spifi coming out of reset. // 1) if you boot into spifi from power-up and run this code (from ram), reset works. // but only if you do soft reset of RGU_SIG_M3. RGU_SIG_CORE won't work, which is consistent with (3) below. // 2) if you boot into dfu from power-up (non-spifi) and run this code, reset fails. // This implies that some state either in the spifi device or the spifi controller isn't being reset/restored correctly // during reset. // 3) if you softreset the spifi, (1) no longer holds. // This implies that the state of the spifi controller is likely causing the reset hang. // 4) reading the state of the spifi controller (registers 0x40003000-0x40003020) shows a change in controller // state regarding (1) and (2), namely 0x40003014, 3018, 301c, but strangely, trying to read 0x40003014 programatically // hangs the processor. // There's this: // http://www.lpcware.com/content/blog/introduction-spifi // which describes how to reset the spifi device. // The Winbond W25Q80BV has a 0xff reset instruction (for stopping a read stream). // But this doesn't help either. // Other sources like the errata: // http://www.nxp.com/documents/errata_sheet/ES_LPC43X0_A.pdf // say that you need to issue a cancel_mem_mode() command beofore resetting. This doesn't work either. // http://www.lpcware.com/content/forum/soft-reset-spifi if (g_resetFlag) { delayus(100000); // wait for USB return packet to be sent #if 0 // reset spifi device SPIFI_CMD =(0xffu << 24) | // opcode 0xFF winbond reset (0x1 << 21) | // frame form indicating opcode only (0x0 << 19) | // field form indicating all serial (0); // datalen while(SPIFI_STAT & 2); // wait for command to complete //RGU_SoftReset(RGU_SIG_SPIFI); // reset spifi controller delayus(100000); // wait for spifi device to reset #endif (*spifi_table.cancel_mem_mode)(&g_spifi); (*spifi_table.cancel_mem_mode)(&g_spifi); delayus(100000); // wait for spifi device to reset RGU_SoftReset(RGU_SIG_CORE); // reset processor while(1); } }
void Init_EMAC(void) { int id1, id2, tout, regv; /* Ethernet pins configuration */ scu_pinmux(0xC, 1, MD_PLN_FAST, FUNC3); // ENET_MDC: PC_1 -> FUNC3 scu_pinmux(0x1, 17, MD_PLN_FAST, FUNC3); // ENET_MDIO: P1_17 -> FUNC3 scu_pinmux(0x1, 18, MD_PLN_FAST, FUNC3); // ENET_TXD0: P1_18 -> FUNC3 scu_pinmux(0x1, 20, MD_PLN_FAST, FUNC3); // ENET_TXD1: P1_20 -> FUNC3 scu_pinmux(0x1, 19, MD_PLN_FAST, FUNC0); // ENET_REF: P1_19 -> FUNC0 scu_pinmux(0x0, 1, MD_PLN_FAST, FUNC6); // ENET_TX_EN: P0_1 -> FUNC6 scu_pinmux(0x1, 15, MD_PLN_FAST, FUNC3); // ENET_RXD0: P1_15 -> FUNC3 scu_pinmux(0x0, 0, MD_PLN_FAST, FUNC2); // ENET_RXD1: P0_0 -> FUNC2 scu_pinmux(0x1, 16, MD_PLN_FAST, FUNC3); // ENET_CRS: P1_16 -> FUNC3 scu_pinmux(0xC, 9, MD_PLN_FAST, FUNC3); // ENET_RX_ER: PC_9 -> FUNC3 scu_pinmux(0xC, 8, MD_PLN_FAST, FUNC3); // ENET_RXDV: PC_8 -> FUNC3 /* Select MII interface */ scu_pinmux(0x9, 3, MD_PLN_FAST, FUNC5); // ENET_RXD2: P9_3 -> FUNC5 scu_pinmux(0x9, 2, MD_PLN_FAST, FUNC5); // ENET_RXD3: P9_2 -> FUNC5 scu_pinmux(0xC, 0, MD_PLN_FAST, FUNC3); // ENET_RXCLK: PC_0 -> FUNC3 scu_pinmux(0xC, 2, MD_PLN_FAST, FUNC3); // ENET_TXD2: PC_2 -> FUNC3 scu_pinmux(0xC, 3, MD_PLN_FAST, FUNC3); // ENET_TXD3: PC_3 -> FUNC3 scu_pinmux(0xC, 5, MD_PLN_FAST, FUNC3); // ENET_TX_ER: PC_5 -> FUNC3 scu_pinmux(0x9, 6, MD_PLN_FAST, FUNC5); // ENET_COL: P9_6 -> FUNC5 RGU_SoftReset(RGU_SIG_ETHERNET); while(1){ // Confirm the reset happened if (LPC_RGU->RESET_ACTIVE_STATUS0 & (1<<ETHERNET_RST)) break; } LPC_ETHERNET->DMA_BUS_MODE |= DMA_SOFT_RESET; // Reset all GMAC Subsystem internal registers and logic while(LPC_ETHERNET->DMA_BUS_MODE & DMA_SOFT_RESET); // Wait for software reset completion /* Put the DP83848C in reset mode */ write_PHY (PHY_REG_BMCR, PHY_BMCR_RESET); /* Wait for hardware reset to end. */ for (tout = 0; tout < TIMEOUT; tout++) { regv = read_PHY (PHY_REG_BMCR); if (!(regv & PHY_BMCR_RESET)) { /* Reset complete */ break; } } /* Check if this is a DP83848C PHY. */ id1 = read_PHY (PHY_REG_IDR1); id2 = read_PHY (PHY_REG_IDR2); if (((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID) { /* Configure the PHY device */ /* Use autonegotiation about the link speed. */ write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG); /* Wait to complete Auto_Negotiation. */ for (tout = 0; tout < TIMEOUT; tout++) { regv = read_PHY (PHY_REG_BMSR); if (regv & PHY_AUTO_NEG_DONE) { /* Autonegotiation Complete. */ break; } } } /* Check the link status. */ for (tout = 0; tout < TIMEOUT; tout++) { regv = read_PHY (PHY_REG_STS); if (regv & LINK_VALID_STS) { /* Link is on. */ break; } } /* Configure Full/Half Duplex mode. */ if (regv & FULL_DUP_STS) { /* Full duplex is enabled. */ LPC_ETHERNET->MAC_CONFIG |= MAC_DUPMODE; } /* Configure 100MBit/10MBit mode. */ if (~(regv & SPEED_10M_STS)) { /* 100MBit mode. */ LPC_ETHERNET->MAC_CONFIG |= MAC_100MPS; } /* Set the Ethernet MAC Address registers */ LPC_ETHERNET->MAC_ADDR0_HIGH = (MYMAC_6 << 8) | MYMAC_5; LPC_ETHERNET->MAC_ADDR0_LOW = (MYMAC_4 << 24) | (MYMAC_3 << 16) | (MYMAC_2 << 8) | MYMAC_1; /* Initialize Descriptor Lists */ rx_descr_init(); tx_descr_init(); /* Configure Filter */ LPC_ETHERNET->MAC_FRAME_FILTER = MAC_PROMISCUOUS | MAC_RECEIVEALL; /* Enable Receiver and Transmitter */ LPC_ETHERNET->MAC_CONFIG |= (MAC_TX_ENABLE | MAC_RX_ENABLE); /* Enable interrupts */ //LPC_ETHERNET->DMA_INT_EN = DMA_INT_NOR_SUM | DMA_INT_RECEIVE | DMA_INT_TRANSMIT; /* Start Transmission & Receive processes */ LPC_ETHERNET->DMA_OP_MODE |= (DMA_SS_TRANSMIT | DMA_SS_RECEIVE ); }