4 * Created on: 2011/12/07
\r
7 #include "NyLPC_config.h"
\r
8 #if NyLPC_MCU==NyLPC_MCU_LPC17xx
\r
10 #include "EthDev_LPC17xx.h"
\r
11 #include "NyLPC_os.h"
\r
12 #include "LPC17xx.h"
\r
13 #include "../NyLPC_cEthernetMM.h"
\r
14 /* If no buffers are available, then wait this long before looking again.... */
\r
15 #define emacBUFFER_WAIT_DELAY_MS 3
\r
16 #define emacBUFFER_WAIT_EMPTY_DELAY_MS 10
\r
17 #define emacSHORT_DELAY_MS 10
\r
18 //--------------------------------------------------
\r
20 //--------------------------------------------------
\r
27 void EthDev_LPC17xx_prevTxDescriptor(void)
\r
31 for( x = 0; x < NUM_TX_FRAG; x++ )
\r
33 TX_DESC_PACKET( x ) = ( unsigned long ) NULL;
\r
34 TX_DESC_CTRL( x ) = 0;
\r
35 TX_STAT_INFO( x ) = 0;
\r
37 /* Set LPC_EMAC Transmit Descriptor Registers. */
\r
38 LPC_EMAC->TxDescriptor = TX_DESC_BASE;
\r
39 LPC_EMAC->TxStatus = TX_STAT_BASE;
\r
40 LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;
\r
45 * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。
\r
46 * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。
\r
48 * 次に書き込むことが出来る送信キュー。
\r
50 static NyLPC_TUInt32 waitForTxEthFrameEmpty(void)
\r
52 NyLPC_TUInt32 IndexNext;
\r
53 struct NyLPC_TTxBufferHeader *b;
\r
58 IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG;
\r
61 while(IndexNext == LPC_EMAC->TxConsumeIndex)
\r
64 NyLPC_cThread_sleep(emacBUFFER_WAIT_EMPTY_DELAY_MS);
\r
67 //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去
\r
68 for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG)
\r
70 p=(void*)TX_DESC_PACKET(i);
\r
72 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p);
\r
73 b->is_lock=NyLPC_TUInt8_FALSE;
\r
74 TX_DESC_PACKET(i)=0;
\r
77 p=(void*)TX_DESC_PACKET(i);
\r
79 b=NyLPC_TTxBufferHeader_getBufferHeaderAddr(p);
\r
80 b->is_lock=NyLPC_TUInt8_FALSE;
\r
81 TX_DESC_PACKET(i)=0;
\r
86 void EthDev_LPC17xx_processTx(void)
\r
88 waitForTxEthFrameEmpty();
\r
92 * Ethernetパケットを送信します。
\r
93 * allocTxBufで得たバッファを指定すること。
\r
98 void EthDev_LPC17xx_sendTxEthFrame(void* i_buf,unsigned short i_size)
\r
100 NyLPC_TUInt32 IndexNext,Index;
\r
101 struct NyLPC_TTxBufferHeader* bh=NyLPC_TTxBufferHeader_getBufferHeaderAddr(i_buf);
\r
108 IndexNext =waitForTxEthFrameEmpty();
\r
110 //送信対象のメモリブロックを送信中に設定。
\r
117 bh->is_lock=NyLPC_TUInt8_TRUE;
\r
120 Index = LPC_EMAC->TxProduceIndex;
\r
121 if (i_size > ETH_FRAG_SIZE){
\r
122 i_size = ETH_FRAG_SIZE;
\r
126 TX_DESC_PACKET( Index ) = ( unsigned long )i_buf;
\r
127 //See UM10360.pdf Table 181. Transmit descriptor control word
\r
128 TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT );
\r
129 LPC_EMAC->TxProduceIndex = IndexNext;
\r
133 /***********************************************************************
\r
135 ***********************************************************************/
\r
137 void EthDev_LPC17xx_prevRxDescriptor(void)
\r
141 for( x = 0; x < NUM_RX_FRAG; x++ )
\r
143 /* Allocate the next Ethernet buffer to this descriptor. */
\r
144 RX_DESC_PACKET(x) = ETH_BUF(x);
\r
145 RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );
\r
146 RX_STAT_INFO(x) = 0;
\r
147 RX_STAT_HASHCRC(x) = 0;
\r
150 /* Set LPC_EMAC Receive Descriptor Registers. */
\r
151 LPC_EMAC->RxDescriptor = RX_DESC_BASE;
\r
152 LPC_EMAC->RxStatus = RX_STAT_BASE;
\r
153 LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;
\r
159 * 受信キューの先頭にあるRXフレームのポインタを返します。
\r
160 * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。
\r
161 * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。)
\r
163 * 成功した場合、受信データを格納したバッファポインターです。
\r
164 * 次回nextRxEthFrameを呼び出すまで有効です。
\r
166 void* EthDev_LPC17xx_getRxEthFrame(unsigned short* o_len_of_data)
\r
169 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex )
\r
172 *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3);
\r
173 return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex );
\r
182 void EthDev_LPC17xx_nextRxEthFrame(void)
\r
185 if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex )
\r
188 lIndex = LPC_EMAC->RxConsumeIndex;
\r
190 if( lIndex >= NUM_RX_FRAG )
\r
194 LPC_EMAC->RxConsumeIndex = lIndex;
\r
199 /*-----------------------------------------------------------*/
\r
202 /*-----------------------------------------------------------*/
\r
203 #define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */
\r
205 NyLPC_TBool EthDev_LPC17xx_prvWritePHY( long lPhyReg, long lValue )
\r
207 const long lMaxTime = 10;
\r
210 LPC_EMAC->MCMD = 0;
\r
211 LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | lPhyReg;
\r
212 LPC_EMAC->MWTD = lValue;
\r
214 for( x = 0; x < lMaxTime; x++ )
\r
216 if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 )
\r
218 /* Operation has finished. */
\r
222 NyLPC_cThread_sleep( emacSHORT_DELAY_MS );
\r
227 return NyLPC_TBool_TRUE;
\r
231 return NyLPC_TBool_FALSE;
\r
234 /*-----------------------------------------------------------*/
\r
236 unsigned short EthDev_LPC17xx_prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool* plStatus )
\r
239 const long lMaxTime = 10;
\r
241 LPC_EMAC->MCMD = 1;
\r
242 LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | ucPhyReg;
\r
243 LPC_EMAC->MCMD = MCMD_READ;
\r
245 for( x = 0; x < lMaxTime; x++ )
\r
247 /* Operation has finished. */
\r
248 if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 )
\r
252 NyLPC_cThread_sleep( emacSHORT_DELAY_MS );
\r
255 LPC_EMAC->MCMD = 0;
\r
257 if( x >= lMaxTime )
\r
259 *plStatus = NyLPC_TBool_FALSE;
\r
262 return( LPC_EMAC->MRDD );
\r