Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
EthDev_LPC4088.c
00001 #include "NyLPC_config.h" 00002 #if NyLPC_MCU==NyLPC_MCU_LPC4088 00003 #include "NyLPC_os.h" 00004 #include "copy_of_ethernet_api.h" 00005 #include "NyLPC_IEthernetDevice.h" 00006 #include "NyLPC_cEthernetMM.h" 00007 00008 00009 00010 #define emacSHORT_DELAY_MS 10 00011 #ifndef configEMAC_INTERRUPT_PRIORITY 00012 #define configEMAC_INTERRUPT_PRIORITY 5 00013 #endif 00014 //////////////////////////////////////////////////////////////////////////////// 00015 // Ethernet Memory 00016 //////////////////////////////////////////////////////////////////////////////// 00017 00018 #define AHB_SRAM_BANK1_BASE 0x20004000UL 00019 #define RX_DESC_BASE (AHB_SRAM_BANK1_BASE ) 00020 #define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */ 00021 #define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */ 00022 #define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */ 00023 #define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */ 00024 00025 /** 00026 * 消費メモリ量は、 00027 * descriptor = NUM_RX_FRAG*16+NUM_TX_FRAG*12. 00028 * EthnetBuf=ETH_FRAG_SIZE*NUM_RX_FRAG 00029 */ 00030 00031 /* RX and TX descriptor and status definitions. */ 00032 #define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) 00033 #define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) 00034 #define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) 00035 #define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) 00036 #define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) 00037 #define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) 00038 #define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) 00039 #define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i ) 00040 #define ETH_TX_BUF_BASE ((void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG)) 00041 00042 00043 #define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500 00044 00045 //////////////////////////////////////////////////////////////////////////////// 00046 // Ethernet interdface functions 00047 //////////////////////////////////////////////////////////////////////////////// 00048 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); 00049 static void stop(void); 00050 static void* getRxEthFrame(unsigned short* o_len_of_data); 00051 static void nextRxEthFrame(void); 00052 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); 00053 static void releaseTxBuf(void* i_buf); 00054 static void sendTxEthFrame(void* i_buf,unsigned short i_size); 00055 static void processTx(void); 00056 00057 //////////////////////////////////////////////////////////////////////////////// 00058 // Private 00059 //////////////////////////////////////////////////////////////////////////////// 00060 static void emacIsrHandler(unsigned long i_status); 00061 static unsigned int clockselect(void); 00062 static int ethernet_link(void); 00063 static int phy_write(unsigned int PhyReg, unsigned short Data); 00064 static int phy_read(unsigned int PhyReg); 00065 static void prevTxDescriptor(void); 00066 static void prevRxDescriptor(void); 00067 static NyLPC_TUInt32 waitForTxEthFrameEmpty(void); 00068 00069 /*-----------------------------------------------------------*/ 00070 00071 00072 const static struct TiEthernetDevice _interface_LAN8720= 00073 { 00074 "LAN8720", 00075 start, 00076 stop, 00077 getRxEthFrame, 00078 nextRxEthFrame, 00079 allocTxBuf, 00080 releaseTxBuf, 00081 sendTxEthFrame, 00082 processTx 00083 }; 00084 const static struct TiEthernetDevice _interface_DP83848C= 00085 { 00086 "DP83848C", 00087 start, 00088 stop, 00089 getRxEthFrame, 00090 nextRxEthFrame, 00091 allocTxBuf, 00092 releaseTxBuf, 00093 sendTxEthFrame, 00094 processTx 00095 }; 00096 00097 static void* _event_param; 00098 static NyLPC_TiEthernetDevice_onEvent _event_handler; 00099 static unsigned int phy_id; 00100 00101 /* 00102 * EthernetDeviceのファクトリー関数。インターフェイスを生成できればtrue 00103 * 00104 */ 00105 NyLPC_TBool EthDev_LPC4088_getInterface( 00106 const struct TiEthernetDevice** o_dev) 00107 { 00108 int regv, tout; 00109 unsigned int clock = clockselect(); 00110 00111 LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ 00112 LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ 00113 LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */ 00114 LPC_IOCON->P1_1 &= ~0x07; 00115 LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */ 00116 LPC_IOCON->P1_4 &= ~0x07; 00117 LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */ 00118 LPC_IOCON->P1_8 &= ~0x07; 00119 LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */ 00120 LPC_IOCON->P1_9 &= ~0x07; 00121 LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */ 00122 LPC_IOCON->P1_10 &= ~0x07; 00123 LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */ 00124 LPC_IOCON->P1_14 &= ~0x07; 00125 LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */ 00126 LPC_IOCON->P1_15 &= ~0x07; 00127 LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */ 00128 LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ 00129 LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */ 00130 LPC_IOCON->P1_17 &= ~0x07; 00131 LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */ 00132 00133 /* Reset all EMAC internal modules. */ 00134 LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; 00135 LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; 00136 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00137 00138 /* Initialize MAC control registers. */ 00139 LPC_EMAC->MAC1 = MAC1_PASS_ALL; 00140 LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; 00141 LPC_EMAC->MAXF = ETH_MAX_FLEN; 00142 LPC_EMAC->CLRT = CLRT_DEF; 00143 LPC_EMAC->IPGR = IPGR_DEF; 00144 00145 /* Enable Reduced MII interface. */ 00146 LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ 00147 LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ 00148 LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM |CR_PASS_RX_FILT; /* Enable Reduced MII interface. */ 00149 00150 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00151 00152 LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; 00153 LPC_EMAC->MCMD = 0; 00154 LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ 00155 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00156 LPC_EMAC->SUPP = SUPP_SPEED; 00157 00158 phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ 00159 for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ 00160 regv = phy_read(PHY_REG_BMCR); 00161 if(regv < 0 || tout == 0) { 00162 return NyLPC_TBool_FALSE; /* Error */ 00163 } 00164 if(!(regv & PHY_BMCR_RESET)) { 00165 break; /* Reset complete. */ 00166 } 00167 } 00168 00169 phy_id = (phy_read(PHY_REG_IDR1) << 16); 00170 phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); 00171 00172 switch(phy_id){ 00173 case DP83848C_ID: 00174 *o_dev=&_interface_DP83848C; 00175 break; 00176 case LAN8720_ID: 00177 *o_dev=&_interface_LAN8720; 00178 break; 00179 default: 00180 return NyLPC_TBool_FALSE; /* Error */ 00181 } 00182 LPC_EMAC->TxProduceIndex = 0; 00183 LPC_EMAC->RxConsumeIndex = 0; 00184 return NyLPC_TBool_TRUE; 00185 } 00186 00187 00188 00189 static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param) 00190 { 00191 int i; 00192 //ISRw割り込み設定 00193 NyLPC_cIsr_setEnetISR(emacIsrHandler); 00194 _event_handler=i_handler; 00195 _event_param=i_param; 00196 /* Set the Ethernet MAC Address registers */ 00197 LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1]; 00198 LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3]; 00199 LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5]; 00200 00201 //TXメモリマネージャの準備 00202 NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE); 00203 /* Initialize Tx and Rx DMA Descriptors */ 00204 prevRxDescriptor(); 00205 prevTxDescriptor(); 00206 //wait for link up 00207 for(i=0;i<5;i++){ 00208 if(ethernet_link()!=0){ 00209 break; 00210 } 00211 NyLPC_cThread_sleep(emacWAIT_FOR_LINK_TO_ESTABLISH_MS); 00212 } 00213 00214 //setup Link 00215 ethernet_set_link(-1, 0); 00216 00217 LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; 00218 /* Receive Broadcast, Perfect Match Packets */ 00219 00220 //Ethernetの割込み開始設定 00221 NyLPC_cIsr_enterCritical(); 00222 { 00223 LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ 00224 LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ 00225 00226 LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ 00227 LPC_EMAC->MAC1 |= MAC1_REC_EN; 00228 00229 NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); 00230 NVIC_EnableIRQ( ENET_IRQn ); 00231 } 00232 NyLPC_cIsr_exitCritical(); 00233 00234 return NyLPC_TBool_TRUE; 00235 } 00236 00237 00238 static void stop(void) 00239 { 00240 NyLPC_cIsr_enterCritical(); 00241 { 00242 LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); 00243 LPC_EMAC->IntClear = 0xFFFF; 00244 00245 NVIC_DisableIRQ( ENET_IRQn ); 00246 } 00247 NyLPC_cIsr_exitCritical(); 00248 LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN ); 00249 LPC_EMAC->MAC1 &= ~MAC1_REC_EN; 00250 //ISR割り込み解除 00251 NyLPC_cIsr_setEnetISR(NULL); 00252 //TXメモリマネージャの終了 00253 NyLPC_cEthernetMM_finalize(); 00254 } 00255 00256 static void* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) 00257 { 00258 return NyLPC_cEthernetMM_alloc(i_hint,o_size); 00259 } 00260 static void releaseTxBuf(void* i_buf) 00261 { 00262 NyLPC_cEthernetMM_release(i_buf); 00263 } 00264 00265 00266 /** 00267 */ 00268 static void processTx(void) 00269 { 00270 waitForTxEthFrameEmpty(); 00271 } 00272 00273 00274 00275 /** 00276 * Ethernetパケットを送信します。 00277 * allocTxBufで得たバッファを指定すること。 00278 * <p>関数仕様</p> 00279 * この関数は、i_bufが 00280 * </div> 00281 */ 00282 static void sendTxEthFrame(void* i_buf,unsigned short i_size) 00283 { 00284 NyLPC_TUInt32 IndexNext,Index; 00285 struct NyLPC_TTxBufferHeader* bh=NyLPC_TTxBufferHeader_getBufferHeaderAddr(i_buf); 00286 00287 //サイズ0なら送信の必要なし 00288 if(i_size == 0) 00289 { 00290 return; 00291 } 00292 //送信デスクリプタの反映 00293 IndexNext =waitForTxEthFrameEmpty(); 00294 00295 //送信対象のメモリブロックを送信中に設定。 00296 // b=(i_buf+1); 00297 //送信中のメモリブロックなら無視 00298 if(bh->is_lock){ 00299 return; 00300 } 00301 //送信中にセット 00302 bh->is_lock=NyLPC_TUInt8_TRUE; 00303 00304 //送信データのセット 00305 Index = LPC_EMAC->TxProduceIndex; 00306 if (i_size > ETH_FRAG_SIZE){ 00307 i_size = ETH_FRAG_SIZE; 00308 } 00309 //送信処理 00310 TX_DESC_PACKET( Index ) = ( unsigned long )i_buf; 00311 //See UM10360.pdf Table 181. Transmit descriptor control word 00312 TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT ); 00313 LPC_EMAC->TxProduceIndex = IndexNext; 00314 return; 00315 } 00316 /** 00317 * 送信デスクリプタを準備します。 00318 */ 00319 static void prevTxDescriptor(void) 00320 { 00321 long x; 00322 //デスクリプタの設定 00323 for( x = 0; x < NUM_TX_FRAG; x++ ) 00324 { 00325 TX_DESC_PACKET( x ) = ( unsigned long ) NULL; 00326 TX_DESC_CTRL( x ) = 0; 00327 TX_STAT_INFO( x ) = 0; 00328 } 00329 /* Set LPC_EMAC Transmit Descriptor Registers. */ 00330 LPC_EMAC->TxDescriptor =TX_DESC_BASE; 00331 LPC_EMAC->TxStatus = TX_STAT_BASE; 00332 LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1; 00333 } 00334 static void prevRxDescriptor(void) 00335 { 00336 int x; 00337 //デスクリプタの設定 00338 for( x = 0; x < NUM_RX_FRAG; x++ ) 00339 { 00340 /* Allocate the next Ethernet buffer to this descriptor. */ 00341 RX_DESC_PACKET(x) = ETH_BUF(x); 00342 RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 ); 00343 RX_STAT_INFO(x) = 0; 00344 RX_STAT_HASHCRC(x) = 0; 00345 } 00346 00347 /* Set LPC_EMAC Receive Descriptor Registers. */ 00348 LPC_EMAC->RxDescriptor = RX_DESC_BASE; 00349 LPC_EMAC->RxStatus = RX_STAT_BASE; 00350 LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1; 00351 00352 } 00353 00354 00355 /** 00356 * 受信キューの先頭にあるRXフレームのポインタを返します。 00357 * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。 00358 * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。) 00359 * @return 00360 * 成功した場合、受信データを格納したバッファポインターです。 00361 * 次回nextRxEthFrameを呼び出すまで有効です。 00362 */ 00363 static void* getRxEthFrame(unsigned short* o_len_of_data) 00364 { 00365 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) 00366 { 00367 //受信データを返却する。 00368 *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3); 00369 return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex ); 00370 } 00371 return NULL; 00372 } 00373 00374 00375 /** 00376 * 受信キューを進行します。 00377 */ 00378 static void nextRxEthFrame(void) 00379 { 00380 long lIndex; 00381 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) 00382 { 00383 //キューすすめる。 00384 lIndex = LPC_EMAC->RxConsumeIndex; 00385 lIndex++; 00386 if( lIndex >= NUM_RX_FRAG ) 00387 { 00388 lIndex = 0; 00389 } 00390 LPC_EMAC->RxConsumeIndex = lIndex; 00391 } 00392 } 00393 /******************************************************************************** 00394 * Private functions 00395 *******************************************************************************/ 00396 00397 00398 00399 /** 00400 * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。 00401 * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。 00402 * @return 00403 * 次に書き込むことが出来る送信キュー。 00404 */ 00405 static NyLPC_TUInt32 waitForTxEthFrameEmpty(void) 00406 { 00407 NyLPC_TUInt32 IndexNext; 00408 struct NyLPC_TTxBufferHeader *b; 00409 void* p; 00410 NyLPC_TUInt32 i; 00411 00412 //送信キューの決定 00413 IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG; 00414 00415 //送信キューフルが解除されるまで待ち 00416 while(IndexNext == LPC_EMAC->TxConsumeIndex) 00417 { 00418 // 00419 NyLPC_cThread_sleep(emacSHORT_DELAY_MS); 00420 } 00421 00422 //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去 00423 for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG) 00424 { 00425 p=(void*)TX_DESC_PACKET(i); 00426 if(p!=NULL){ 00427 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); 00428 b->is_lock=NyLPC_TUInt8_FALSE; 00429 TX_DESC_PACKET(i)=0; 00430 } 00431 } 00432 p=(void*)TX_DESC_PACKET(i); 00433 if(p!=NULL){ 00434 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); 00435 b->is_lock=NyLPC_TUInt8_FALSE; 00436 TX_DESC_PACKET(i)=0; 00437 } 00438 return IndexNext; 00439 } 00440 00441 //-------------------------------------------------------------------------------- 00442 // ISR 00443 //-------------------------------------------------------------------------------- 00444 00445 static void ethernet_set_link(int speed, int duplex) { 00446 unsigned short phy_data; 00447 int tout; 00448 00449 if((speed < 0) || (speed > 1)) { 00450 phy_data = PHY_AUTO_NEG; 00451 } else { 00452 phy_data = (((unsigned short) speed << 13) | 00453 ((unsigned short) duplex << 8)); 00454 } 00455 00456 phy_write(PHY_REG_BMCR, phy_data); 00457 00458 for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ 00459 00460 switch(phy_id) { 00461 case DP83848C_ID: 00462 phy_data = phy_read(PHY_REG_STS); 00463 00464 if(phy_data & PHY_STS_DUPLEX) { 00465 LPC_EMAC->MAC2 |= MAC2_FULL_DUP; 00466 LPC_EMAC->Command |= CR_FULL_DUP; 00467 LPC_EMAC->IPGT = IPGT_FULL_DUP; 00468 } else { 00469 LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; 00470 LPC_EMAC->Command &= ~CR_FULL_DUP; 00471 LPC_EMAC->IPGT = IPGT_HALF_DUP; 00472 } 00473 00474 if(phy_data & PHY_STS_SPEED) { 00475 LPC_EMAC->SUPP &= ~SUPP_SPEED; 00476 } else { 00477 LPC_EMAC->SUPP |= SUPP_SPEED; 00478 } 00479 break; 00480 00481 case LAN8720_ID: 00482 phy_data = phy_read(PHY_REG_SCSR); 00483 00484 if (phy_data & PHY_SCSR_DUPLEX) { 00485 LPC_EMAC->MAC2 |= MAC2_FULL_DUP; 00486 LPC_EMAC->Command |= CR_FULL_DUP; 00487 LPC_EMAC->IPGT = IPGT_FULL_DUP; 00488 } else { 00489 LPC_EMAC->Command &= ~CR_FULL_DUP; 00490 LPC_EMAC->IPGT = IPGT_HALF_DUP; 00491 } 00492 00493 if(phy_data & PHY_SCSR_100MBIT) { 00494 LPC_EMAC->SUPP |= SUPP_SPEED; 00495 } else { 00496 LPC_EMAC->SUPP &= ~SUPP_SPEED; 00497 } 00498 00499 break; 00500 } 00501 } 00502 00503 static int phy_write(unsigned int PhyReg, unsigned short Data) { 00504 unsigned int timeOut; 00505 00506 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; 00507 LPC_EMAC->MWTD = Data; 00508 00509 for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ 00510 if((LPC_EMAC->MIND & MIND_BUSY) == 0) { 00511 return 0; 00512 } 00513 } 00514 00515 return -1; 00516 } 00517 00518 00519 static int phy_read(unsigned int PhyReg) { 00520 unsigned int timeOut; 00521 00522 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; 00523 LPC_EMAC->MCMD = MCMD_READ; 00524 00525 for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ 00526 if((LPC_EMAC->MIND & MIND_BUSY) == 0) { 00527 LPC_EMAC->MCMD = 0; 00528 return LPC_EMAC->MRDD; /* Return a 16-bit value. */ 00529 } 00530 } 00531 00532 return -1; 00533 } 00534 00535 00536 //extern unsigned int SystemFrequency; 00537 static unsigned int clockselect(void) 00538 { 00539 if(SystemCoreClock < 10000000) { 00540 return 1; 00541 } else if(SystemCoreClock < 15000000) { 00542 return 2; 00543 } else if(SystemCoreClock < 20000000) { 00544 return 3; 00545 } else if(SystemCoreClock < 25000000) { 00546 return 4; 00547 } else if(SystemCoreClock < 35000000) { 00548 return 5; 00549 } else if(SystemCoreClock < 50000000) { 00550 return 6; 00551 } else if(SystemCoreClock < 70000000) { 00552 return 7; 00553 } else if(SystemCoreClock < 80000000) { 00554 return 8; 00555 } else if(SystemCoreClock < 90000000) { 00556 return 9; 00557 } else if(SystemCoreClock < 100000000) { 00558 return 10; 00559 } else if(SystemCoreClock < 120000000) { 00560 return 11; 00561 } else if(SystemCoreClock < 130000000) { 00562 return 12; 00563 } else if(SystemCoreClock < 140000000) { 00564 return 13; 00565 } else if(SystemCoreClock < 150000000) { 00566 return 15; 00567 } else if(SystemCoreClock < 160000000) { 00568 return 16; 00569 } else { 00570 return 0; 00571 } 00572 } 00573 00574 static int ethernet_link(void) 00575 { 00576 00577 if (phy_id == DP83848C_ID) { 00578 return (phy_read(PHY_REG_STS) & PHY_STS_LINK); 00579 } 00580 else { // LAN8720_ID 00581 return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); 00582 } 00583 } 00584 //-------------------------------------------------------------------------------- 00585 // ISR 00586 //-------------------------------------------------------------------------------- 00587 00588 00589 /** 00590 * EMACからのハンドラ 00591 */ 00592 static void emacIsrHandler(unsigned long i_status) 00593 { 00594 if( i_status & INT_RX_DONE ) 00595 { 00596 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX); 00597 } 00598 if( i_status & INT_TX_DONE ) 00599 { 00600 _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX); 00601 } 00602 } 00603 00604 #endif 00605 00606 00607
Generated on Tue Jul 12 2022 16:22:56 by
1.7.2
