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_LPC17xx.c
00001 /* 00002 * EthDev_LPC1769.c 00003 * 00004 * Created on: 2011/12/07 00005 * Author: nyatla 00006 */ 00007 #include "NyLPC_config.h" 00008 #if NyLPC_MCU==NyLPC_MCU_LPC17xx 00009 #include "LPC17xx.h" 00010 #include "EthDev_LPC17xx.h" 00011 #include "NyLPC_os.h" 00012 #include "LPC17xx.h" 00013 #include "../NyLPC_cEthernetMM.h" 00014 /* If no buffers are available, then wait this long before looking again.... */ 00015 #define emacBUFFER_WAIT_DELAY_MS 3 00016 #define emacBUFFER_WAIT_EMPTY_DELAY_MS 10 00017 #define emacSHORT_DELAY_MS 10 00018 //-------------------------------------------------- 00019 // common function. 00020 //-------------------------------------------------- 00021 00022 00023 00024 /** 00025 * 送信デスクリプタを準備します。 00026 */ 00027 void EthDev_LPC17xx_prevTxDescriptor(void) 00028 { 00029 long x; 00030 //デスクリプタの設定 00031 for( x = 0; x < NUM_TX_FRAG; x++ ) 00032 { 00033 TX_DESC_PACKET( x ) = ( unsigned long ) NULL; 00034 TX_DESC_CTRL( x ) = 0; 00035 TX_STAT_INFO( x ) = 0; 00036 } 00037 /* Set LPC_EMAC Transmit Descriptor Registers. */ 00038 LPC_EMAC->TxDescriptor = TX_DESC_BASE; 00039 LPC_EMAC->TxStatus = TX_STAT_BASE; 00040 LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1; 00041 } 00042 00043 00044 /** 00045 * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。 00046 * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。 00047 * @return 00048 * 次に書き込むことが出来る送信キュー。 00049 */ 00050 static NyLPC_TUInt32 waitForTxEthFrameEmpty(void) 00051 { 00052 NyLPC_TUInt32 IndexNext; 00053 struct NyLPC_TTxBufferHeader *b; 00054 void* p; 00055 NyLPC_TUInt32 i; 00056 00057 //送信キューの決定 00058 IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG; 00059 00060 //送信キューフルが解除されるまで待ち 00061 while(IndexNext == LPC_EMAC->TxConsumeIndex) 00062 { 00063 // 00064 NyLPC_cThread_sleep(emacBUFFER_WAIT_EMPTY_DELAY_MS); 00065 } 00066 00067 //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去 00068 for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG) 00069 { 00070 p=(void*)TX_DESC_PACKET(i); 00071 if(p!=NULL){ 00072 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); 00073 b->is_lock=NyLPC_TUInt8_FALSE; 00074 TX_DESC_PACKET(i)=0; 00075 } 00076 } 00077 p=(void*)TX_DESC_PACKET(i); 00078 if(p!=NULL){ 00079 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p); 00080 b->is_lock=NyLPC_TUInt8_FALSE; 00081 TX_DESC_PACKET(i)=0; 00082 } 00083 return IndexNext; 00084 } 00085 00086 void EthDev_LPC17xx_processTx(void) 00087 { 00088 waitForTxEthFrameEmpty(); 00089 } 00090 00091 /** 00092 * Ethernetパケットを送信します。 00093 * allocTxBufで得たバッファを指定すること。 00094 * <p>関数仕様</p> 00095 * この関数は、i_bufが 00096 * </div> 00097 */ 00098 void EthDev_LPC17xx_sendTxEthFrame(void* i_buf,unsigned short i_size) 00099 { 00100 NyLPC_TUInt32 IndexNext,Index; 00101 struct NyLPC_TTxBufferHeader* bh=NyLPC_TTxBufferHeader_getBufferHeaderAddr(i_buf); 00102 //サイズ0なら送信の必要なし 00103 if(i_size == 0) 00104 { 00105 return; 00106 } 00107 //送信デスクリプタの反映 00108 IndexNext =waitForTxEthFrameEmpty(); 00109 00110 //送信対象のメモリブロックを送信中に設定。 00111 // b=(i_buf+1); 00112 //送信中のメモリブロックなら無視 00113 if(bh->is_lock){ 00114 return; 00115 } 00116 //送信中にセット 00117 bh->is_lock=NyLPC_TUInt8_TRUE; 00118 00119 //送信データのセット 00120 Index = LPC_EMAC->TxProduceIndex; 00121 if (i_size > ETH_FRAG_SIZE){ 00122 i_size = ETH_FRAG_SIZE; 00123 } 00124 00125 //送信処理 00126 TX_DESC_PACKET( Index ) = ( unsigned long )i_buf; 00127 //See UM10360.pdf Table 181. Transmit descriptor control word 00128 TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT ); 00129 LPC_EMAC->TxProduceIndex = IndexNext; 00130 return; 00131 } 00132 00133 /*********************************************************************** 00134 * RXバッファ 00135 ***********************************************************************/ 00136 00137 void EthDev_LPC17xx_prevRxDescriptor(void) 00138 { 00139 int x; 00140 //デスクリプタの設定 00141 for( x = 0; x < NUM_RX_FRAG; x++ ) 00142 { 00143 /* Allocate the next Ethernet buffer to this descriptor. */ 00144 RX_DESC_PACKET(x) = ETH_BUF(x); 00145 RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 ); 00146 RX_STAT_INFO(x) = 0; 00147 RX_STAT_HASHCRC(x) = 0; 00148 } 00149 00150 /* Set LPC_EMAC Receive Descriptor Registers. */ 00151 LPC_EMAC->RxDescriptor = RX_DESC_BASE; 00152 LPC_EMAC->RxStatus = RX_STAT_BASE; 00153 LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1; 00154 00155 } 00156 00157 00158 /** 00159 * 受信キューの先頭にあるRXフレームのポインタを返します。 00160 * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。 00161 * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。) 00162 * @return 00163 * 成功した場合、受信データを格納したバッファポインターです。 00164 * 次回nextRxEthFrameを呼び出すまで有効です。 00165 */ 00166 void* EthDev_LPC17xx_getRxEthFrame(unsigned short* o_len_of_data) 00167 { 00168 00169 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) 00170 { 00171 //受信データを返却する。 00172 *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3); 00173 return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex ); 00174 } 00175 return NULL; 00176 } 00177 00178 00179 /** 00180 * 受信キューを進行します。 00181 */ 00182 void EthDev_LPC17xx_nextRxEthFrame(void) 00183 { 00184 long lIndex; 00185 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) 00186 { 00187 //キューすすめる。 00188 lIndex = LPC_EMAC->RxConsumeIndex; 00189 lIndex++; 00190 if( lIndex >= NUM_RX_FRAG ) 00191 { 00192 lIndex = 0; 00193 } 00194 LPC_EMAC->RxConsumeIndex = lIndex; 00195 } 00196 } 00197 00198 00199 /*-----------------------------------------------------------*/ 00200 00201 00202 /*-----------------------------------------------------------*/ 00203 #define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */ 00204 00205 NyLPC_TBool EthDev_LPC17xx_prvWritePHY( long lPhyReg, long lValue ) 00206 { 00207 const long lMaxTime = 10; 00208 long x; 00209 00210 LPC_EMAC->MCMD = 0; 00211 LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | lPhyReg; 00212 LPC_EMAC->MWTD = lValue; 00213 00214 for( x = 0; x < lMaxTime; x++ ) 00215 { 00216 if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) 00217 { 00218 /* Operation has finished. */ 00219 break; 00220 } 00221 00222 NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); 00223 } 00224 00225 if( x < lMaxTime ) 00226 { 00227 return NyLPC_TBool_TRUE; 00228 } 00229 else 00230 { 00231 return NyLPC_TBool_FALSE; 00232 } 00233 } 00234 /*-----------------------------------------------------------*/ 00235 00236 unsigned short EthDev_LPC17xx_prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool* plStatus ) 00237 { 00238 long x; 00239 const long lMaxTime = 10; 00240 00241 LPC_EMAC->MCMD = 1; 00242 LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | ucPhyReg; 00243 LPC_EMAC->MCMD = MCMD_READ; 00244 00245 for( x = 0; x < lMaxTime; x++ ) 00246 { 00247 /* Operation has finished. */ 00248 if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) 00249 { 00250 break; 00251 } 00252 NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); 00253 } 00254 00255 LPC_EMAC->MCMD = 0; 00256 00257 if( x >= lMaxTime ) 00258 { 00259 *plStatus = NyLPC_TBool_FALSE; 00260 } 00261 00262 return( LPC_EMAC->MRDD ); 00263 } 00264 00265 00266 00267 00268 00269 00270 00271 00272 #endif 00273
Generated on Tue Jul 12 2022 16:22:56 by
1.7.2
