This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
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 15:46:14 by 1.7.2