This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
core/driver/ethernet/lpc4088/EthDev_LPC4088.c@97:6ca5900a2d68, 2014-10-19 (annotated)
- Committer:
- nyatla
- Date:
- Sun Oct 19 08:44:52 2014 +0000
- Revision:
- 97:6ca5900a2d68
- Parent:
- 92:4f77028cce64
Bugfix LPC4088 driver; Bugfix mDNS TTL;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nyatla | 69:8c5f220441f5 | 1 | #include "NyLPC_config.h" |
nyatla | 69:8c5f220441f5 | 2 | #if NyLPC_MCU==NyLPC_MCU_LPC4088 |
nyatla | 69:8c5f220441f5 | 3 | #include "NyLPC_os.h" |
nyatla | 69:8c5f220441f5 | 4 | #include "copy_of_ethernet_api.h" |
nyatla | 69:8c5f220441f5 | 5 | #include "NyLPC_IEthernetDevice.h" |
nyatla | 69:8c5f220441f5 | 6 | #include "NyLPC_cEthernetMM.h" |
nyatla | 69:8c5f220441f5 | 7 | |
nyatla | 69:8c5f220441f5 | 8 | |
nyatla | 69:8c5f220441f5 | 9 | |
nyatla | 69:8c5f220441f5 | 10 | #define emacSHORT_DELAY_MS 10 |
nyatla | 69:8c5f220441f5 | 11 | #ifndef configEMAC_INTERRUPT_PRIORITY |
nyatla | 69:8c5f220441f5 | 12 | #define configEMAC_INTERRUPT_PRIORITY 5 |
nyatla | 69:8c5f220441f5 | 13 | #endif |
nyatla | 69:8c5f220441f5 | 14 | //////////////////////////////////////////////////////////////////////////////// |
nyatla | 69:8c5f220441f5 | 15 | // Ethernet Memory |
nyatla | 69:8c5f220441f5 | 16 | //////////////////////////////////////////////////////////////////////////////// |
nyatla | 69:8c5f220441f5 | 17 | |
nyatla | 69:8c5f220441f5 | 18 | #define AHB_SRAM_BANK1_BASE 0x20004000UL |
nyatla | 69:8c5f220441f5 | 19 | #define RX_DESC_BASE (AHB_SRAM_BANK1_BASE ) |
nyatla | 69:8c5f220441f5 | 20 | #define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */ |
nyatla | 69:8c5f220441f5 | 21 | #define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */ |
nyatla | 69:8c5f220441f5 | 22 | #define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */ |
nyatla | 69:8c5f220441f5 | 23 | #define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */ |
nyatla | 69:8c5f220441f5 | 24 | |
nyatla | 69:8c5f220441f5 | 25 | /** |
nyatla | 69:8c5f220441f5 | 26 | * 消費メモリ量は、 |
nyatla | 69:8c5f220441f5 | 27 | * descriptor = NUM_RX_FRAG*16+NUM_TX_FRAG*12. |
nyatla | 69:8c5f220441f5 | 28 | * EthnetBuf=ETH_FRAG_SIZE*NUM_RX_FRAG |
nyatla | 69:8c5f220441f5 | 29 | */ |
nyatla | 69:8c5f220441f5 | 30 | |
nyatla | 69:8c5f220441f5 | 31 | /* RX and TX descriptor and status definitions. */ |
nyatla | 69:8c5f220441f5 | 32 | #define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) |
nyatla | 69:8c5f220441f5 | 33 | #define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) |
nyatla | 69:8c5f220441f5 | 34 | #define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) |
nyatla | 69:8c5f220441f5 | 35 | #define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) |
nyatla | 69:8c5f220441f5 | 36 | #define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) |
nyatla | 69:8c5f220441f5 | 37 | #define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) |
nyatla | 69:8c5f220441f5 | 38 | #define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) |
nyatla | 69:8c5f220441f5 | 39 | #define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i ) |
nyatla | 69:8c5f220441f5 | 40 | #define ETH_TX_BUF_BASE ((void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG)) |
nyatla | 69:8c5f220441f5 | 41 | |
nyatla | 69:8c5f220441f5 | 42 | |
nyatla | 69:8c5f220441f5 | 43 | #define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500 |
nyatla | 69:8c5f220441f5 | 44 | |
nyatla | 69:8c5f220441f5 | 45 | //////////////////////////////////////////////////////////////////////////////// |
nyatla | 69:8c5f220441f5 | 46 | // Ethernet interdface functions |
nyatla | 69:8c5f220441f5 | 47 | //////////////////////////////////////////////////////////////////////////////// |
nyatla | 69:8c5f220441f5 | 48 | static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); |
nyatla | 69:8c5f220441f5 | 49 | static void stop(void); |
nyatla | 69:8c5f220441f5 | 50 | static void* getRxEthFrame(unsigned short* o_len_of_data); |
nyatla | 69:8c5f220441f5 | 51 | static void nextRxEthFrame(void); |
nyatla | 97:6ca5900a2d68 | 52 | static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); |
nyatla | 92:4f77028cce64 | 53 | static void releaseTxBuf(void* i_buf); |
nyatla | 92:4f77028cce64 | 54 | static void sendTxEthFrame(void* i_buf,unsigned short i_size); |
nyatla | 69:8c5f220441f5 | 55 | static void processTx(void); |
nyatla | 69:8c5f220441f5 | 56 | |
nyatla | 69:8c5f220441f5 | 57 | //////////////////////////////////////////////////////////////////////////////// |
nyatla | 69:8c5f220441f5 | 58 | // Private |
nyatla | 69:8c5f220441f5 | 59 | //////////////////////////////////////////////////////////////////////////////// |
nyatla | 69:8c5f220441f5 | 60 | static void emacIsrHandler(unsigned long i_status); |
nyatla | 69:8c5f220441f5 | 61 | static unsigned int clockselect(void); |
nyatla | 69:8c5f220441f5 | 62 | static int ethernet_link(void); |
nyatla | 69:8c5f220441f5 | 63 | static int phy_write(unsigned int PhyReg, unsigned short Data); |
nyatla | 69:8c5f220441f5 | 64 | static int phy_read(unsigned int PhyReg); |
nyatla | 69:8c5f220441f5 | 65 | static void prevTxDescriptor(void); |
nyatla | 69:8c5f220441f5 | 66 | static void prevRxDescriptor(void); |
nyatla | 69:8c5f220441f5 | 67 | static NyLPC_TUInt32 waitForTxEthFrameEmpty(void); |
nyatla | 69:8c5f220441f5 | 68 | |
nyatla | 69:8c5f220441f5 | 69 | /*-----------------------------------------------------------*/ |
nyatla | 69:8c5f220441f5 | 70 | |
nyatla | 69:8c5f220441f5 | 71 | |
nyatla | 69:8c5f220441f5 | 72 | const static struct TiEthernetDevice _interface_LAN8720= |
nyatla | 69:8c5f220441f5 | 73 | { |
nyatla | 69:8c5f220441f5 | 74 | "LAN8720", |
nyatla | 69:8c5f220441f5 | 75 | start, |
nyatla | 69:8c5f220441f5 | 76 | stop, |
nyatla | 69:8c5f220441f5 | 77 | getRxEthFrame, |
nyatla | 69:8c5f220441f5 | 78 | nextRxEthFrame, |
nyatla | 69:8c5f220441f5 | 79 | allocTxBuf, |
nyatla | 69:8c5f220441f5 | 80 | releaseTxBuf, |
nyatla | 69:8c5f220441f5 | 81 | sendTxEthFrame, |
nyatla | 69:8c5f220441f5 | 82 | processTx |
nyatla | 69:8c5f220441f5 | 83 | }; |
nyatla | 69:8c5f220441f5 | 84 | const static struct TiEthernetDevice _interface_DP83848C= |
nyatla | 69:8c5f220441f5 | 85 | { |
nyatla | 69:8c5f220441f5 | 86 | "DP83848C", |
nyatla | 69:8c5f220441f5 | 87 | start, |
nyatla | 69:8c5f220441f5 | 88 | stop, |
nyatla | 69:8c5f220441f5 | 89 | getRxEthFrame, |
nyatla | 69:8c5f220441f5 | 90 | nextRxEthFrame, |
nyatla | 69:8c5f220441f5 | 91 | allocTxBuf, |
nyatla | 69:8c5f220441f5 | 92 | releaseTxBuf, |
nyatla | 69:8c5f220441f5 | 93 | sendTxEthFrame, |
nyatla | 69:8c5f220441f5 | 94 | processTx |
nyatla | 69:8c5f220441f5 | 95 | }; |
nyatla | 69:8c5f220441f5 | 96 | |
nyatla | 69:8c5f220441f5 | 97 | static void* _event_param; |
nyatla | 69:8c5f220441f5 | 98 | static NyLPC_TiEthernetDevice_onEvent _event_handler; |
nyatla | 69:8c5f220441f5 | 99 | static unsigned int phy_id; |
nyatla | 69:8c5f220441f5 | 100 | |
nyatla | 69:8c5f220441f5 | 101 | /* |
nyatla | 69:8c5f220441f5 | 102 | * EthernetDeviceのファクトリー関数。インターフェイスを生成できればtrue |
nyatla | 69:8c5f220441f5 | 103 | * |
nyatla | 69:8c5f220441f5 | 104 | */ |
nyatla | 69:8c5f220441f5 | 105 | NyLPC_TBool EthDev_LPC4088_getInterface( |
nyatla | 69:8c5f220441f5 | 106 | const struct TiEthernetDevice** o_dev) |
nyatla | 69:8c5f220441f5 | 107 | { |
nyatla | 69:8c5f220441f5 | 108 | int regv, tout; |
nyatla | 69:8c5f220441f5 | 109 | unsigned int clock = clockselect(); |
nyatla | 69:8c5f220441f5 | 110 | |
nyatla | 69:8c5f220441f5 | 111 | LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ |
nyatla | 69:8c5f220441f5 | 112 | LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ |
nyatla | 69:8c5f220441f5 | 113 | LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */ |
nyatla | 69:8c5f220441f5 | 114 | LPC_IOCON->P1_1 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 115 | LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */ |
nyatla | 69:8c5f220441f5 | 116 | LPC_IOCON->P1_4 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 117 | LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */ |
nyatla | 69:8c5f220441f5 | 118 | LPC_IOCON->P1_8 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 119 | LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */ |
nyatla | 69:8c5f220441f5 | 120 | LPC_IOCON->P1_9 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 121 | LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */ |
nyatla | 69:8c5f220441f5 | 122 | LPC_IOCON->P1_10 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 123 | LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */ |
nyatla | 69:8c5f220441f5 | 124 | LPC_IOCON->P1_14 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 125 | LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */ |
nyatla | 69:8c5f220441f5 | 126 | LPC_IOCON->P1_15 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 127 | LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */ |
nyatla | 69:8c5f220441f5 | 128 | LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ |
nyatla | 69:8c5f220441f5 | 129 | LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */ |
nyatla | 69:8c5f220441f5 | 130 | LPC_IOCON->P1_17 &= ~0x07; |
nyatla | 69:8c5f220441f5 | 131 | LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */ |
nyatla | 69:8c5f220441f5 | 132 | |
nyatla | 69:8c5f220441f5 | 133 | /* Reset all EMAC internal modules. */ |
nyatla | 69:8c5f220441f5 | 134 | LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; |
nyatla | 69:8c5f220441f5 | 135 | LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; |
nyatla | 69:8c5f220441f5 | 136 | for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ |
nyatla | 69:8c5f220441f5 | 137 | |
nyatla | 69:8c5f220441f5 | 138 | /* Initialize MAC control registers. */ |
nyatla | 69:8c5f220441f5 | 139 | LPC_EMAC->MAC1 = MAC1_PASS_ALL; |
nyatla | 69:8c5f220441f5 | 140 | LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; |
nyatla | 69:8c5f220441f5 | 141 | LPC_EMAC->MAXF = ETH_MAX_FLEN; |
nyatla | 69:8c5f220441f5 | 142 | LPC_EMAC->CLRT = CLRT_DEF; |
nyatla | 69:8c5f220441f5 | 143 | LPC_EMAC->IPGR = IPGR_DEF; |
nyatla | 69:8c5f220441f5 | 144 | |
nyatla | 69:8c5f220441f5 | 145 | /* Enable Reduced MII interface. */ |
nyatla | 69:8c5f220441f5 | 146 | LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ |
nyatla | 69:8c5f220441f5 | 147 | LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ |
nyatla | 69:8c5f220441f5 | 148 | LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM |CR_PASS_RX_FILT; /* Enable Reduced MII interface. */ |
nyatla | 69:8c5f220441f5 | 149 | |
nyatla | 69:8c5f220441f5 | 150 | for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ |
nyatla | 69:8c5f220441f5 | 151 | |
nyatla | 69:8c5f220441f5 | 152 | LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; |
nyatla | 69:8c5f220441f5 | 153 | LPC_EMAC->MCMD = 0; |
nyatla | 69:8c5f220441f5 | 154 | LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ |
nyatla | 69:8c5f220441f5 | 155 | for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ |
nyatla | 69:8c5f220441f5 | 156 | LPC_EMAC->SUPP = SUPP_SPEED; |
nyatla | 69:8c5f220441f5 | 157 | |
nyatla | 69:8c5f220441f5 | 158 | phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ |
nyatla | 69:8c5f220441f5 | 159 | for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ |
nyatla | 69:8c5f220441f5 | 160 | regv = phy_read(PHY_REG_BMCR); |
nyatla | 69:8c5f220441f5 | 161 | if(regv < 0 || tout == 0) { |
nyatla | 69:8c5f220441f5 | 162 | return NyLPC_TBool_FALSE; /* Error */ |
nyatla | 69:8c5f220441f5 | 163 | } |
nyatla | 69:8c5f220441f5 | 164 | if(!(regv & PHY_BMCR_RESET)) { |
nyatla | 69:8c5f220441f5 | 165 | break; /* Reset complete. */ |
nyatla | 69:8c5f220441f5 | 166 | } |
nyatla | 69:8c5f220441f5 | 167 | } |
nyatla | 69:8c5f220441f5 | 168 | |
nyatla | 69:8c5f220441f5 | 169 | phy_id = (phy_read(PHY_REG_IDR1) << 16); |
nyatla | 69:8c5f220441f5 | 170 | phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); |
nyatla | 69:8c5f220441f5 | 171 | |
nyatla | 69:8c5f220441f5 | 172 | switch(phy_id){ |
nyatla | 69:8c5f220441f5 | 173 | case DP83848C_ID: |
nyatla | 69:8c5f220441f5 | 174 | *o_dev=&_interface_DP83848C; |
nyatla | 69:8c5f220441f5 | 175 | break; |
nyatla | 69:8c5f220441f5 | 176 | case LAN8720_ID: |
nyatla | 69:8c5f220441f5 | 177 | *o_dev=&_interface_LAN8720; |
nyatla | 69:8c5f220441f5 | 178 | break; |
nyatla | 69:8c5f220441f5 | 179 | default: |
nyatla | 69:8c5f220441f5 | 180 | return NyLPC_TBool_FALSE; /* Error */ |
nyatla | 69:8c5f220441f5 | 181 | } |
nyatla | 69:8c5f220441f5 | 182 | LPC_EMAC->TxProduceIndex = 0; |
nyatla | 69:8c5f220441f5 | 183 | LPC_EMAC->RxConsumeIndex = 0; |
nyatla | 69:8c5f220441f5 | 184 | return NyLPC_TBool_TRUE; |
nyatla | 69:8c5f220441f5 | 185 | } |
nyatla | 69:8c5f220441f5 | 186 | |
nyatla | 69:8c5f220441f5 | 187 | |
nyatla | 69:8c5f220441f5 | 188 | |
nyatla | 69:8c5f220441f5 | 189 | static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param) |
nyatla | 69:8c5f220441f5 | 190 | { |
nyatla | 69:8c5f220441f5 | 191 | int i; |
nyatla | 69:8c5f220441f5 | 192 | //ISRw割り込み設定 |
nyatla | 69:8c5f220441f5 | 193 | NyLPC_cIsr_setEnetISR(emacIsrHandler); |
nyatla | 69:8c5f220441f5 | 194 | _event_handler=i_handler; |
nyatla | 69:8c5f220441f5 | 195 | _event_param=i_param; |
nyatla | 69:8c5f220441f5 | 196 | /* Set the Ethernet MAC Address registers */ |
nyatla | 69:8c5f220441f5 | 197 | LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1]; |
nyatla | 69:8c5f220441f5 | 198 | LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3]; |
nyatla | 69:8c5f220441f5 | 199 | LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5]; |
nyatla | 69:8c5f220441f5 | 200 | |
nyatla | 69:8c5f220441f5 | 201 | //TXメモリマネージャの準備 |
nyatla | 69:8c5f220441f5 | 202 | NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE); |
nyatla | 69:8c5f220441f5 | 203 | /* Initialize Tx and Rx DMA Descriptors */ |
nyatla | 69:8c5f220441f5 | 204 | prevRxDescriptor(); |
nyatla | 69:8c5f220441f5 | 205 | prevTxDescriptor(); |
nyatla | 69:8c5f220441f5 | 206 | //wait for link up |
nyatla | 69:8c5f220441f5 | 207 | for(i=0;i<5;i++){ |
nyatla | 69:8c5f220441f5 | 208 | if(ethernet_link()!=0){ |
nyatla | 69:8c5f220441f5 | 209 | break; |
nyatla | 69:8c5f220441f5 | 210 | } |
nyatla | 69:8c5f220441f5 | 211 | NyLPC_cThread_sleep(emacWAIT_FOR_LINK_TO_ESTABLISH_MS); |
nyatla | 69:8c5f220441f5 | 212 | } |
nyatla | 69:8c5f220441f5 | 213 | |
nyatla | 69:8c5f220441f5 | 214 | //setup Link |
nyatla | 69:8c5f220441f5 | 215 | ethernet_set_link(-1, 0); |
nyatla | 69:8c5f220441f5 | 216 | |
nyatla | 69:8c5f220441f5 | 217 | LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; |
nyatla | 69:8c5f220441f5 | 218 | /* Receive Broadcast, Perfect Match Packets */ |
nyatla | 69:8c5f220441f5 | 219 | |
nyatla | 69:8c5f220441f5 | 220 | //Ethernetの割込み開始設定 |
nyatla | 69:8c5f220441f5 | 221 | NyLPC_cIsr_enterCritical(); |
nyatla | 69:8c5f220441f5 | 222 | { |
nyatla | 69:8c5f220441f5 | 223 | LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ |
nyatla | 69:8c5f220441f5 | 224 | LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ |
nyatla | 69:8c5f220441f5 | 225 | |
nyatla | 69:8c5f220441f5 | 226 | LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ |
nyatla | 69:8c5f220441f5 | 227 | LPC_EMAC->MAC1 |= MAC1_REC_EN; |
nyatla | 69:8c5f220441f5 | 228 | |
nyatla | 69:8c5f220441f5 | 229 | NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); |
nyatla | 69:8c5f220441f5 | 230 | NVIC_EnableIRQ( ENET_IRQn ); |
nyatla | 69:8c5f220441f5 | 231 | } |
nyatla | 69:8c5f220441f5 | 232 | NyLPC_cIsr_exitCritical(); |
nyatla | 69:8c5f220441f5 | 233 | |
nyatla | 69:8c5f220441f5 | 234 | return NyLPC_TBool_TRUE; |
nyatla | 69:8c5f220441f5 | 235 | } |
nyatla | 69:8c5f220441f5 | 236 | |
nyatla | 69:8c5f220441f5 | 237 | |
nyatla | 69:8c5f220441f5 | 238 | static void stop(void) |
nyatla | 69:8c5f220441f5 | 239 | { |
nyatla | 69:8c5f220441f5 | 240 | NyLPC_cIsr_enterCritical(); |
nyatla | 69:8c5f220441f5 | 241 | { |
nyatla | 69:8c5f220441f5 | 242 | LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); |
nyatla | 69:8c5f220441f5 | 243 | LPC_EMAC->IntClear = 0xFFFF; |
nyatla | 69:8c5f220441f5 | 244 | |
nyatla | 69:8c5f220441f5 | 245 | NVIC_DisableIRQ( ENET_IRQn ); |
nyatla | 69:8c5f220441f5 | 246 | } |
nyatla | 69:8c5f220441f5 | 247 | NyLPC_cIsr_exitCritical(); |
nyatla | 69:8c5f220441f5 | 248 | LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN ); |
nyatla | 69:8c5f220441f5 | 249 | LPC_EMAC->MAC1 &= ~MAC1_REC_EN; |
nyatla | 69:8c5f220441f5 | 250 | //ISR割り込み解除 |
nyatla | 69:8c5f220441f5 | 251 | NyLPC_cIsr_setEnetISR(NULL); |
nyatla | 69:8c5f220441f5 | 252 | //TXメモリマネージャの終了 |
nyatla | 69:8c5f220441f5 | 253 | NyLPC_cEthernetMM_finalize(); |
nyatla | 69:8c5f220441f5 | 254 | } |
nyatla | 69:8c5f220441f5 | 255 | |
nyatla | 92:4f77028cce64 | 256 | static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) |
nyatla | 69:8c5f220441f5 | 257 | { |
nyatla | 69:8c5f220441f5 | 258 | return NyLPC_cEthernetMM_alloc(i_hint,o_size); |
nyatla | 69:8c5f220441f5 | 259 | } |
nyatla | 92:4f77028cce64 | 260 | static void releaseTxBuf(void* i_buf) |
nyatla | 69:8c5f220441f5 | 261 | { |
nyatla | 69:8c5f220441f5 | 262 | NyLPC_cEthernetMM_release(i_buf); |
nyatla | 69:8c5f220441f5 | 263 | } |
nyatla | 69:8c5f220441f5 | 264 | |
nyatla | 69:8c5f220441f5 | 265 | |
nyatla | 69:8c5f220441f5 | 266 | /** |
nyatla | 69:8c5f220441f5 | 267 | */ |
nyatla | 69:8c5f220441f5 | 268 | static void processTx(void) |
nyatla | 69:8c5f220441f5 | 269 | { |
nyatla | 69:8c5f220441f5 | 270 | waitForTxEthFrameEmpty(); |
nyatla | 69:8c5f220441f5 | 271 | } |
nyatla | 69:8c5f220441f5 | 272 | |
nyatla | 69:8c5f220441f5 | 273 | |
nyatla | 69:8c5f220441f5 | 274 | |
nyatla | 69:8c5f220441f5 | 275 | /** |
nyatla | 69:8c5f220441f5 | 276 | * Ethernetパケットを送信します。 |
nyatla | 92:4f77028cce64 | 277 | * allocTxBufで得たバッファを指定すること。 |
nyatla | 69:8c5f220441f5 | 278 | * <p>関数仕様</p> |
nyatla | 69:8c5f220441f5 | 279 | * この関数は、i_bufが |
nyatla | 69:8c5f220441f5 | 280 | * </div> |
nyatla | 69:8c5f220441f5 | 281 | */ |
nyatla | 92:4f77028cce64 | 282 | static void sendTxEthFrame(void* i_buf,unsigned short i_size) |
nyatla | 69:8c5f220441f5 | 283 | { |
nyatla | 69:8c5f220441f5 | 284 | NyLPC_TUInt32 IndexNext,Index; |
nyatla | 92:4f77028cce64 | 285 | struct NyLPC_TTxBufferHeader* bh=NyLPC_TTxBufferHeader_getBufferHeaderAddr(i_buf); |
nyatla | 69:8c5f220441f5 | 286 | |
nyatla | 69:8c5f220441f5 | 287 | //サイズ0なら送信の必要なし |
nyatla | 69:8c5f220441f5 | 288 | if(i_size == 0) |
nyatla | 69:8c5f220441f5 | 289 | { |
nyatla | 69:8c5f220441f5 | 290 | return; |
nyatla | 69:8c5f220441f5 | 291 | } |
nyatla | 69:8c5f220441f5 | 292 | //送信デスクリプタの反映 |
nyatla | 69:8c5f220441f5 | 293 | IndexNext =waitForTxEthFrameEmpty(); |
nyatla | 69:8c5f220441f5 | 294 | |
nyatla | 69:8c5f220441f5 | 295 | //送信対象のメモリブロックを送信中に設定。 |
nyatla | 69:8c5f220441f5 | 296 | // b=(i_buf+1); |
nyatla | 69:8c5f220441f5 | 297 | //送信中のメモリブロックなら無視 |
nyatla | 92:4f77028cce64 | 298 | if(bh->is_lock){ |
nyatla | 69:8c5f220441f5 | 299 | return; |
nyatla | 69:8c5f220441f5 | 300 | } |
nyatla | 69:8c5f220441f5 | 301 | //送信中にセット |
nyatla | 92:4f77028cce64 | 302 | bh->is_lock=NyLPC_TUInt8_TRUE; |
nyatla | 69:8c5f220441f5 | 303 | |
nyatla | 69:8c5f220441f5 | 304 | //送信データのセット |
nyatla | 69:8c5f220441f5 | 305 | Index = LPC_EMAC->TxProduceIndex; |
nyatla | 69:8c5f220441f5 | 306 | if (i_size > ETH_FRAG_SIZE){ |
nyatla | 69:8c5f220441f5 | 307 | i_size = ETH_FRAG_SIZE; |
nyatla | 69:8c5f220441f5 | 308 | } |
nyatla | 69:8c5f220441f5 | 309 | //送信処理 |
nyatla | 92:4f77028cce64 | 310 | TX_DESC_PACKET( Index ) = ( unsigned long )i_buf; |
nyatla | 69:8c5f220441f5 | 311 | //See UM10360.pdf Table 181. Transmit descriptor control word |
nyatla | 69:8c5f220441f5 | 312 | TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT ); |
nyatla | 69:8c5f220441f5 | 313 | LPC_EMAC->TxProduceIndex = IndexNext; |
nyatla | 69:8c5f220441f5 | 314 | return; |
nyatla | 69:8c5f220441f5 | 315 | } |
nyatla | 69:8c5f220441f5 | 316 | /** |
nyatla | 69:8c5f220441f5 | 317 | * 送信デスクリプタを準備します。 |
nyatla | 69:8c5f220441f5 | 318 | */ |
nyatla | 69:8c5f220441f5 | 319 | static void prevTxDescriptor(void) |
nyatla | 69:8c5f220441f5 | 320 | { |
nyatla | 69:8c5f220441f5 | 321 | long x; |
nyatla | 69:8c5f220441f5 | 322 | //デスクリプタの設定 |
nyatla | 69:8c5f220441f5 | 323 | for( x = 0; x < NUM_TX_FRAG; x++ ) |
nyatla | 69:8c5f220441f5 | 324 | { |
nyatla | 69:8c5f220441f5 | 325 | TX_DESC_PACKET( x ) = ( unsigned long ) NULL; |
nyatla | 69:8c5f220441f5 | 326 | TX_DESC_CTRL( x ) = 0; |
nyatla | 69:8c5f220441f5 | 327 | TX_STAT_INFO( x ) = 0; |
nyatla | 69:8c5f220441f5 | 328 | } |
nyatla | 69:8c5f220441f5 | 329 | /* Set LPC_EMAC Transmit Descriptor Registers. */ |
nyatla | 69:8c5f220441f5 | 330 | LPC_EMAC->TxDescriptor =TX_DESC_BASE; |
nyatla | 69:8c5f220441f5 | 331 | LPC_EMAC->TxStatus = TX_STAT_BASE; |
nyatla | 69:8c5f220441f5 | 332 | LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1; |
nyatla | 69:8c5f220441f5 | 333 | } |
nyatla | 69:8c5f220441f5 | 334 | static void prevRxDescriptor(void) |
nyatla | 69:8c5f220441f5 | 335 | { |
nyatla | 69:8c5f220441f5 | 336 | int x; |
nyatla | 69:8c5f220441f5 | 337 | //デスクリプタの設定 |
nyatla | 69:8c5f220441f5 | 338 | for( x = 0; x < NUM_RX_FRAG; x++ ) |
nyatla | 69:8c5f220441f5 | 339 | { |
nyatla | 69:8c5f220441f5 | 340 | /* Allocate the next Ethernet buffer to this descriptor. */ |
nyatla | 69:8c5f220441f5 | 341 | RX_DESC_PACKET(x) = ETH_BUF(x); |
nyatla | 69:8c5f220441f5 | 342 | RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 ); |
nyatla | 69:8c5f220441f5 | 343 | RX_STAT_INFO(x) = 0; |
nyatla | 69:8c5f220441f5 | 344 | RX_STAT_HASHCRC(x) = 0; |
nyatla | 69:8c5f220441f5 | 345 | } |
nyatla | 69:8c5f220441f5 | 346 | |
nyatla | 69:8c5f220441f5 | 347 | /* Set LPC_EMAC Receive Descriptor Registers. */ |
nyatla | 69:8c5f220441f5 | 348 | LPC_EMAC->RxDescriptor = RX_DESC_BASE; |
nyatla | 69:8c5f220441f5 | 349 | LPC_EMAC->RxStatus = RX_STAT_BASE; |
nyatla | 69:8c5f220441f5 | 350 | LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1; |
nyatla | 69:8c5f220441f5 | 351 | |
nyatla | 69:8c5f220441f5 | 352 | } |
nyatla | 69:8c5f220441f5 | 353 | |
nyatla | 69:8c5f220441f5 | 354 | |
nyatla | 69:8c5f220441f5 | 355 | /** |
nyatla | 69:8c5f220441f5 | 356 | * 受信キューの先頭にあるRXフレームのポインタを返します。 |
nyatla | 69:8c5f220441f5 | 357 | * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。 |
nyatla | 69:8c5f220441f5 | 358 | * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。) |
nyatla | 69:8c5f220441f5 | 359 | * @return |
nyatla | 69:8c5f220441f5 | 360 | * 成功した場合、受信データを格納したバッファポインターです。 |
nyatla | 69:8c5f220441f5 | 361 | * 次回nextRxEthFrameを呼び出すまで有効です。 |
nyatla | 69:8c5f220441f5 | 362 | */ |
nyatla | 69:8c5f220441f5 | 363 | static void* getRxEthFrame(unsigned short* o_len_of_data) |
nyatla | 69:8c5f220441f5 | 364 | { |
nyatla | 69:8c5f220441f5 | 365 | if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) |
nyatla | 69:8c5f220441f5 | 366 | { |
nyatla | 69:8c5f220441f5 | 367 | //受信データを返却する。 |
nyatla | 69:8c5f220441f5 | 368 | *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3); |
nyatla | 69:8c5f220441f5 | 369 | return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex ); |
nyatla | 69:8c5f220441f5 | 370 | } |
nyatla | 69:8c5f220441f5 | 371 | return NULL; |
nyatla | 69:8c5f220441f5 | 372 | } |
nyatla | 69:8c5f220441f5 | 373 | |
nyatla | 69:8c5f220441f5 | 374 | |
nyatla | 69:8c5f220441f5 | 375 | /** |
nyatla | 69:8c5f220441f5 | 376 | * 受信キューを進行します。 |
nyatla | 69:8c5f220441f5 | 377 | */ |
nyatla | 69:8c5f220441f5 | 378 | static void nextRxEthFrame(void) |
nyatla | 69:8c5f220441f5 | 379 | { |
nyatla | 69:8c5f220441f5 | 380 | long lIndex; |
nyatla | 69:8c5f220441f5 | 381 | if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) |
nyatla | 69:8c5f220441f5 | 382 | { |
nyatla | 69:8c5f220441f5 | 383 | //キューすすめる。 |
nyatla | 69:8c5f220441f5 | 384 | lIndex = LPC_EMAC->RxConsumeIndex; |
nyatla | 69:8c5f220441f5 | 385 | lIndex++; |
nyatla | 69:8c5f220441f5 | 386 | if( lIndex >= NUM_RX_FRAG ) |
nyatla | 69:8c5f220441f5 | 387 | { |
nyatla | 69:8c5f220441f5 | 388 | lIndex = 0; |
nyatla | 69:8c5f220441f5 | 389 | } |
nyatla | 69:8c5f220441f5 | 390 | LPC_EMAC->RxConsumeIndex = lIndex; |
nyatla | 69:8c5f220441f5 | 391 | } |
nyatla | 69:8c5f220441f5 | 392 | } |
nyatla | 69:8c5f220441f5 | 393 | /******************************************************************************** |
nyatla | 69:8c5f220441f5 | 394 | * Private functions |
nyatla | 69:8c5f220441f5 | 395 | *******************************************************************************/ |
nyatla | 69:8c5f220441f5 | 396 | |
nyatla | 69:8c5f220441f5 | 397 | |
nyatla | 69:8c5f220441f5 | 398 | |
nyatla | 69:8c5f220441f5 | 399 | /** |
nyatla | 69:8c5f220441f5 | 400 | * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。 |
nyatla | 69:8c5f220441f5 | 401 | * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。 |
nyatla | 69:8c5f220441f5 | 402 | * @return |
nyatla | 69:8c5f220441f5 | 403 | * 次に書き込むことが出来る送信キュー。 |
nyatla | 69:8c5f220441f5 | 404 | */ |
nyatla | 69:8c5f220441f5 | 405 | static NyLPC_TUInt32 waitForTxEthFrameEmpty(void) |
nyatla | 69:8c5f220441f5 | 406 | { |
nyatla | 69:8c5f220441f5 | 407 | NyLPC_TUInt32 IndexNext; |
nyatla | 69:8c5f220441f5 | 408 | struct NyLPC_TTxBufferHeader *b; |
nyatla | 69:8c5f220441f5 | 409 | void* p; |
nyatla | 69:8c5f220441f5 | 410 | NyLPC_TUInt32 i; |
nyatla | 69:8c5f220441f5 | 411 | |
nyatla | 69:8c5f220441f5 | 412 | //送信キューの決定 |
nyatla | 69:8c5f220441f5 | 413 | IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG; |
nyatla | 69:8c5f220441f5 | 414 | |
nyatla | 69:8c5f220441f5 | 415 | //送信キューフルが解除されるまで待ち |
nyatla | 69:8c5f220441f5 | 416 | while(IndexNext == LPC_EMAC->TxConsumeIndex) |
nyatla | 69:8c5f220441f5 | 417 | { |
nyatla | 69:8c5f220441f5 | 418 | // |
nyatla | 69:8c5f220441f5 | 419 | NyLPC_cThread_sleep(emacSHORT_DELAY_MS); |
nyatla | 69:8c5f220441f5 | 420 | } |
nyatla | 69:8c5f220441f5 | 421 | |
nyatla | 69:8c5f220441f5 | 422 | //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去 |
nyatla | 69:8c5f220441f5 | 423 | for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG) |
nyatla | 69:8c5f220441f5 | 424 | { |
nyatla | 69:8c5f220441f5 | 425 | p=(void*)TX_DESC_PACKET(i); |
nyatla | 69:8c5f220441f5 | 426 | if(p!=NULL){ |
nyatla | 92:4f77028cce64 | 427 | b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); |
nyatla | 69:8c5f220441f5 | 428 | b->is_lock=NyLPC_TUInt8_FALSE; |
nyatla | 69:8c5f220441f5 | 429 | TX_DESC_PACKET(i)=0; |
nyatla | 69:8c5f220441f5 | 430 | } |
nyatla | 69:8c5f220441f5 | 431 | } |
nyatla | 69:8c5f220441f5 | 432 | p=(void*)TX_DESC_PACKET(i); |
nyatla | 69:8c5f220441f5 | 433 | if(p!=NULL){ |
nyatla | 92:4f77028cce64 | 434 | b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); |
nyatla | 69:8c5f220441f5 | 435 | b->is_lock=NyLPC_TUInt8_FALSE; |
nyatla | 69:8c5f220441f5 | 436 | TX_DESC_PACKET(i)=0; |
nyatla | 69:8c5f220441f5 | 437 | } |
nyatla | 69:8c5f220441f5 | 438 | return IndexNext; |
nyatla | 69:8c5f220441f5 | 439 | } |
nyatla | 69:8c5f220441f5 | 440 | |
nyatla | 69:8c5f220441f5 | 441 | //-------------------------------------------------------------------------------- |
nyatla | 69:8c5f220441f5 | 442 | // ISR |
nyatla | 69:8c5f220441f5 | 443 | //-------------------------------------------------------------------------------- |
nyatla | 69:8c5f220441f5 | 444 | |
nyatla | 69:8c5f220441f5 | 445 | static void ethernet_set_link(int speed, int duplex) { |
nyatla | 69:8c5f220441f5 | 446 | unsigned short phy_data; |
nyatla | 69:8c5f220441f5 | 447 | int tout; |
nyatla | 69:8c5f220441f5 | 448 | |
nyatla | 69:8c5f220441f5 | 449 | if((speed < 0) || (speed > 1)) { |
nyatla | 69:8c5f220441f5 | 450 | phy_data = PHY_AUTO_NEG; |
nyatla | 69:8c5f220441f5 | 451 | } else { |
nyatla | 69:8c5f220441f5 | 452 | phy_data = (((unsigned short) speed << 13) | |
nyatla | 69:8c5f220441f5 | 453 | ((unsigned short) duplex << 8)); |
nyatla | 69:8c5f220441f5 | 454 | } |
nyatla | 69:8c5f220441f5 | 455 | |
nyatla | 69:8c5f220441f5 | 456 | phy_write(PHY_REG_BMCR, phy_data); |
nyatla | 69:8c5f220441f5 | 457 | |
nyatla | 69:8c5f220441f5 | 458 | for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ |
nyatla | 69:8c5f220441f5 | 459 | |
nyatla | 69:8c5f220441f5 | 460 | switch(phy_id) { |
nyatla | 69:8c5f220441f5 | 461 | case DP83848C_ID: |
nyatla | 69:8c5f220441f5 | 462 | phy_data = phy_read(PHY_REG_STS); |
nyatla | 69:8c5f220441f5 | 463 | |
nyatla | 69:8c5f220441f5 | 464 | if(phy_data & PHY_STS_DUPLEX) { |
nyatla | 69:8c5f220441f5 | 465 | LPC_EMAC->MAC2 |= MAC2_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 466 | LPC_EMAC->Command |= CR_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 467 | LPC_EMAC->IPGT = IPGT_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 468 | } else { |
nyatla | 69:8c5f220441f5 | 469 | LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 470 | LPC_EMAC->Command &= ~CR_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 471 | LPC_EMAC->IPGT = IPGT_HALF_DUP; |
nyatla | 69:8c5f220441f5 | 472 | } |
nyatla | 69:8c5f220441f5 | 473 | |
nyatla | 69:8c5f220441f5 | 474 | if(phy_data & PHY_STS_SPEED) { |
nyatla | 69:8c5f220441f5 | 475 | LPC_EMAC->SUPP &= ~SUPP_SPEED; |
nyatla | 69:8c5f220441f5 | 476 | } else { |
nyatla | 69:8c5f220441f5 | 477 | LPC_EMAC->SUPP |= SUPP_SPEED; |
nyatla | 69:8c5f220441f5 | 478 | } |
nyatla | 69:8c5f220441f5 | 479 | break; |
nyatla | 69:8c5f220441f5 | 480 | |
nyatla | 69:8c5f220441f5 | 481 | case LAN8720_ID: |
nyatla | 69:8c5f220441f5 | 482 | phy_data = phy_read(PHY_REG_SCSR); |
nyatla | 69:8c5f220441f5 | 483 | |
nyatla | 69:8c5f220441f5 | 484 | if (phy_data & PHY_SCSR_DUPLEX) { |
nyatla | 69:8c5f220441f5 | 485 | LPC_EMAC->MAC2 |= MAC2_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 486 | LPC_EMAC->Command |= CR_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 487 | LPC_EMAC->IPGT = IPGT_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 488 | } else { |
nyatla | 69:8c5f220441f5 | 489 | LPC_EMAC->Command &= ~CR_FULL_DUP; |
nyatla | 69:8c5f220441f5 | 490 | LPC_EMAC->IPGT = IPGT_HALF_DUP; |
nyatla | 69:8c5f220441f5 | 491 | } |
nyatla | 69:8c5f220441f5 | 492 | |
nyatla | 69:8c5f220441f5 | 493 | if(phy_data & PHY_SCSR_100MBIT) { |
nyatla | 69:8c5f220441f5 | 494 | LPC_EMAC->SUPP |= SUPP_SPEED; |
nyatla | 69:8c5f220441f5 | 495 | } else { |
nyatla | 69:8c5f220441f5 | 496 | LPC_EMAC->SUPP &= ~SUPP_SPEED; |
nyatla | 69:8c5f220441f5 | 497 | } |
nyatla | 69:8c5f220441f5 | 498 | |
nyatla | 69:8c5f220441f5 | 499 | break; |
nyatla | 69:8c5f220441f5 | 500 | } |
nyatla | 69:8c5f220441f5 | 501 | } |
nyatla | 69:8c5f220441f5 | 502 | |
nyatla | 69:8c5f220441f5 | 503 | static int phy_write(unsigned int PhyReg, unsigned short Data) { |
nyatla | 69:8c5f220441f5 | 504 | unsigned int timeOut; |
nyatla | 69:8c5f220441f5 | 505 | |
nyatla | 69:8c5f220441f5 | 506 | LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; |
nyatla | 69:8c5f220441f5 | 507 | LPC_EMAC->MWTD = Data; |
nyatla | 69:8c5f220441f5 | 508 | |
nyatla | 69:8c5f220441f5 | 509 | for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ |
nyatla | 69:8c5f220441f5 | 510 | if((LPC_EMAC->MIND & MIND_BUSY) == 0) { |
nyatla | 69:8c5f220441f5 | 511 | return 0; |
nyatla | 69:8c5f220441f5 | 512 | } |
nyatla | 69:8c5f220441f5 | 513 | } |
nyatla | 69:8c5f220441f5 | 514 | |
nyatla | 69:8c5f220441f5 | 515 | return -1; |
nyatla | 69:8c5f220441f5 | 516 | } |
nyatla | 69:8c5f220441f5 | 517 | |
nyatla | 69:8c5f220441f5 | 518 | |
nyatla | 69:8c5f220441f5 | 519 | static int phy_read(unsigned int PhyReg) { |
nyatla | 69:8c5f220441f5 | 520 | unsigned int timeOut; |
nyatla | 69:8c5f220441f5 | 521 | |
nyatla | 69:8c5f220441f5 | 522 | LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; |
nyatla | 69:8c5f220441f5 | 523 | LPC_EMAC->MCMD = MCMD_READ; |
nyatla | 69:8c5f220441f5 | 524 | |
nyatla | 69:8c5f220441f5 | 525 | for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ |
nyatla | 69:8c5f220441f5 | 526 | if((LPC_EMAC->MIND & MIND_BUSY) == 0) { |
nyatla | 69:8c5f220441f5 | 527 | LPC_EMAC->MCMD = 0; |
nyatla | 69:8c5f220441f5 | 528 | return LPC_EMAC->MRDD; /* Return a 16-bit value. */ |
nyatla | 69:8c5f220441f5 | 529 | } |
nyatla | 69:8c5f220441f5 | 530 | } |
nyatla | 69:8c5f220441f5 | 531 | |
nyatla | 69:8c5f220441f5 | 532 | return -1; |
nyatla | 69:8c5f220441f5 | 533 | } |
nyatla | 69:8c5f220441f5 | 534 | |
nyatla | 69:8c5f220441f5 | 535 | |
nyatla | 69:8c5f220441f5 | 536 | //extern unsigned int SystemFrequency; |
nyatla | 69:8c5f220441f5 | 537 | static unsigned int clockselect(void) |
nyatla | 69:8c5f220441f5 | 538 | { |
nyatla | 69:8c5f220441f5 | 539 | if(SystemCoreClock < 10000000) { |
nyatla | 69:8c5f220441f5 | 540 | return 1; |
nyatla | 69:8c5f220441f5 | 541 | } else if(SystemCoreClock < 15000000) { |
nyatla | 69:8c5f220441f5 | 542 | return 2; |
nyatla | 69:8c5f220441f5 | 543 | } else if(SystemCoreClock < 20000000) { |
nyatla | 69:8c5f220441f5 | 544 | return 3; |
nyatla | 69:8c5f220441f5 | 545 | } else if(SystemCoreClock < 25000000) { |
nyatla | 69:8c5f220441f5 | 546 | return 4; |
nyatla | 69:8c5f220441f5 | 547 | } else if(SystemCoreClock < 35000000) { |
nyatla | 69:8c5f220441f5 | 548 | return 5; |
nyatla | 69:8c5f220441f5 | 549 | } else if(SystemCoreClock < 50000000) { |
nyatla | 69:8c5f220441f5 | 550 | return 6; |
nyatla | 69:8c5f220441f5 | 551 | } else if(SystemCoreClock < 70000000) { |
nyatla | 69:8c5f220441f5 | 552 | return 7; |
nyatla | 69:8c5f220441f5 | 553 | } else if(SystemCoreClock < 80000000) { |
nyatla | 69:8c5f220441f5 | 554 | return 8; |
nyatla | 69:8c5f220441f5 | 555 | } else if(SystemCoreClock < 90000000) { |
nyatla | 69:8c5f220441f5 | 556 | return 9; |
nyatla | 69:8c5f220441f5 | 557 | } else if(SystemCoreClock < 100000000) { |
nyatla | 69:8c5f220441f5 | 558 | return 10; |
nyatla | 69:8c5f220441f5 | 559 | } else if(SystemCoreClock < 120000000) { |
nyatla | 69:8c5f220441f5 | 560 | return 11; |
nyatla | 69:8c5f220441f5 | 561 | } else if(SystemCoreClock < 130000000) { |
nyatla | 69:8c5f220441f5 | 562 | return 12; |
nyatla | 69:8c5f220441f5 | 563 | } else if(SystemCoreClock < 140000000) { |
nyatla | 69:8c5f220441f5 | 564 | return 13; |
nyatla | 69:8c5f220441f5 | 565 | } else if(SystemCoreClock < 150000000) { |
nyatla | 69:8c5f220441f5 | 566 | return 15; |
nyatla | 69:8c5f220441f5 | 567 | } else if(SystemCoreClock < 160000000) { |
nyatla | 69:8c5f220441f5 | 568 | return 16; |
nyatla | 69:8c5f220441f5 | 569 | } else { |
nyatla | 69:8c5f220441f5 | 570 | return 0; |
nyatla | 69:8c5f220441f5 | 571 | } |
nyatla | 69:8c5f220441f5 | 572 | } |
nyatla | 69:8c5f220441f5 | 573 | |
nyatla | 69:8c5f220441f5 | 574 | static int ethernet_link(void) |
nyatla | 69:8c5f220441f5 | 575 | { |
nyatla | 69:8c5f220441f5 | 576 | |
nyatla | 69:8c5f220441f5 | 577 | if (phy_id == DP83848C_ID) { |
nyatla | 69:8c5f220441f5 | 578 | return (phy_read(PHY_REG_STS) & PHY_STS_LINK); |
nyatla | 69:8c5f220441f5 | 579 | } |
nyatla | 69:8c5f220441f5 | 580 | else { // LAN8720_ID |
nyatla | 69:8c5f220441f5 | 581 | return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); |
nyatla | 69:8c5f220441f5 | 582 | } |
nyatla | 69:8c5f220441f5 | 583 | } |
nyatla | 69:8c5f220441f5 | 584 | //-------------------------------------------------------------------------------- |
nyatla | 69:8c5f220441f5 | 585 | // ISR |
nyatla | 69:8c5f220441f5 | 586 | //-------------------------------------------------------------------------------- |
nyatla | 69:8c5f220441f5 | 587 | |
nyatla | 69:8c5f220441f5 | 588 | |
nyatla | 69:8c5f220441f5 | 589 | /** |
nyatla | 69:8c5f220441f5 | 590 | * EMACからのハンドラ |
nyatla | 69:8c5f220441f5 | 591 | */ |
nyatla | 69:8c5f220441f5 | 592 | static void emacIsrHandler(unsigned long i_status) |
nyatla | 69:8c5f220441f5 | 593 | { |
nyatla | 69:8c5f220441f5 | 594 | if( i_status & INT_RX_DONE ) |
nyatla | 69:8c5f220441f5 | 595 | { |
nyatla | 69:8c5f220441f5 | 596 | _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX); |
nyatla | 69:8c5f220441f5 | 597 | } |
nyatla | 69:8c5f220441f5 | 598 | if( i_status & INT_TX_DONE ) |
nyatla | 69:8c5f220441f5 | 599 | { |
nyatla | 69:8c5f220441f5 | 600 | _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX); |
nyatla | 69:8c5f220441f5 | 601 | } |
nyatla | 69:8c5f220441f5 | 602 | } |
nyatla | 69:8c5f220441f5 | 603 | |
nyatla | 69:8c5f220441f5 | 604 | #endif |
nyatla | 69:8c5f220441f5 | 605 | |
nyatla | 69:8c5f220441f5 | 606 | |
nyatla | 69:8c5f220441f5 | 607 |