This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EthDev_LPC17xx.c Source File

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