ethernet.c 44 KB

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