ethernet.c 47 KB

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