6 * This file contains the device abstraction layer APIs for EMAC.
9 /* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
14 #include "sys/hw_reg_access.h"
15 #include "sys/ti_drv_emac.h"
16 #include "sys/hw_emac.h"
17 #include "sys/hw_emac_ctrl.h"
19 /*******************************************************************************
20 * INTERNAL MACRO DEFINITIONS
21 *******************************************************************************/
22 #define EMAC_CONTROL_RESET (0x01u)
23 #define EMAC_SOFT_RESET (0x01u)
24 #define EMAC_MAX_HEADER_DESC (8u)
25 #define EMAC_UNICAST_DISABLE (0xFFu)
27 /*******************************************************************************
28 * API FUNCTION DEFINITIONS
29 *******************************************************************************/
31 * \brief Enables the TXPULSE Interrupt Generation.
33 * \param emacBase Base address of the EMAC Module registers.
34 * \param emacCtrlBase Base address of the EMAC CONTROL module registers
35 * \param ctrlCore Control core for which the interrupt to be enabled.
36 * \param channel Channel number for which interrupt to be enabled
41 void EMACTxIntPulseEnable(unsigned int emacBase, unsigned int emacCtrlBase,
42 unsigned int ctrlCore, unsigned int channel)
44 HWREG(emacBase + EMAC_TXINTMASKSET) |= (1 << channel);
46 HWREG(emacCtrlBase + EMAC_CTRL_CnTXEN(ctrlCore)) |= (1 << channel);
50 * \brief Disables the TXPULSE Interrupt Generation.
52 * \param emacBase Base address of the EMAC Module registers.
53 * \param emacCtrlBase Base address of the EMAC CONTROL module registers
54 * \param ctrlCore Control core for which the interrupt to be disabled.
55 * \param channel Channel number for which interrupt to be disabled
60 void EMACTxIntPulseDisable(unsigned int emacBase, unsigned int emacCtrlBase,
61 unsigned int ctrlCore, unsigned int channel)
63 HWREG(emacBase + EMAC_TXINTMASKCLEAR) |= (1 << channel);
65 HWREG(emacCtrlBase + EMAC_CTRL_CnTXEN(ctrlCore)) &= ~(1 << channel);
69 * \brief Enables the RXPULSE Interrupt Generation.
71 * \param emacBase Base address of the EMAC Module registers.
72 * \param emacCtrlBase Base address of the EMAC CONTROL module registers
73 * \param ctrlCore Control core for which the interrupt to be enabled.
74 * \param channel Channel number for which interrupt to be enabled
79 void EMACRxIntPulseEnable(unsigned int emacBase, unsigned int emacCtrlBase,
80 unsigned int ctrlCore, unsigned int channel)
82 HWREG(emacBase + EMAC_RXINTMASKSET) |= (1 << channel);
84 HWREG(emacCtrlBase + EMAC_CTRL_CnRXEN(ctrlCore)) |= (1 << channel);
88 * \brief Disables the RXPULSE Interrupt Generation.
90 * \param emacBase Base address of the EMAC Module registers.
91 * \param emacCtrlBase Base address of the EMAC CONTROL module registers
92 * \param ctrlCore Control core for which the interrupt to be disabled.
93 * \param channel Channel number for which interrupt to be disabled
98 void EMACRxIntPulseDisable(unsigned int emacBase, unsigned int emacCtrlBase,
99 unsigned int ctrlCore, unsigned int channel)
101 HWREG(emacBase + EMAC_RXINTMASKCLEAR) |= (1 << channel);
103 HWREG(emacCtrlBase + EMAC_CTRL_CnRXEN(ctrlCore)) &= ~(1 << channel);
106 * \brief This API sets the RMII speed. The RMII Speed can be 10 Mbps or
109 * \param emacBase Base address of the EMAC Module registers.
110 * \param speed speed for setting.
111 * speed can take the following values. \n
112 * EMAC_RMIISPEED_10MBPS - 10 Mbps \n
113 * EMAC_RMIISPEED_100MBPS - 100 Mbps.
118 void EMACRMIISpeedSet(unsigned int emacBase, unsigned int speed)
120 HWREG(emacBase + EMAC_MACCONTROL) &= ~EMAC_MACCONTROL_RMIISPEED;
122 HWREG(emacBase + EMAC_MACCONTROL) |= speed;
126 * \brief This API enables the MII control block
128 * \param emacBase Base address of the EMAC Module registers.
133 void EMACMIIEnable(unsigned int emacBase)
135 HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_GMIIEN;
139 * \brief This API sets the duplex mode of operation(full/half) for MAC.
141 * \param emacBase Base address of the EMAC Module registers.
142 * \param duplexMode duplex mode of operation.
143 * duplexMode can take the following values. \n
144 * EMAC_DUPLEX_FULL - Full Duplex \n
145 * EMAC_DUPLEX_HALF - Half Duplex.
150 void EMACDuplexSet(unsigned int emacBase, unsigned int duplexMode)
152 HWREG(emacBase + EMAC_MACCONTROL) &= ~EMAC_MACCONTROL_FULLDUPLEX;
154 HWREG(emacBase + EMAC_MACCONTROL) |= duplexMode;
158 * \brief API to enable the transmit in the TX Control Register
159 * After the transmit is enabled, any write to TXHDP of
160 * a channel will start transmission
162 * \param emacBase Base Address of the EMAC Module Registers.
167 void EMACTxEnable(unsigned int emacBase)
169 HWREG(emacBase + EMAC_TXCONTROL) = EMAC_TXCONTROL_TXEN;
173 * \brief API to enable the receive in the RX Control Register
174 * After the transmit is enabled, and write to RXHDP of
175 * a channel, the data can be received in the destination
176 * specified by the corresponding RX buffer descriptor.
178 * \param emacBase Base Address of the EMAC Module Registers.
183 void EMACRxEnable(unsigned int emacBase)
185 HWREG(emacBase + EMAC_RXCONTROL) = EMAC_RXCONTROL_RXEN;
189 * \brief API to write the TX HDP register. If transmit is enabled,
190 * write to the TX HDP will immediately start transmission.
191 * The data will be taken from the buffer pointer of the TX buffer
192 * descriptor written to the TX HDP
194 * \param emacBase Base Address of the EMAC Module Registers.\n
195 * \param descHdr Address of the TX buffer descriptor
196 * \param channel Channel Number
201 volatile unsigned int lastInputdescHdr = 0;
202 volatile unsigned int valHDPbefWrite = 0;
203 void EMACTxHdrDescPtrWrite(unsigned int emacBase, unsigned int descHdr,
204 unsigned int channel)
206 valHDPbefWrite = HWREG(emacBase + EMAC_TXHDP(channel));
207 HWREG(emacBase + EMAC_TXHDP(channel)) = descHdr;
208 lastInputdescHdr = descHdr;
212 * \brief API to write the RX HDP register. If receive is enabled,
213 * write to the RX HDP will enable data reception to point to
214 * the corresponding RX buffer descriptor's buffer pointer.
216 * \param emacBase Base Address of the EMAC Module Registers.\n
217 * \param descHdr Address of the RX buffer descriptor
218 * \param channel Channel Number
223 void EMACRxHdrDescPtrWrite(unsigned int emacBase, unsigned int descHdr,
224 unsigned int channel)
226 HWREG(emacBase + EMAC_RXHDP(channel)) = descHdr;
230 * \brief This API Initializes the EMAC and EMAC Control modules. The
231 * EMAC Control module is reset, the CPPI RAM is cleared. also,
232 * all the interrupts are disabled. This API doesnot enable any
233 * interrupt or operation of the EMAC.
235 * \param emacCtrlBase Base Address of the EMAC Control module
237 * \param emacBase Base address of the EMAC module registers
242 void EMACInit(unsigned int emacCtrlBase, unsigned int emacBase)
246 /* Reset the EMAC Control Module. This clears the CPPI RAM also */
247 HWREG(emacCtrlBase + EMAC_CTRL_SOFTRESET) = EMAC_CONTROL_RESET;
249 while(HWREG(emacCtrlBase + EMAC_CTRL_SOFTRESET) & EMAC_CONTROL_RESET);
251 /* Reset the EMAC Control Module. This clears the CPPI RAM also */
252 HWREG(emacBase + EMAC_SOFTRESET) = EMAC_SOFT_RESET;
254 while(HWREG(emacBase + EMAC_SOFTRESET) & EMAC_SOFT_RESET);
256 HWREG(emacBase + EMAC_MACCONTROL)= 0;
257 HWREG(emacBase + EMAC_RXCONTROL)= 0;
258 HWREG(emacBase + EMAC_TXCONTROL)= 0;
260 /* Initialize all the header descriptor pointer registers */
261 for(cnt = 0; cnt< EMAC_MAX_HEADER_DESC; cnt++)
263 HWREG(emacBase + EMAC_RXHDP(cnt)) = 0;
264 HWREG(emacBase + EMAC_TXHDP(cnt)) = 0;
265 HWREG(emacBase + EMAC_RXCP(cnt)) = 0;
266 HWREG(emacBase + EMAC_TXCP(cnt)) = 0;
267 HWREG(emacBase + EMAC_RXFREEBUFFER(cnt)) = 0xFF;
269 /* Clear the interrupt enable for all the channels */
270 HWREG(emacBase + EMAC_TXINTMASKCLEAR) = 0xFF;
271 HWREG(emacBase + EMAC_RXINTMASKCLEAR) = 0xFF;
273 HWREG(emacBase + EMAC_MACHASH1) = 0;
274 HWREG(emacBase + EMAC_MACHASH2) = 0;
276 HWREG(emacBase + EMAC_RXBUFFEROFFSET) = 0;
280 * \brief Sets the MAC Address in MACSRCADDR registers.
282 * \param emacBase Base Address of the EMAC module registers.
283 * \param macAddr Start address of a MAC address array.
284 * The array[0] shall be the LSB of the MAC address
289 void EMACMACSrcAddrSet(unsigned int emacBase, unsigned char *macAddr)
291 HWREG(emacBase + EMAC_MACSRCADDRHI) = macAddr[5] |(macAddr[4] << 8)
292 |(macAddr[3] << 16) |(macAddr[2] << 24);
293 HWREG(emacBase + EMAC_MACSRCADDRLO) = macAddr[1] | (macAddr[0] << 8);
297 * \brief Sets the MAC Address in MACADDR registers.
299 * \param emacBase Base Address of the EMAC module registers.
300 * \param channel Channel Number
301 * \param matchFilt Match or Filter
302 * \param macAddr Start address of a MAC address array.
303 * The array[0] shall be the LSB of the MAC address
304 * matchFilt can take the following values \n
305 * EMAC_MACADDR_NO_MATCH_NO_FILTER - Address is not used to match
306 * or filter incoming packet. \n
307 * EMAC_MACADDR_FILTER - Address is used to filter incoming packets \n
308 * EMAC_MACADDR_MATCH - Address is used to match incoming packets \n
313 void EMACMACAddrSet(unsigned int emacBase, unsigned int channel,
314 unsigned char *macAddr, unsigned int matchFilt)
316 HWREG(emacBase + EMAC_MACINDEX) = channel;
318 HWREG(emacBase + EMAC_MACADDRHI) = macAddr[5] |(macAddr[4] << 8)
319 |(macAddr[3] << 16) |(macAddr[2] << 24);
320 HWREG(emacBase + EMAC_MACADDRLO) = macAddr[1] | (macAddr[0] << 8)
321 | matchFilt | (channel << 16);
325 * \brief Acknowledges an interrupt processed to the EMAC Control Core.
327 * \param emacBase Base Address of the EMAC module registers.
328 * \param eoiFlag Type of interrupt to acknowledge to the EMAC Control
330 * eoiFlag can take the following values \n
331 * EMAC_INT_CORE0_TX - Core 0 TX Interrupt
332 * EMAC_INT_CORE1_TX - Core 1 TX Interrupt
333 * EMAC_INT_CORE2_TX - Core 2 TX Interrupt
334 * EMAC_INT_CORE0_RX - Core 0 RX Interrupt
335 * EMAC_INT_CORE1_RX - Core 1 RX Interrupt
336 * EMAC_INT_CORE2_RX - Core 2 RX Interrupt
340 void EMACCoreIntAck(unsigned int emacBase, unsigned int eoiFlag)
342 /* Acknowledge the EMAC Control Core */
343 HWREG(emacBase + EMAC_MACEOIVECTOR) = eoiFlag;
347 * \brief Writes the the TX Completion Pointer for a specific channel
349 * \param emacBase Base Address of the EMAC module registers.
350 * \param channel Channel Number.
351 * \param comPtr Completion Pointer Value to be written
356 void EMACTxCPWrite(unsigned int emacBase, unsigned int channel, unsigned int comPtr)
358 HWREG(emacBase + EMAC_TXCP(channel)) = comPtr;
361 uint32_t EMACTxCPRead(unsigned int emacBase, unsigned int channel)
363 return (HWREG(emacBase + EMAC_TXCP(channel)));
367 * \brief Writes the the RX Completion Pointer for a specific channel
369 * \param emacBase Base Address of the EMAC module registers.
370 * \param channel Channel Number.
371 * \param comPtr Completion Pointer Value to be written
376 void EMACRxCPWrite(unsigned int emacBase, unsigned int channel, unsigned int comPtr)
378 HWREG(emacBase + EMAC_RXCP(channel)) = comPtr;
382 * \brief Acknowledges an interrupt processed to the EMAC module. After
383 * processing an interrupt, the last processed buffer descriptor is
384 * written to the completion pointer. Also this API acknowledges
385 * the EMAC Control Module that the RX interrupt is processed for
388 * \param emacBase Base Address of the EMAC module registers.
389 * \param channel Channel Number
390 * \param comPtr Completion Pointer value. This shall be the buffer
391 * descriptor address last processed.
392 * \param eoiFlag Type of interrupt to acknowledge to the EMAC Control
394 * eoiFlag can take the following values \n
395 * EMAC_INT_CORE0_RX - Core 0 RX Interrupt
396 * EMAC_INT_CORE1_RX - Core 1 RX Interrupt
397 * EMAC_INT_CORE2_RX - Core 2 RX Interrupt
401 void EMACRxIntAckToClear(unsigned int emacBase, unsigned int channel,
402 unsigned int comPtr, unsigned eoiFlag)
404 HWREG(emacBase + EMAC_RXCP(channel)) = comPtr;
406 /* Acknowledge the EMAC Control Core */
407 HWREG(emacBase + EMAC_MACEOIVECTOR) = eoiFlag;
411 * \brief Enables a specific channel to receive broadcast frames
413 * \param emacBase Base Address of the EMAC module registers.
414 * \param channel Channel Number.
419 void EMACRxBroadCastEnable(unsigned int emacBase, unsigned int channel)
421 HWREG(emacBase + EMAC_RXMBPENABLE) &= ~EMAC_RXMBPENABLE_RXBROADCH;
423 HWREG(emacBase + EMAC_RXMBPENABLE) |=
424 EMAC_RXMBPENABLE_RXBROADEN |
425 (channel << EMAC_RXMBPENABLE_RXBROADCH_SHIFT);
428 void EMACRxPromiscEnable(unsigned int emacBase, unsigned int channel)
430 HWREG(emacBase + EMAC_RXMBPENABLE) |= EMAC_RXMBPENABLE_RXCAFEN | EMAC_RXMBPENABLE_RXCEFEN;
431 HWREG(emacBase + EMAC_RXMBPENABLE) |= (channel << EMAC_RXMBPENABLE_RXPROMCH_SHIFT);
434 * \brief Enables unicast for a specific channel
436 * \param emacBase Base Address of the EMAC module registers.
437 * \param channel Channel Number.
442 void EMACRxUnicastSet(unsigned int emacBase, unsigned int channel)
444 HWREG(emacBase + EMAC_RXUNICASTSET) |= (1 << channel);
448 * \brief Set the free buffers for a specific channel
450 * \param emacBase Base Address of the EMAC module registers.
451 * \param channel Channel Number.
452 * \param nBuf Number of free buffers
457 void EMACNumFreeBufSet(unsigned int emacBase, unsigned int channel,
460 HWREG(emacBase + EMAC_RXFREEBUFFER(channel)) = nBuf;
464 * \brief Gets the interrupt vectors of EMAC, which are pending
466 * \param emacBase Base Address of the EMAC module registers.
471 unsigned int EMACIntVectorGet(unsigned int emacBase)
473 return (HWREG(emacBase + EMAC_MACINVECTOR));
476 unsigned int EMACIntVectorRawGet(unsigned int emacBase)
478 return (HWREG(emacBase + EMAC_RXINTSTATRAW));
481 /***************************** End Of File ***********************************/