1
0

ethernet.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. //*****************************************************************************
  2. //
  3. // ethernet.c - Driver for the Integrated Ethernet Controller
  4. //
  5. // Copyright (c) 2006-2011 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
  22. //
  23. //*****************************************************************************
  24. //*****************************************************************************
  25. //
  26. //! \addtogroup ethernet_api
  27. //! @{
  28. //
  29. //*****************************************************************************
  30. #include "inc/hw_ethernet.h"
  31. #include "inc/hw_ints.h"
  32. #include "inc/hw_memmap.h"
  33. #include "inc/hw_types.h"
  34. #include "driverlib/debug.h"
  35. #include "driverlib/ethernet.h"
  36. #include "driverlib/interrupt.h"
  37. //*****************************************************************************
  38. //
  39. //! Initializes the Ethernet controller for operation.
  40. //!
  41. //! \param ulBase is the base address of the controller.
  42. //! \param ulEthClk is the rate of the clock supplied to the Ethernet module.
  43. //!
  44. //! This function prepares the Ethernet controller for first-time use in
  45. //! a given hardware/software configuration. This function should be called
  46. //! before any other Ethernet API functions are called.
  47. //!
  48. //! The peripheral clock is the same as the processor clock. This value is
  49. //! returned by SysCtlClockGet(), or it can be explicitly hard-coded if it is
  50. //! constant and known (to save the code/execution overhead of a call to
  51. //! SysCtlClockGet()).
  52. //!
  53. //! This function replaces the original EthernetInit() API and performs the
  54. //! same actions. A macro is provided in <tt>ethernet.h</tt> to map the
  55. //! original API to this API.
  56. //!
  57. //! \note If the device configuration is changed (for example, the system clock
  58. //! is reprogrammed to a different speed), then the Ethernet controller must be
  59. //! disabled by calling the EthernetDisable() function and the controller must
  60. //! be reinitialized by calling the EthernetInitExpClk() function again. After
  61. //! the controller has been reinitialized, the controller should be
  62. //! reconfigured using the appropriate Ethernet API calls.
  63. //!
  64. //! \return None.
  65. //
  66. //*****************************************************************************
  67. void
  68. EthernetInitExpClk(unsigned long ulBase, unsigned long ulEthClk)
  69. {
  70. unsigned long ulDiv;
  71. //
  72. // Check the arguments.
  73. //
  74. ASSERT(ulBase == ETH_BASE);
  75. //
  76. // Set the Management Clock Divider register for access to the PHY
  77. // register set (via EthernetPHYRead/Write).
  78. //
  79. // The MDC clock divided down from the system clock using the following
  80. // formula. A maximum of 2.5MHz is allowed for F(mdc).
  81. //
  82. // F(mdc) = F(sys) / (2 * (div + 1))
  83. // div = (F(sys) / (2 * F(mdc))) - 1
  84. // div = (F(sys) / 2 / F(mdc)) - 1
  85. //
  86. // Note: Because we should round up, to ensure we don't violate the
  87. // maximum clock speed, we can simplify this as follows:
  88. //
  89. // div = F(sys) / 2 / F(mdc)
  90. //
  91. // For example, given a system clock of 6.0MHz, and a div value of 1,
  92. // the mdc clock would be programmed as 1.5 MHz.
  93. //
  94. ulDiv = (ulEthClk / 2) / 2500000;
  95. HWREG(ulBase + MAC_O_MDV) = (ulDiv & MAC_MDV_DIV_M);
  96. }
  97. //*****************************************************************************
  98. //
  99. //! Sets the configuration of the Ethernet controller.
  100. //!
  101. //! \param ulBase is the base address of the controller.
  102. //! \param ulConfig is the configuration for the controller.
  103. //!
  104. //! After the EthernetInitExpClk() function has been called, this API function
  105. //! can be used to configure the various features of the Ethernet controller.
  106. //!
  107. //! The Ethernet controller provides three control registers that are used
  108. //! to configure the controller's operation. The transmit control register
  109. //! provides settings to enable full-duplex operation, to auto-generate the
  110. //! frame check sequence, and to pad the transmit packets to the minimum
  111. //! length as required by the IEEE standard. The receive control register
  112. //! provides settings to enable reception of packets with bad frame check
  113. //! sequence values and to enable multi-cast or promiscuous modes. The
  114. //! timestamp control register provides settings that enable support logic in
  115. //! the controller that allow the use of the General Purpose Timer 3 to capture
  116. //! timestamps for the transmitted and received packets. Note that not all
  117. //! devices support this functionality; see the data sheet to determine if
  118. //! this feature is supported.
  119. //!
  120. //! The \e ulConfig parameter is the logical OR of the following values:
  121. //!
  122. //! - \b ETH_CFG_TS_TSEN - Enable TX and RX interrupt status as CCP timer
  123. //! inputs
  124. //! - \b ETH_CFG_RX_BADCRCDIS - Disable reception of packets with a bad CRC
  125. //! - \b ETH_CFG_RX_PRMSEN - Enable promiscuous mode reception (all packets)
  126. //! - \b ETH_CFG_RX_AMULEN - Enable reception of multicast packets
  127. //! - \b ETH_CFG_TX_DPLXEN - Enable full duplex transmit mode
  128. //! - \b ETH_CFG_TX_CRCEN - Enable transmit with auto CRC generation
  129. //! - \b ETH_CFG_TX_PADEN - Enable padding of transmit data to minimum size
  130. //!
  131. //! These bit-mapped values are programmed into the transmit, receive, and/or
  132. //! timestamp control register.
  133. //!
  134. //! \return None.
  135. //
  136. //*****************************************************************************
  137. void
  138. EthernetConfigSet(unsigned long ulBase, unsigned long ulConfig)
  139. {
  140. unsigned long ulTemp;
  141. //
  142. // Check the arguments.
  143. //
  144. ASSERT(ulBase == ETH_BASE);
  145. ASSERT((ulConfig & ~(ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN |
  146. ETH_CFG_TX_PADEN | ETH_CFG_RX_BADCRCDIS |
  147. ETH_CFG_RX_PRMSEN | ETH_CFG_RX_AMULEN |
  148. ETH_CFG_TS_TSEN)) == 0);
  149. //
  150. // Setup the Transmit Control Register.
  151. //
  152. ulTemp = HWREG(ulBase + MAC_O_TCTL);
  153. ulTemp &= ~(MAC_TCTL_DUPLEX | MAC_TCTL_CRC | MAC_TCTL_PADEN);
  154. ulTemp |= ulConfig & 0x0FF;
  155. HWREG(ulBase + MAC_O_TCTL) = ulTemp;
  156. //
  157. // Setup the Receive Control Register.
  158. //
  159. ulTemp = HWREG(ulBase + MAC_O_RCTL);
  160. ulTemp &= ~(MAC_RCTL_BADCRC | MAC_RCTL_PRMS | MAC_RCTL_AMUL);
  161. ulTemp |= (ulConfig >> 8) & 0x0FF;
  162. HWREG(ulBase + MAC_O_RCTL) = ulTemp;
  163. //
  164. // Setup the Time Stamp Configuration register.
  165. //
  166. ulTemp = HWREG(ulBase + MAC_O_TS);
  167. ulTemp &= ~(MAC_TS_TSEN);
  168. ulTemp |= (ulConfig >> 16) & 0x0FF;
  169. HWREG(ulBase + MAC_O_TS) = ulTemp;
  170. }
  171. //*****************************************************************************
  172. //
  173. //! Gets the current configuration of the Ethernet controller.
  174. //!
  175. //! \param ulBase is the base address of the controller.
  176. //!
  177. //! This function queries the control registers of the Ethernet controller
  178. //! and returns a bit-mapped configuration value.
  179. //!
  180. //! \sa The description of the EthernetConfigSet() function provides detailed
  181. //! information for the bit-mapped configuration values that are returned.
  182. //!
  183. //! \return Returns the bit-mapped Ethernet controller configuration value.
  184. //
  185. //*****************************************************************************
  186. unsigned long
  187. EthernetConfigGet(unsigned long ulBase)
  188. {
  189. unsigned long ulConfig;
  190. //
  191. // Check the arguments.
  192. //
  193. ASSERT(ulBase == ETH_BASE);
  194. //
  195. // Read and return the Ethernet controller configuration parameters,
  196. // properly shifted into the appropriate bit field positions.
  197. //
  198. ulConfig = HWREG(ulBase + MAC_O_TS) << 16;
  199. ulConfig |= (HWREG(ulBase + MAC_O_RCTL) & ~(MAC_RCTL_RXEN)) << 8;
  200. ulConfig |= HWREG(ulBase + MAC_O_TCTL) & ~(MAC_TCTL_TXEN);
  201. return(ulConfig);
  202. }
  203. //*****************************************************************************
  204. //
  205. //! Sets the MAC address of the Ethernet controller.
  206. //!
  207. //! \param ulBase is the base address of the controller.
  208. //! \param pucMACAddr is the pointer to the array of MAC-48 address octets.
  209. //!
  210. //! This function programs the IEEE-defined MAC-48 address specified in
  211. //! \e pucMACAddr into the Ethernet controller. This address is used by the
  212. //! Ethernet controller for hardware-level filtering of incoming Ethernet
  213. //! packets (when promiscuous mode is not enabled).
  214. //!
  215. //! The MAC-48 address is defined as 6 octets, illustrated by the following
  216. //! example address. The numbers are shown in hexadecimal format.
  217. //!
  218. //! AC-DE-48-00-00-80
  219. //!
  220. //! In this representation, the first three octets (AC-DE-48) are the
  221. //! Organizationally Unique Identifier (OUI). This is a number assigned by
  222. //! the IEEE to an organization that requests a block of MAC addresses. The
  223. //! last three octets (00-00-80) are a 24-bit number managed by the OUI owner
  224. //! to uniquely identify a piece of hardware within that organization that is
  225. //! to be connected to the Ethernet.
  226. //!
  227. //! In this representation, the octets are transmitted from left to right,
  228. //! with the ``AC'' octet being transmitted first and the ``80'' octet being
  229. //! transmitted last. Within an octet, the bits are transmitted LSB to MSB.
  230. //! For this address, the first bit to be transmitted would be ``0'', the LSB
  231. //! of ``AC'', and the last bit to be transmitted would be ``1'', the MSB of
  232. //! ``80''.
  233. //!
  234. //! \return None.
  235. //
  236. //*****************************************************************************
  237. void
  238. EthernetMACAddrSet(unsigned long ulBase, unsigned char *pucMACAddr)
  239. {
  240. unsigned long ulTemp;
  241. unsigned char *pucTemp = (unsigned char *)&ulTemp;
  242. //
  243. // Check the arguments.
  244. //
  245. ASSERT(ulBase == ETH_BASE);
  246. ASSERT(pucMACAddr != 0);
  247. //
  248. // Program the MAC Address into the device. The first four bytes of the
  249. // MAC Address are placed into the IA0 register. The remaining two bytes
  250. // of the MAC address are placed into the IA1 register.
  251. //
  252. pucTemp[0] = pucMACAddr[0];
  253. pucTemp[1] = pucMACAddr[1];
  254. pucTemp[2] = pucMACAddr[2];
  255. pucTemp[3] = pucMACAddr[3];
  256. HWREG(ulBase + MAC_O_IA0) = ulTemp;
  257. ulTemp = 0;
  258. pucTemp[0] = pucMACAddr[4];
  259. pucTemp[1] = pucMACAddr[5];
  260. HWREG(ulBase + MAC_O_IA1) = ulTemp;
  261. }
  262. //*****************************************************************************
  263. //
  264. //! Gets the MAC address of the Ethernet controller.
  265. //!
  266. //! \param ulBase is the base address of the controller.
  267. //! \param pucMACAddr is the pointer to the location in which to store the
  268. //! array of MAC-48 address octets.
  269. //!
  270. //! This function reads the currently programmed MAC address into the
  271. //! \e pucMACAddr buffer.
  272. //!
  273. //! \sa Refer to EthernetMACAddrSet() API description for more details about
  274. //! the MAC address format.
  275. //!
  276. //! \return None.
  277. //
  278. //*****************************************************************************
  279. void
  280. EthernetMACAddrGet(unsigned long ulBase, unsigned char *pucMACAddr)
  281. {
  282. unsigned long ulTemp;
  283. unsigned char *pucTemp = (unsigned char *)&ulTemp;
  284. //
  285. // Check the arguments.
  286. //
  287. ASSERT(ulBase == ETH_BASE);
  288. ASSERT(pucMACAddr != 0);
  289. //
  290. // Read the MAC address from the device. The first four bytes of the
  291. // MAC address are read from the IA0 register. The remaining two bytes
  292. // of the MAC addres
  293. //
  294. ulTemp = HWREG(ulBase + MAC_O_IA0);
  295. pucMACAddr[0] = pucTemp[0];
  296. pucMACAddr[1] = pucTemp[1];
  297. pucMACAddr[2] = pucTemp[2];
  298. pucMACAddr[3] = pucTemp[3];
  299. ulTemp = HWREG(ulBase + MAC_O_IA1);
  300. pucMACAddr[4] = pucTemp[0];
  301. pucMACAddr[5] = pucTemp[1];
  302. }
  303. //*****************************************************************************
  304. //
  305. //! Enables the Ethernet controller for normal operation.
  306. //!
  307. //! \param ulBase is the base address of the controller.
  308. //!
  309. //! Once the Ethernet controller has been configured using the
  310. //! EthernetConfigSet() function and the MAC address has been programmed using
  311. //! the EthernetMACAddrSet() function, this API function can be called to
  312. //! enable the controller for normal operation.
  313. //!
  314. //! This function enables the controller's transmitter and receiver, and
  315. //! resets the receive FIFO.
  316. //!
  317. //! \return None.
  318. //
  319. //*****************************************************************************
  320. void
  321. EthernetEnable(unsigned long ulBase)
  322. {
  323. //
  324. // Check the arguments.
  325. //
  326. ASSERT(ulBase == ETH_BASE);
  327. //
  328. // Reset the receive FIFO.
  329. //
  330. HWREG(ulBase + MAC_O_RCTL) |= MAC_RCTL_RSTFIFO;
  331. //
  332. // Enable the Ethernet receiver.
  333. //
  334. HWREG(ulBase + MAC_O_RCTL) |= MAC_RCTL_RXEN;
  335. //
  336. // Enable Ethernet transmitter.
  337. //
  338. HWREG(ulBase + MAC_O_TCTL) |= MAC_TCTL_TXEN;
  339. //
  340. // Reset the receive FIFO again, after the receiver has been enabled.
  341. //
  342. HWREG(ulBase + MAC_O_RCTL) |= MAC_RCTL_RSTFIFO;
  343. }
  344. //*****************************************************************************
  345. //
  346. //! Disables the Ethernet controller.
  347. //!
  348. //! \param ulBase is the base address of the controller.
  349. //!
  350. //! When terminating operations on the Ethernet interface, this function should
  351. //! be called. This function disables the transmitter and receiver, and
  352. //! clears out the receive FIFO.
  353. //!
  354. //! \return None.
  355. //
  356. //*****************************************************************************
  357. void
  358. EthernetDisable(unsigned long ulBase)
  359. {
  360. //
  361. // Check the arguments.
  362. //
  363. ASSERT(ulBase == ETH_BASE);
  364. //
  365. // Reset the receive FIFO.
  366. //
  367. HWREG(ulBase + MAC_O_RCTL) |= MAC_RCTL_RSTFIFO;
  368. //
  369. // Disable the Ethernet transmitter.
  370. //
  371. HWREG(ulBase + MAC_O_TCTL) &= ~(MAC_TCTL_TXEN);
  372. //
  373. // Disable the Ethernet receiver.
  374. //
  375. HWREG(ulBase + MAC_O_RCTL) &= ~(MAC_RCTL_RXEN);
  376. //
  377. // Reset the receive FIFO again, after the receiver has been disabled.
  378. //
  379. HWREG(ulBase + MAC_O_RCTL) |= MAC_RCTL_RSTFIFO;
  380. }
  381. //*****************************************************************************
  382. //
  383. //! Check for packet available from the Ethernet controller.
  384. //!
  385. //! \param ulBase is the base address of the controller.
  386. //!
  387. //! The Ethernet controller provides a register that contains the number of
  388. //! packets available in the receive FIFO. When the last bytes of a packet are
  389. //! successfully received (that is, the frame check sequence bytes), the packet
  390. //! count is incremented. Once the packet has been fully read (including the
  391. //! frame check sequence bytes) from the FIFO, the packet count is decremented.
  392. //!
  393. //! \return Returns \b true if there are one or more packets available in the
  394. //! receive FIFO, including the current packet being read, and \b false
  395. //! otherwise.
  396. //
  397. //*****************************************************************************
  398. tBoolean
  399. EthernetPacketAvail(unsigned long ulBase)
  400. {
  401. //
  402. // Check the arguments.
  403. //
  404. ASSERT(ulBase == ETH_BASE);
  405. //
  406. // Return the availability of packets.
  407. //
  408. return((HWREG(ulBase + MAC_O_NP) & MAC_NP_NPR_M) ? true : false);
  409. }
  410. //*****************************************************************************
  411. //
  412. //! Checks for packet space available in the Ethernet controller.
  413. //!
  414. //! \param ulBase is the base address of the controller.
  415. //!
  416. //! The Ethernet controller's transmit FIFO is designed to support a single
  417. //! packet at a time. After the packet has been written into the FIFO, the
  418. //! transmit request bit must be set to enable the transmission of the packet.
  419. //! Only after the packet has been transmitted can a new packet be written
  420. //! into the FIFO. This function simply checks to see if a packet is
  421. //! in progress. If so, there is no space available in the transmit FIFO.
  422. //!
  423. //! \return Returns \b true if a space is available in the transmit FIFO, and
  424. //! \b false otherwise.
  425. //
  426. //*****************************************************************************
  427. tBoolean
  428. EthernetSpaceAvail(unsigned long ulBase)
  429. {
  430. //
  431. // Check the arguments.
  432. //
  433. ASSERT(ulBase == ETH_BASE);
  434. //
  435. // Return the availability of space.
  436. //
  437. return((HWREG(ulBase + MAC_O_TR) & MAC_TR_NEWTX) ? false : true);
  438. }
  439. //*****************************************************************************
  440. //
  441. //! \internal
  442. //!
  443. //! Internal function for reading a packet from the Ethernet controller.
  444. //!
  445. //! \param ulBase is the base address of the controller.
  446. //! \param pucBuf is the pointer to the packet buffer.
  447. //! \param lBufLen is the maximum number of bytes to be read into the buffer.
  448. //!
  449. //! Based on the following table of how the receive frame is stored in the
  450. //! receive FIFO, this function will extract a packet from the FIFO and store
  451. //! it in the packet buffer that was passed in.
  452. //!
  453. //! Format of the data in the RX FIFO is as follows:
  454. //!
  455. //! \verbatim
  456. //! +---------+----------+----------+----------+----------+
  457. //! | | 31:24 | 23:16 | 15:8 | 7:0 |
  458. //! +---------+----------+----------+----------+----------+
  459. //! | Word 0 | DA 2 | DA 1 | FL MSB | FL LSB |
  460. //! +---------+----------+----------+----------+----------+
  461. //! | Word 1 | DA 6 | DA 5 | DA 4 | DA 3 |
  462. //! +---------+----------+----------+----------+----------+
  463. //! | Word 2 | SA 4 | SA 3 | SA 2 | SA 1 |
  464. //! +---------+----------+----------+----------+----------+
  465. //! | Word 3 | FT LSB | FT MSB | SA 6 | SA 5 |
  466. //! +---------+----------+----------+----------+----------+
  467. //! | Word 4 | DATA 4 | DATA 3 | DATA 2 | DATA 1 |
  468. //! +---------+----------+----------+----------+----------+
  469. //! | Word 5 | DATA 8 | DATA 7 | DATA 6 | DATA 5 |
  470. //! +---------+----------+----------+----------+----------+
  471. //! | Word 6 | DATA 12 | DATA 11 | DATA 10 | DATA 9 |
  472. //! +---------+----------+----------+----------+----------+
  473. //! | ... | | | | |
  474. //! +---------+----------+----------+----------+----------+
  475. //! | Word X | DATA n | DATA n-1 | DATA n-2 | DATA n-3 |
  476. //! +---------+----------+----------+----------+----------+
  477. //! | Word Y | FCS 4 | FCS 3 | FCS 2 | FCS 1 |
  478. //! +---------+----------+----------+----------+----------+
  479. //! \endverbatim
  480. //!
  481. //! Where FL is Frame Length, (FL + DA + SA + FT + DATA + FCS) Bytes.
  482. //! Where DA is Destination (MAC) Address.
  483. //! Where SA is Source (MAC) Address.
  484. //! Where FT is Frame Type (or Frame Length for Ethernet).
  485. //! Where DATA is Payload Data for the Ethernet Frame.
  486. //! Where FCS is the Frame Check Sequence.
  487. //!
  488. //! \return Returns the negated packet length \b -n if the packet is too large
  489. //! for \e pucBuf, and returns the packet length \b n otherwise.
  490. //
  491. //*****************************************************************************
  492. static long
  493. EthernetPacketGetInternal(unsigned long ulBase, unsigned char *pucBuf,
  494. long lBufLen)
  495. {
  496. unsigned long ulTemp;
  497. long lFrameLen, lTempLen;
  498. long i = 0;
  499. //
  500. // Read WORD 0 (see format above) from the FIFO, set the receive
  501. // Frame Length and store the first two bytes of the destination
  502. // address in the receive buffer.
  503. //
  504. ulTemp = HWREG(ulBase + MAC_O_DATA);
  505. lFrameLen = (long)(ulTemp & 0xFFFF);
  506. pucBuf[i++] = (unsigned char) ((ulTemp >> 16) & 0xff);
  507. pucBuf[i++] = (unsigned char) ((ulTemp >> 24) & 0xff);
  508. //
  509. // Read all but the last WORD into the receive buffer.
  510. //
  511. lTempLen = (lBufLen < (lFrameLen - 6)) ? lBufLen : (lFrameLen - 6);
  512. while(i <= (lTempLen - 4))
  513. {
  514. *(unsigned long *)&pucBuf[i] = HWREG(ulBase + MAC_O_DATA);
  515. i += 4;
  516. }
  517. //
  518. // Read the last 1, 2, or 3 BYTES into the buffer
  519. //
  520. if(i < lTempLen)
  521. {
  522. ulTemp = HWREG(ulBase + MAC_O_DATA);
  523. if(i == lTempLen - 3)
  524. {
  525. pucBuf[i++] = ((ulTemp >> 0) & 0xff);
  526. pucBuf[i++] = ((ulTemp >> 8) & 0xff);
  527. pucBuf[i++] = ((ulTemp >> 16) & 0xff);
  528. i += 1;
  529. }
  530. else if(i == lTempLen - 2)
  531. {
  532. pucBuf[i++] = ((ulTemp >> 0) & 0xff);
  533. pucBuf[i++] = ((ulTemp >> 8) & 0xff);
  534. i += 2;
  535. }
  536. else if(i == lTempLen - 1)
  537. {
  538. pucBuf[i++] = ((ulTemp >> 0) & 0xff);
  539. i += 3;
  540. }
  541. }
  542. //
  543. // Read any remaining WORDS (that did not fit into the buffer).
  544. //
  545. while(i < (lFrameLen - 2))
  546. {
  547. ulTemp = HWREG(ulBase + MAC_O_DATA);
  548. i += 4;
  549. }
  550. //
  551. // If frame was larger than the buffer, return the "negative" frame length
  552. //
  553. lFrameLen -= 6;
  554. if(lFrameLen > lBufLen)
  555. {
  556. return(-lFrameLen);
  557. }
  558. //
  559. // Return the Frame Length
  560. //
  561. return(lFrameLen);
  562. }
  563. //*****************************************************************************
  564. //
  565. //! Receives a packet from the Ethernet controller.
  566. //!
  567. //! \param ulBase is the base address of the controller.
  568. //! \param pucBuf is the pointer to the packet buffer.
  569. //! \param lBufLen is the maximum number of bytes to be read into the buffer.
  570. //!
  571. //! This function reads a packet from the receive FIFO of the controller and
  572. //! places it into \e pucBuf. If no packet is available the function
  573. //! returns immediately. Otherwise, the function reads the entire packet
  574. //! from the receive FIFO. If there are more bytes in the packet than can fit
  575. //! into \e pucBuf (as specified by \e lBufLen), the function returns the
  576. //! negated length of the packet and the buffer contains \e lBufLen bytes
  577. //! of the packet. Otherwise, the function returns the length of the
  578. //! packet that was read and \e pucBuf contains the entire packet
  579. //! (excluding the frame check sequence bytes).
  580. //!
  581. //! This function replaces the original EthernetPacketNonBlockingGet() API and
  582. //! performs the same actions. A macro is provided in <tt>ethernet.h</tt> to
  583. //! map the original API to this API.
  584. //!
  585. //! \note This function returns immediately if no packet is available.
  586. //!
  587. //! \return Returns \b 0 if no packet is available, the negated packet length
  588. //! \b -n if the packet is too large for \e pucBuf, and the packet length \b n
  589. //! otherwise.
  590. //
  591. //*****************************************************************************
  592. long
  593. EthernetPacketGetNonBlocking(unsigned long ulBase, unsigned char *pucBuf,
  594. long lBufLen)
  595. {
  596. //
  597. // Check the arguments.
  598. //
  599. ASSERT(ulBase == ETH_BASE);
  600. ASSERT(pucBuf != 0);
  601. ASSERT(lBufLen > 0);
  602. //
  603. // Check to see if any packets are available.
  604. //
  605. if((HWREG(ulBase + MAC_O_NP) & MAC_NP_NPR_M) == 0)
  606. {
  607. return(0);
  608. }
  609. //
  610. // Read the packet, and return.
  611. //
  612. return(EthernetPacketGetInternal(ulBase, pucBuf, lBufLen));
  613. }
  614. //*****************************************************************************
  615. //
  616. //! Waits for a packet from the Ethernet controller.
  617. //!
  618. //! \param ulBase is the base address of the controller.
  619. //! \param pucBuf is the pointer to the packet buffer.
  620. //! \param lBufLen is the maximum number of bytes to be read into the buffer.
  621. //!
  622. //! This function reads a packet from the receive FIFO of the controller and
  623. //! places it into \e pucBuf. The function waits until a packet is
  624. //! available in the FIFO. Then the function reads the entire packet
  625. //! from the receive FIFO. If there are more bytes in the packet than can
  626. //! fit into \e pucBuf (as specified by \e lBufLen), the function returns
  627. //! the negated length of the packet and the buffer contains \e lBufLen
  628. //! bytes of the packet. Otherwise, the function returns the length of
  629. //! the packet that was read and \e pucBuf contains the entire packet
  630. //! (excluding the frame check sequence bytes).
  631. //!
  632. //! \note This function is blocking and does not return until a packet arrives.
  633. //!
  634. //! \return Returns the negated packet length \b -n if the packet is too large
  635. //! for \e pucBuf, and returns the packet length \b n otherwise.
  636. //
  637. //*****************************************************************************
  638. long
  639. EthernetPacketGet(unsigned long ulBase, unsigned char *pucBuf,
  640. long lBufLen)
  641. {
  642. //
  643. // Check the arguments.
  644. //
  645. ASSERT(ulBase == ETH_BASE);
  646. ASSERT(pucBuf != 0);
  647. ASSERT(lBufLen > 0);
  648. //
  649. // Wait for a packet to become available
  650. //
  651. while((HWREG(ulBase + MAC_O_NP) & MAC_NP_NPR_M) == 0)
  652. {
  653. }
  654. //
  655. // Read the packet
  656. //
  657. return(EthernetPacketGetInternal(ulBase, pucBuf, lBufLen));
  658. }
  659. //*****************************************************************************
  660. //
  661. //! \internal
  662. //!
  663. //! Internal function for sending a packet to the Ethernet controller.
  664. //!
  665. //! \param ulBase is the base address of the controller.
  666. //! \param pucBuf is the pointer to the packet buffer.
  667. //! \param lBufLen is number of bytes in the packet to be transmitted.
  668. //!
  669. //! Puts a packet into the transmit FIFO of the controller.
  670. //!
  671. //! Format of the data in the TX FIFO is as follows:
  672. //!
  673. //! \verbatim
  674. //! +---------+----------+----------+----------+----------+
  675. //! | | 31:24 | 23:16 | 15:8 | 7:0 |
  676. //! +---------+----------+----------+----------+----------+
  677. //! | Word 0 | DA 2 | DA 1 | PL MSB | PL LSB |
  678. //! +---------+----------+----------+----------+----------+
  679. //! | Word 1 | DA 6 | DA 5 | DA 4 | DA 3 |
  680. //! +---------+----------+----------+----------+----------+
  681. //! | Word 2 | SA 4 | SA 3 | SA 2 | SA 1 |
  682. //! +---------+----------+----------+----------+----------+
  683. //! | Word 3 | FT LSB | FT MSB | SA 6 | SA 5 |
  684. //! +---------+----------+----------+----------+----------+
  685. //! | Word 4 | DATA 4 | DATA 3 | DATA 2 | DATA 1 |
  686. //! +---------+----------+----------+----------+----------+
  687. //! | Word 5 | DATA 8 | DATA 7 | DATA 6 | DATA 5 |
  688. //! +---------+----------+----------+----------+----------+
  689. //! | Word 6 | DATA 12 | DATA 11 | DATA 10 | DATA 9 |
  690. //! +---------+----------+----------+----------+----------+
  691. //! | ... | | | | |
  692. //! +---------+----------+----------+----------+----------+
  693. //! | Word X | DATA n | DATA n-1 | DATA n-2 | DATA n-3 |
  694. //! +---------+----------+----------+----------+----------+
  695. //! \endverbatim
  696. //!
  697. //! Where PL is Payload Length, (DATA) only
  698. //! Where DA is Destination (MAC) Address
  699. //! Where SA is Source (MAC) Address
  700. //! Where FT is Frame Type (or Frame Length for Ethernet)
  701. //! Where DATA is Payload Data for the Ethernet Frame
  702. //!
  703. //! \return Returns the negated packet length \b -lBufLen if the packet is too
  704. //! large for FIFO, and the packet length \b lBufLen otherwise.
  705. //
  706. //*****************************************************************************
  707. static long
  708. EthernetPacketPutInternal(unsigned long ulBase, unsigned char *pucBuf,
  709. long lBufLen)
  710. {
  711. unsigned long ulTemp;
  712. long i = 0;
  713. //
  714. // If the packet is too large, return the negative packet length as
  715. // an error code.
  716. //
  717. if(lBufLen > (2048 - 2))
  718. {
  719. return(-lBufLen);
  720. }
  721. //
  722. // Build and write WORD 0 (see format above) to the transmit FIFO.
  723. //
  724. ulTemp = (unsigned long)(lBufLen - 14);
  725. ulTemp |= (pucBuf[i++] << 16);
  726. ulTemp |= (pucBuf[i++] << 24);
  727. HWREG(ulBase + MAC_O_DATA) = ulTemp;
  728. //
  729. // Write each subsequent WORD n to the transmit FIFO, except for the last
  730. // WORD (if the word does not contain 4 bytes).
  731. //
  732. while(i <= (lBufLen - 4))
  733. {
  734. HWREG(ulBase + MAC_O_DATA) = *(unsigned long *)&pucBuf[i];
  735. i += 4;
  736. }
  737. //
  738. // Build the last word of the remaining 1, 2, or 3 bytes, and store
  739. // the WORD into the transmit FIFO.
  740. //
  741. if(i != lBufLen)
  742. {
  743. if(i == (lBufLen - 3))
  744. {
  745. ulTemp = (pucBuf[i++] << 0);
  746. ulTemp |= (pucBuf[i++] << 8);
  747. ulTemp |= (pucBuf[i++] << 16);
  748. HWREG(ulBase + MAC_O_DATA) = ulTemp;
  749. }
  750. else if(i == (lBufLen - 2))
  751. {
  752. ulTemp = (pucBuf[i++] << 0);
  753. ulTemp |= (pucBuf[i++] << 8);
  754. HWREG(ulBase + MAC_O_DATA) = ulTemp;
  755. }
  756. else if(i == (lBufLen - 1))
  757. {
  758. ulTemp = (pucBuf[i++] << 0);
  759. HWREG(ulBase + MAC_O_DATA) = ulTemp;
  760. }
  761. }
  762. //
  763. // Activate the transmitter
  764. //
  765. HWREG(ulBase + MAC_O_TR) = MAC_TR_NEWTX;
  766. //
  767. // Return the Buffer Length transmitted.
  768. //
  769. return(lBufLen);
  770. }
  771. //*****************************************************************************
  772. //
  773. //! Sends a packet to the Ethernet controller.
  774. //!
  775. //! \param ulBase is the base address of the controller.
  776. //! \param pucBuf is the pointer to the packet buffer.
  777. //! \param lBufLen is number of bytes in the packet to be transmitted.
  778. //!
  779. //! This function writes \e lBufLen bytes of the packet contained in \e pucBuf
  780. //! into the transmit FIFO of the controller and then activates the
  781. //! transmitter for this packet. If no space is available in the FIFO, the
  782. //! function returns immediately. If space is available, the
  783. //! function returns once \e lBufLen bytes of the packet have been placed
  784. //! into the FIFO and the transmitter has been started. The function does not
  785. //! wait for the transmission to complete. The function returns the
  786. //! negated \e lBufLen if the length is larger than the space available in
  787. //! the transmit FIFO.
  788. //!
  789. //! This function replaces the original EthernetPacketNonBlockingPut() API and
  790. //! performs the same actions. A macro is provided in <tt>ethernet.h</tt> to
  791. //! map the original API to this API.
  792. //!
  793. //! \note This function does not block and returns immediately if no space
  794. //! is available for the transmit packet.
  795. //!
  796. //! \return Returns \b 0 if no space is available in the transmit FIFO, the
  797. //! negated packet length \b -lBufLen if the packet is too large for FIFO, and
  798. //! the packet length \b lBufLen otherwise.
  799. //
  800. //*****************************************************************************
  801. long
  802. EthernetPacketPutNonBlocking(unsigned long ulBase, unsigned char *pucBuf,
  803. long lBufLen)
  804. {
  805. //
  806. // Check the arguments.
  807. //
  808. ASSERT(ulBase == ETH_BASE);
  809. ASSERT(pucBuf != 0);
  810. ASSERT(lBufLen > 0);
  811. //
  812. // Check if the transmit FIFO is in use and return the appropriate code.
  813. //
  814. if(HWREG(ulBase + MAC_O_TR) & MAC_TR_NEWTX)
  815. {
  816. return(0);
  817. }
  818. //
  819. // Send the packet and return.
  820. //
  821. return(EthernetPacketPutInternal(ulBase, pucBuf, lBufLen));
  822. }
  823. //*****************************************************************************
  824. //
  825. //! Waits to send a packet from the Ethernet controller.
  826. //!
  827. //! \param ulBase is the base address of the controller.
  828. //! \param pucBuf is the pointer to the packet buffer.
  829. //! \param lBufLen is number of bytes in the packet to be transmitted.
  830. //!
  831. //! This function writes \e lBufLen bytes of the packet contained in \e pucBuf
  832. //! into the transmit FIFO of the controller and then activates the transmitter
  833. //! for this packet. This function waits until the transmit FIFO is empty.
  834. //! Once space is available, the function returns once \e lBufLen bytes of
  835. //! the packet have been placed into the FIFO and the transmitter has been
  836. //! started. The function does not wait for the transmission to complete. The
  837. //! function returns the negated \e lBufLen if the length is larger than
  838. //! the space available in the transmit FIFO.
  839. //!
  840. //! \note This function blocks and waits until space is available for the
  841. //! transmit packet before returning.
  842. //!
  843. //! \return Returns the negated packet length \b -lBufLen if the packet is too
  844. //! large for FIFO, and the packet length \b lBufLen otherwise.
  845. //
  846. //*****************************************************************************
  847. long
  848. EthernetPacketPut(unsigned long ulBase, unsigned char *pucBuf,
  849. long lBufLen)
  850. {
  851. //
  852. // Check the arguments.
  853. //
  854. ASSERT(ulBase == ETH_BASE);
  855. ASSERT(pucBuf != 0);
  856. ASSERT(lBufLen > 0);
  857. //
  858. // Wait for current packet (if any) to complete.
  859. //
  860. while(HWREG(ulBase + MAC_O_TR) & MAC_TR_NEWTX)
  861. {
  862. }
  863. //
  864. // Send the packet and return.
  865. //
  866. return(EthernetPacketPutInternal(ulBase, pucBuf, lBufLen));
  867. }
  868. //*****************************************************************************
  869. //
  870. //! Registers an interrupt handler for an Ethernet interrupt.
  871. //!
  872. //! \param ulBase is the base address of the controller.
  873. //! \param pfnHandler is a pointer to the function to be called when the
  874. //! enabled Ethernet interrupts occur.
  875. //!
  876. //! This function sets the handler to be called when the Ethernet interrupt
  877. //! occurs. This function enables the global interrupt in the interrupt
  878. //! controller; specific Ethernet interrupts must be enabled via
  879. //! EthernetIntEnable(). It is the interrupt handler's responsibility to clear
  880. //! the interrupt source.
  881. //!
  882. //! \sa IntRegister() for important information about registering interrupt
  883. //! handlers.
  884. //!
  885. //! \return None.
  886. //
  887. //*****************************************************************************
  888. void
  889. EthernetIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
  890. {
  891. //
  892. // Check the arguments.
  893. //
  894. ASSERT(ulBase == ETH_BASE);
  895. ASSERT(pfnHandler != 0);
  896. //
  897. // Register the interrupt handler.
  898. //
  899. IntRegister(INT_ETH, pfnHandler);
  900. //
  901. // Enable the Ethernet interrupt.
  902. //
  903. IntEnable(INT_ETH);
  904. }
  905. //*****************************************************************************
  906. //
  907. //! Unregisters an interrupt handler for an Ethernet interrupt.
  908. //!
  909. //! \param ulBase is the base address of the controller.
  910. //!
  911. //! This function unregisters the interrupt handler. This function disables
  912. //! the global interrupt in the interrupt controller so that the interrupt
  913. //! handler no longer is called.
  914. //!
  915. //! \sa IntRegister() for important information about registering interrupt
  916. //! handlers.
  917. //!
  918. //! \return None.
  919. //
  920. //*****************************************************************************
  921. void
  922. EthernetIntUnregister(unsigned long ulBase)
  923. {
  924. //
  925. // Check the arguments.
  926. //
  927. ASSERT(ulBase == ETH_BASE);
  928. //
  929. // Disable the interrupt.
  930. //
  931. IntDisable(INT_ETH);
  932. //
  933. // Unregister the interrupt handler.
  934. //
  935. IntUnregister(INT_ETH);
  936. }
  937. //*****************************************************************************
  938. //
  939. //! Enables individual Ethernet interrupt sources.
  940. //!
  941. //! \param ulBase is the base address of the controller.
  942. //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
  943. //!
  944. //! This function enables the indicated Ethernet interrupt sources. Only the
  945. //! sources that are enabled can be reflected to the processor interrupt;
  946. //! disabled sources have no effect on the processor.
  947. //!
  948. //! The \e ulIntFlags parameter is the logical OR of any of the following:
  949. //!
  950. //! - \b ETH_INT_PHY - An interrupt from the PHY has occurred. The integrated
  951. //! PHY supports a number of interrupt conditions. The appropriate PHY
  952. //! register, PHY_MR17 or PHY_MR29 depending on the device class, must be read
  953. //! to determine which PHY interrupt has occurred. This register can be read
  954. //! using the EthernetPHYRead() API function.
  955. //! - \b ETH_INT_MDIO - This interrupt indicates that a transaction on the
  956. //! management interface has completed successfully.
  957. //! - \b ETH_INT_RXER - This interrupt indicates that an error has occurred
  958. //! during reception of a frame. This error can indicate a length mismatch, a
  959. //! CRC failure, or an error indication from the PHY.
  960. //! - \b ETH_INT_RXOF - This interrupt indicates that a frame has been received
  961. //! that exceeds the available space in the RX FIFO.
  962. //! - \b ETH_INT_TX - This interrupt indicates that the packet stored in the TX
  963. //! FIFO has been successfully transmitted.
  964. //! - \b ETH_INT_TXER - This interrupt indicates that an error has occurred
  965. //! during the transmission of a packet. This error can be either a retry
  966. //! failure during the back-off process, or an invalid length stored in the TX
  967. //! FIFO.
  968. //! - \b ETH_INT_RX - This interrupt indicates that one (or more) packets are
  969. //! available in the RX FIFO for processing.
  970. //!
  971. //! \return None.
  972. //
  973. //*****************************************************************************
  974. void
  975. EthernetIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
  976. {
  977. //
  978. // Check the arguments.
  979. //
  980. ASSERT(ulBase == ETH_BASE);
  981. ASSERT(!(ulIntFlags & ~(ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
  982. ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER |
  983. ETH_INT_RX)));
  984. //
  985. // Enable the specified interrupts.
  986. //
  987. HWREG(ulBase + MAC_O_IM) |= ulIntFlags;
  988. }
  989. //*****************************************************************************
  990. //
  991. //! Disables individual Ethernet interrupt sources.
  992. //!
  993. //! \param ulBase is the base address of the controller.
  994. //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
  995. //!
  996. //! Disables the indicated Ethernet interrupt sources. Only the sources that
  997. //! are enabled can be reflected to the processor interrupt; disabled sources
  998. //! have no effect on the processor.
  999. //!
  1000. //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
  1001. //! parameter to EthernetIntEnable().
  1002. //!
  1003. //! \return None.
  1004. //
  1005. //*****************************************************************************
  1006. void
  1007. EthernetIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
  1008. {
  1009. //
  1010. // Check the arguments.
  1011. //
  1012. ASSERT(ulBase == ETH_BASE);
  1013. ASSERT(!(ulIntFlags & ~(ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
  1014. ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER |
  1015. ETH_INT_RX)));
  1016. //
  1017. // Disable the specified interrupts.
  1018. //
  1019. HWREG(ulBase + MAC_O_IM) &= ~ulIntFlags;
  1020. }
  1021. //*****************************************************************************
  1022. //
  1023. //! Gets the current Ethernet interrupt status.
  1024. //!
  1025. //! \param ulBase is the base address of the controller.
  1026. //! \param bMasked is false if the raw interrupt status is required and true
  1027. //! if the masked interrupt status is required.
  1028. //!
  1029. //! This function returns the interrupt status for the Ethernet controller.
  1030. //! Either the raw interrupt status or the status of interrupts that are
  1031. //! allowed to reflect to the processor can be returned.
  1032. //!
  1033. //! \return Returns the current interrupt status, enumerated as a bit field of
  1034. //! values described in EthernetIntEnable().
  1035. //
  1036. //*****************************************************************************
  1037. unsigned long
  1038. EthernetIntStatus(unsigned long ulBase, tBoolean bMasked)
  1039. {
  1040. unsigned long ulStatus;
  1041. //
  1042. // Check the arguments.
  1043. //
  1044. ASSERT(ulBase == ETH_BASE);
  1045. //
  1046. // Read the unmasked status.
  1047. //
  1048. ulStatus = HWREG(ulBase + MAC_O_RIS);
  1049. //
  1050. // If masked status is requested, mask it off.
  1051. //
  1052. if(bMasked)
  1053. {
  1054. ulStatus &= HWREG(ulBase + MAC_O_IM);
  1055. }
  1056. //
  1057. // Return the interrupt status value.
  1058. //
  1059. return(ulStatus);
  1060. }
  1061. //*****************************************************************************
  1062. //
  1063. //! Clears Ethernet interrupt sources.
  1064. //!
  1065. //! \param ulBase is the base address of the controller.
  1066. //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
  1067. //!
  1068. //! The specified Ethernet interrupt sources are cleared so that they no longer
  1069. //! assert. This function must be called in the interrupt handler to keep the
  1070. //! interrupt from being triggered again immediately upon exit.
  1071. //!
  1072. //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
  1073. //! parameter to EthernetIntEnable().
  1074. //!
  1075. //! \note Because there is a write buffer in the Cortex-M processor, it may
  1076. //! take several clock cycles before the interrupt source is actually cleared.
  1077. //! Therefore, it is recommended that the interrupt source be cleared early in
  1078. //! the interrupt handler (as opposed to the very last action) to avoid
  1079. //! returning from the interrupt handler before the interrupt source is
  1080. //! actually cleared. Failure to do so may result in the interrupt handler
  1081. //! being immediately reentered (because the interrupt controller still sees
  1082. //! the interrupt source asserted).
  1083. //!
  1084. //! \return None.
  1085. //
  1086. //*****************************************************************************
  1087. void
  1088. EthernetIntClear(unsigned long ulBase, unsigned long ulIntFlags)
  1089. {
  1090. //
  1091. // Check the arguments.
  1092. //
  1093. ASSERT(ulBase == ETH_BASE);
  1094. ASSERT(!(ulIntFlags & ~(ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
  1095. ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER |
  1096. ETH_INT_RX)));
  1097. //
  1098. // Clear the requested interrupt sources.
  1099. //
  1100. HWREG(ulBase + MAC_O_IACK) = ulIntFlags;
  1101. }
  1102. //*****************************************************************************
  1103. //
  1104. //! Sets the PHY address.
  1105. //!
  1106. //! \param ulBase is the base address of the controller.
  1107. //! \param ucAddr is the address of the PHY.
  1108. //!
  1109. //! This function sets the address of the PHY that is accessed via
  1110. //! EthernetPHYRead() and EthernePHYWrite(). This configuration is only needed
  1111. //! when connecting to an external PHY via MII, and should not be used on
  1112. //! devices that have integrated PHYs.
  1113. //!
  1114. //! \return None.
  1115. //
  1116. //*****************************************************************************
  1117. void
  1118. EthernetPHYAddrSet(unsigned long ulBase, unsigned char ucAddr)
  1119. {
  1120. //
  1121. // Check the arguments.
  1122. //
  1123. ASSERT(ulBase == ETH_BASE);
  1124. //
  1125. // Wait for any pending transaction to complete.
  1126. //
  1127. while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
  1128. {
  1129. }
  1130. //
  1131. // Set the PHY address.
  1132. //
  1133. HWREG(ulBase + MAC_O_MADD) = ucAddr;
  1134. }
  1135. //*****************************************************************************
  1136. //
  1137. //! Writes to the PHY register.
  1138. //!
  1139. //! \param ulBase is the base address of the controller.
  1140. //! \param ucRegAddr is the address of the PHY register to be accessed.
  1141. //! \param ulData is the data to be written to the PHY register.
  1142. //!
  1143. //! This function writes the \e ulData to the PHY register specified by
  1144. //! \e ucRegAddr.
  1145. //!
  1146. //! \return None.
  1147. //
  1148. //*****************************************************************************
  1149. void
  1150. EthernetPHYWrite(unsigned long ulBase, unsigned char ucRegAddr,
  1151. unsigned long ulData)
  1152. {
  1153. //
  1154. // Check the arguments.
  1155. //
  1156. ASSERT(ulBase == ETH_BASE);
  1157. //
  1158. // Wait for any pending transaction to complete.
  1159. //
  1160. while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
  1161. {
  1162. }
  1163. //
  1164. // Program the DATA to be written.
  1165. //
  1166. HWREG(ulBase + MAC_O_MTXD) = ulData & MAC_MTXD_MDTX_M;
  1167. //
  1168. // Program the PHY register address and initiate the transaction.
  1169. //
  1170. HWREG(ulBase + MAC_O_MCTL) = (((ucRegAddr << 3) & MAC_MCTL_REGADR_M) |
  1171. MAC_MCTL_WRITE | MAC_MCTL_START);
  1172. //
  1173. // Wait for the write transaction to complete.
  1174. //
  1175. while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
  1176. {
  1177. }
  1178. }
  1179. //*****************************************************************************
  1180. //
  1181. //! Reads from a PHY register.
  1182. //!
  1183. //! \param ulBase is the base address of the controller.
  1184. //! \param ucRegAddr is the address of the PHY register to be accessed.
  1185. //!
  1186. //! This function returns the contents of the PHY register specified by
  1187. //! \e ucRegAddr.
  1188. //!
  1189. //! \return Returns the 16-bit value read from the PHY.
  1190. //
  1191. //*****************************************************************************
  1192. unsigned long
  1193. EthernetPHYRead(unsigned long ulBase, unsigned char ucRegAddr)
  1194. {
  1195. //
  1196. // Check the arguments.
  1197. //
  1198. ASSERT(ulBase == ETH_BASE);
  1199. //
  1200. // Wait for any pending transaction to complete.
  1201. //
  1202. while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
  1203. {
  1204. }
  1205. //
  1206. // Program the PHY register address and initiate the transaction.
  1207. //
  1208. HWREG(ulBase + MAC_O_MCTL) = (((ucRegAddr << 3) & MAC_MCTL_REGADR_M) |
  1209. MAC_MCTL_START);
  1210. //
  1211. // Wait for the transaction to complete.
  1212. //
  1213. while(HWREG(ulBase + MAC_O_MCTL) & MAC_MCTL_START)
  1214. {
  1215. }
  1216. //
  1217. // Return the PHY data that was read.
  1218. //
  1219. return(HWREG(ulBase + MAC_O_MRXD) & MAC_MRXD_MDRX_M);
  1220. }
  1221. //*****************************************************************************
  1222. //
  1223. //! Powers off the Ethernet PHY.
  1224. //!
  1225. //! \param ulBase is the base address of the controller.
  1226. //!
  1227. //! This function powers off the Ethernet PHY, reducing the current
  1228. //! consumption of the device. While in the powered off state, the Ethernet
  1229. //! controller is unable to connect to the Ethernet.
  1230. //!
  1231. //! \return None.
  1232. //
  1233. //*****************************************************************************
  1234. void
  1235. EthernetPHYPowerOff(unsigned long ulBase)
  1236. {
  1237. //
  1238. // Set the PWRDN bit and clear the ANEGEN bit in the PHY, putting it into
  1239. // its low power mode.
  1240. //
  1241. EthernetPHYWrite(ulBase, PHY_MR0,
  1242. (EthernetPHYRead(ulBase, PHY_MR0) & ~PHY_MR0_ANEGEN) |
  1243. PHY_MR0_PWRDN);
  1244. }
  1245. //*****************************************************************************
  1246. //
  1247. //! Powers on the Ethernet PHY.
  1248. //!
  1249. //! \param ulBase is the base address of the controller.
  1250. //!
  1251. //! This function powers on the Ethernet PHY, enabling it return to normal
  1252. //! operation. By default, the PHY is powered on, so this function is only
  1253. //! called if EthernetPHYPowerOff() has previously been called.
  1254. //!
  1255. //! \return None.
  1256. //
  1257. //*****************************************************************************
  1258. void
  1259. EthernetPHYPowerOn(unsigned long ulBase)
  1260. {
  1261. //
  1262. // Clear the PWRDN bit and set the ANEGEN bit in the PHY, putting it into
  1263. // normal operating mode.
  1264. //
  1265. EthernetPHYWrite(ulBase, PHY_MR0,
  1266. (EthernetPHYRead(ulBase, PHY_MR0) & ~PHY_MR0_PWRDN) |
  1267. PHY_MR0_ANEGEN);
  1268. }
  1269. //*****************************************************************************
  1270. //
  1271. // Close the Doxygen group.
  1272. //! @}
  1273. //
  1274. //*****************************************************************************