iLLD_TC27xD  1.0
IfxEth.c
Go to the documentation of this file.
1 /**
2  * \file IfxEth.c
3  * \brief ETH basic functionality
4  *
5  * \version iLLD_1_0_0_11_0
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  */
24 
25 /******************************************************************************/
26 /*----------------------------------Includes----------------------------------*/
27 /******************************************************************************/
28 
29 #include "IfxEth.h"
30 
31 /******************************************************************************/
32 /*-----------------------Exported Variables/Constants-------------------------*/
33 /******************************************************************************/
34 
36 
38 
40 
42 
43 /******************************************************************************/
44 /*-------------------------Function Implementations---------------------------*/
45 /******************************************************************************/
46 
48 {
49  {
51  IfxScuWdt_clearCpuEndinit(l_TempVar);
52  ETH_CLC.U = 0;
53  IfxScuWdt_setCpuEndinit(l_TempVar);
54  }
55 }
56 
57 
59 {
63 }
64 
65 
67 {
68  void *result = 0;
69  IfxEth_RxDescr *descr;
70 
71  if (IfxEth_isRxDataAvailable(eth))
72  {
73  eth->rxCount++;
74  descr = IfxEth_getActualRxDescriptor(eth);
75  result = (void *)(descr->RDES2.U);
76  }
77 
79 
80  return result;
81 }
82 
83 
85 {
86  void *buffer = NULL_PTR;
88 
89  // check descriptor / buffer is free.
90  if (descr->TDES0.A.OWN == 0)
91  {
92  buffer = ((void *)descr->TDES2.U);
93  }
94 
95  return buffer;
96 }
97 
98 
99 void IfxEth_init(IfxEth *eth, const IfxEth_Config *config)
100 {
101  eth->ethSfr = config->ethSfr;
102 
103 #ifndef _WIN32
105 
107  {
108  IfxEth_setupRmiiOutputPins(eth, config->rmiiPins);
109  IfxEth_setupRmiiInputPins(eth, config->rmiiPins);
110  }
111  else
112  {
113  IfxEth_setupMiiOutputPins(eth, config->miiPins);
114  IfxEth_setupMiiInputPins(eth, config->miiPins);
115  }
116 
117 #endif
118 
120 
121  /* select the Phy Interface Mode */
124 
125  /* wait until reset is finished or timeout. */
126  {
127  uint32 timeout = 0;
128 
129  while ((IfxEth_isSoftwareResetDone(eth) == 0) && (timeout < IFXETH_MAX_TIMEOUT_VALUE))
130  {
131  timeout++;
132  }
133  }
134 
135  /* configure bus mode */
136  {
137  Ifx_ETH_BUS_MODE busMode;
138  busMode.U = ETH_BUS_MODE.U;
139  busMode.B.DSL = 0; /* descriptor skip length in ring mode */
140  busMode.B.ATDS = 0; /* alternate descriptor size: 0 => 4 DWORDS, 1 => 8 DWORDS */
141  busMode.B.DA = 0; /* 0 = weighted round-robin, 1 = fixed priority */
142 
143  ETH_BUS_MODE.U = busMode.U;
144  }
145 
146  /* configure ETH MAC */
147  {
148  Ifx_ETH_MAC_CONFIGURATION ethMacCfg;
149  ethMacCfg.U = ETH_MAC_CONFIGURATION.U;
150 
151  ethMacCfg.B.PRELEN = 0; /* 7 bytes preamble */
152  // ethMacCfg.B.RE = 0; /* disable receiver */
153  // ethMacCfg.B.TE = 0; /* disable transmitter */
154  ethMacCfg.B.DC = 0; /* Deferral Check */
155  // ethMacCfg.B.BL = 0; /* Backoff Limit */
156  ethMacCfg.B.ACS = 1; /* Automatic Pad/CRC stripping--less than 1536 bytes */
157  // ethMacCfg.B.DR = 0; /* Disable Retry */
158  ethMacCfg.B.IPC = 0; /* checksum offload */
159  ethMacCfg.B.DM = 1; /* Duplex Mode: 0=Half Duplex, 1=Full duplex */
160  ethMacCfg.B.LM = 0; /* Loopback Mode */
161  // ethMacCfg.B.DO = 0; /* Disable Receive Own */
162  ethMacCfg.B.FES = 1; /* Speed 0->10mbps 1->100mbps */
163  ethMacCfg.B.PS = 1; /* port select 10/100mbps */
164  ethMacCfg.B.IFG = 0; /* Inter Frame Gap - gap between frames = 96 bit times */
165  ethMacCfg.B.JE = 0; /* Jumbo Frame Enable - no jumbo frames */
166  ethMacCfg.B.JD = 0; /* Jabber Disable - cut of transmission after 2,048 data bytes. */
167  ethMacCfg.B.WD = 0; /* Watchdog Disable - cut off frame after 2,048 bytes. */
168  ethMacCfg.B.CST = 1; /* CRC stripping - last four bytes are stripped and dropped to application. */
169  ethMacCfg.B.TWOKPE = 0; /* 2K Packets Enable - with JE=0 - all received frames of size > 1,518bytes are Giant frames.*/
170 
171  ETH_MAC_CONFIGURATION.U = ethMacCfg.U;
172  }
173 
174  IfxEth_setMacAddress(eth, config->macAddress);
175 
176  /* setup MMC */
177  ETH_MMC_CONTROL.B.CNTFREEZ = 1; /* disable MMC counters - counters reset */
178 
179  /* setup GMAC */
180  ETH_STATUS.U = 0x0001e7ff; /* reset all interrupt flag(s) */
181  ETH_MAC_FRAME_FILTER.U = 0x00000010; /* Hash Unicast */
182 
183  ETH_INTERRUPT_ENABLE.U = 0x00010041; /* enable tx & rx interrupts */
184 
185 #ifndef _WIN32
186 
187  if (config->isrPriority)
188  {
189  IfxSrc_init(&SRC_ETH, config->isrProvider, config->isrPriority);
190  IfxSrc_enable(&SRC_ETH);
191  }
192 
193  if (config->phyInit != NULL_PTR)
194  {
195  config->phyInit(); /* init PHY (100Mbit, full duplex with RMII) */
196  }
197 
198 #endif
199 
200  eth->config = *config;
201  eth->error = 0;
202  eth->status.U = 0;
203  eth->rxCount = 0;
204  eth->txCount = 0;
205 
207 
210 
211  eth->rxDescr = config->rxDescr;
212  eth->txDescr = config->txDescr;
213 
216 }
217 
218 
219 void IfxEth_initConfig(IfxEth_Config *config, Ifx_ETH *ethSfr)
220 {
221  const IfxEth_Config defaultConfig = {
222  {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}, /* MAC address */
223  NULL_PTR,
224  NULL_PTR,
225  IfxEth_PhyInterfaceMode_rmii, /* PHY Interfac mode RMII */
226  NULL_PTR, /* Pointer to the RMII pin config */
227  NULL_PTR, /* Pointer to the MII pin config */
228  (Ifx_Priority)0, /* Interrupt serivce priority */
229  IfxSrc_Tos_cpu0, /* Interrupt serivce provider */
230  NULL_PTR, /* Pointer to register base */
231  &IfxEth_rxDescr, /* pointer to RX descriptor RAM */
232  &IfxEth_txDescr, /* pointer to TX descriptor RAM */
233  };
234 
235  *config = defaultConfig;
236  config->ethSfr = ethSfr;
237 }
238 
239 
241 {
242  /* Use enhanced descriptors, because ETH is generally configured to precision time protocol. */
243  int i;
245 
246  eth->pRxDescr = descr;
247 
248  /* init descriptor chained mode */
249  for (i = 0; i < IFXETH_MAX_RX_BUFFERS; i++)
250  {
251  descr->RDES0.U = 0;
252  descr->RDES0.A.OWN = 1U;
253 
254  descr->RDES1.U = 0;
255  descr->RDES1.A.RCH = 1U;
256  descr->RDES1.A.RBS1 = (IFXETH_RTX_BUFFER_SIZE);
257 
258 #if !IFXETH_RX_BUFFER_BY_USER
259  IfxEth_RxDescr_setBuffer(descr, &(IfxEth_rxBuffer[i][0]));
260 #endif
261 
262  /* with RCH set, link to next descriptor address */
263  descr->RDES3.U = (uint32)&(descr[1]);
264  descr = &descr[1];
265  }
266 
267  /* correction for last descriptor */
268  {
269  descr = &descr[-1];
270 
271  /* indicate end of ring */
272  descr->RDES1.A.RER = 1U;
273 
274  /* with RCH set, link to first descriptor address */
276  descr->RDES3.U = (uint32)eth->pRxDescr;
277  }
278 
279  eth->rxCount = 0;
280 
281  /* write descriptor list base address */
283 }
284 
285 
287 {
288  int i;
290 
291  eth->pTxDescr = descr;
292 
293  /* Initialize chained descriptor mode */
294  for (i = 0; i < IFXETH_MAX_TX_BUFFERS; i++)
295  {
296  descr->TDES0.U = 0;
297  descr->TDES0.A.IC = 1U;
298  descr->TDES0.A.FS = 1U;
299  descr->TDES0.A.LS = 1U;
300  descr->TDES0.A.TCH = 1U;
301 
302 #if !IFXETH_TX_BUFFER_BY_USER
303  IfxEth_TxDescr_setBuffer(descr, &(IfxEth_txBuffer[i][0]));
304 #endif
305 
306  /* with TCH set, TDES3 points to next descriptor */
307  descr->TDES3.U = (uint32)&descr[1];
308  descr = &descr[1];
309  }
310 
311  /* correction for last descriptor */
312  {
313  descr = &descr[-1];
314 
315  /* indicate end of ring */
316  descr->TDES0.A.TER = 1U;
317 
318  /* with TCH set, TDES3 points to the first descriptor */
320  descr->TDES3.U = (uint32)eth->pTxDescr;
321  }
322 
323  eth->txCount = 0;
324 
325  /* write descriptor list base address */
327 }
328 
329 
330 void IfxEth_readMacAddress(IfxEth *eth, uint8 *macAddress)
331 {
332  (void)eth;
333  *((uint32 *)macAddress) = ETH_MAC_ADDRESS_G00_LOW.U;
334  *((uint16 *)(&macAddress[4])) = (uint16)(ETH_MAC_ADDRESS_G00_HIGH.U & 0xFFFFU);
335 }
336 
337 
339 {
342 
343  ETH_KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
344  ETH_KRST1.B.RST = 1;
345  IfxScuWdt_setCpuEndinit(passwd);
346 
347  while (0 == ETH_KRST0.B.RSTSTAT) /* Wait until reset is executed */
348  {}
349 
351  ETH_KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
352 
353  IfxScuWdt_setCpuEndinit(passwd);
354 }
355 
356 
358 {
360 
361  descr->TDES1.U = len; /* with TCH set, TBS1 is used for buffer size */
362  descr->TDES0.A.OWN = 1U; /* release to DMA */
363 
366 
367  eth->txCount++;
368 }
369 
370 
371 void IfxEth_setAndSendTransmitBuffer(IfxEth *eth, void *buffer, uint16 len)
372 {
374  IfxEth_sendTransmitBuffer(eth, len);
375 }
376 
377 
378 void IfxEth_setMacAddress(IfxEth *eth, const uint8 *macAddress)
379 {
380  (void)eth;
381  ETH_MAC_ADDRESS_G00_HIGH.U = 0
382  | ((uint32)macAddress[4] << 0U)
383  | ((uint32)macAddress[5] << 8U)
384  | 0x80000000U;
385 
386  ETH_MAC_ADDRESS_G00_LOW.U = 0
387  | ((uint32)macAddress[0] << 0U)
388  | ((uint32)macAddress[1] << 8U)
389  | ((uint32)macAddress[2] << 16U)
390  | ((uint32)macAddress[3] << 24U)
391  ;
392 }
393 
394 
396 {
397  int i;
398 
399  if (mode != IfxEth_ChecksumMode_bypass)
400  {
401  ETH_OPERATION_MODE.B.TSF = 1U;
402  ETH_OPERATION_MODE.B.DT = 0U; /* 0 = drop TCP/IP frame with checksum error */
403  ETH_MAC_CONFIGURATION.B.IPC = 1U; /* 1 = enable received IP frame checksum engine */
404 
406 
407  for (i = 0; i < IFXETH_MAX_TX_BUFFERS; i++)
408  {
409  descr->TDES0.A.CIC = mode;
410  descr = IfxEth_TxDescr_getNext(descr);
411  }
412  }
413 }
414 
415 
417 {
418  (void)eth;
419 
422 
423  IfxEth_Crs_In *crs = miiPins->crs;
424  IfxEth_Col_In *col = miiPins->col;
425  IfxEth_Txclk_In *txClk = miiPins->txClk;
426  IfxEth_Rxclk_In *rxClk = miiPins->rxClk;
427  IfxEth_Rxdv_In *rxDv = miiPins->rxDv;
428  IfxEth_Rxer_In *rxEr = miiPins->rxEr;
429  IfxEth_Rxd_In *rxd0 = miiPins->rxd0;
430  IfxEth_Rxd_In *rxd1 = miiPins->rxd1;
431  IfxEth_Rxd_In *rxd2 = miiPins->rxd2;
432  IfxEth_Rxd_In *rxd3 = miiPins->rxd3;
433 
434  ETH_GPCTL.B.ALTI1 = rxClk->select;
435  ETH_GPCTL.B.ALTI2 = crs->select;
436  ETH_GPCTL.B.ALTI3 = col->select;
437  ETH_GPCTL.B.ALTI4 = rxDv->select;
438  ETH_GPCTL.B.ALTI5 = rxEr->select;
439  ETH_GPCTL.B.ALTI6 = rxd0->select;
440  ETH_GPCTL.B.ALTI7 = rxd1->select;
441  ETH_GPCTL.B.ALTI8 = rxd2->select;
442  ETH_GPCTL.B.ALTI9 = rxd3->select;
443  ETH_GPCTL.B.ALTI10 = txClk->select;
444 
445  {
446  IfxPort_setPinModeInput(crs->pin.port, crs->pin.pinIndex, mode);
447  IfxPort_setPinModeInput(col->pin.port, col->pin.pinIndex, mode);
448  IfxPort_setPinModeInput(txClk->pin.port, txClk->pin.pinIndex, mode);
449  IfxPort_setPinModeInput(rxClk->pin.port, rxClk->pin.pinIndex, mode);
450  IfxPort_setPinModeInput(rxDv->pin.port, rxDv->pin.pinIndex, mode);
451  IfxPort_setPinModeInput(rxEr->pin.port, rxEr->pin.pinIndex, mode);
452  IfxPort_setPinModeInput(rxd0->pin.port, rxd0->pin.pinIndex, mode);
453  IfxPort_setPinModeInput(rxd1->pin.port, rxd1->pin.pinIndex, mode);
454  IfxPort_setPinModeInput(rxd2->pin.port, rxd2->pin.pinIndex, mode);
455  IfxPort_setPinModeInput(rxd3->pin.port, rxd3->pin.pinIndex, mode);
456 
457  IfxPort_setPinPadDriver(crs->pin.port, crs->pin.pinIndex, speedGrade);
458  IfxPort_setPinPadDriver(col->pin.port, col->pin.pinIndex, speedGrade);
459  IfxPort_setPinPadDriver(txClk->pin.port, txClk->pin.pinIndex, speedGrade);
460  IfxPort_setPinPadDriver(rxClk->pin.port, rxClk->pin.pinIndex, speedGrade);
461  IfxPort_setPinPadDriver(rxDv->pin.port, rxDv->pin.pinIndex, speedGrade);
462  IfxPort_setPinPadDriver(rxEr->pin.port, rxEr->pin.pinIndex, speedGrade);
463  IfxPort_setPinPadDriver(rxd0->pin.port, rxd0->pin.pinIndex, speedGrade);
464  IfxPort_setPinPadDriver(rxd1->pin.port, rxd1->pin.pinIndex, speedGrade);
465  IfxPort_setPinPadDriver(rxd2->pin.port, rxd2->pin.pinIndex, speedGrade);
466  IfxPort_setPinPadDriver(rxd3->pin.port, rxd3->pin.pinIndex, speedGrade);
467  }
468 }
469 
470 
472 {
475 
476  IfxEth_Txen_Out *txEn = miiPins->txEn;
477  IfxEth_Txer_Out *txEr = miiPins->txEr;
478  IfxEth_Txd_Out *txd0 = miiPins->txd0;
479  IfxEth_Txd_Out *txd1 = miiPins->txd1;
480  IfxEth_Txd_Out *txd2 = miiPins->txd2;
481  IfxEth_Txd_Out *txd3 = miiPins->txd3;
482 
483  (void)eth;
484 
485  IfxPort_setPinPadDriver(txEn->pin.port, txEn->pin.pinIndex, speedGrade);
486  IfxPort_setPinPadDriver(txEr->pin.port, txEr->pin.pinIndex, speedGrade);
487  IfxPort_setPinPadDriver(txd0->pin.port, txd0->pin.pinIndex, speedGrade);
488  IfxPort_setPinPadDriver(txd1->pin.port, txd1->pin.pinIndex, speedGrade);
489  IfxPort_setPinPadDriver(txd2->pin.port, txd2->pin.pinIndex, speedGrade);
490  IfxPort_setPinPadDriver(txd3->pin.port, txd3->pin.pinIndex, speedGrade);
491 
492  IfxPort_setPinModeOutput(txEn->pin.port, txEn->pin.pinIndex, mode, txEn->select);
493  IfxPort_setPinModeOutput(txEr->pin.port, txEr->pin.pinIndex, mode, txEr->select);
494  IfxPort_setPinModeOutput(txd0->pin.port, txd0->pin.pinIndex, mode, txd0->select);
495  IfxPort_setPinModeOutput(txd1->pin.port, txd1->pin.pinIndex, mode, txd1->select);
496  IfxPort_setPinModeOutput(txd2->pin.port, txd2->pin.pinIndex, mode, txd2->select);
497  IfxPort_setPinModeOutput(txd3->pin.port, txd3->pin.pinIndex, mode, txd3->select);
498 }
499 
500 
502 {
503  (void)eth;
504 
505  ETH_GPCTL.B.ALTI0 = rmiiPins->mdio->inSelect;
506  ETH_GPCTL.B.ALTI1 = rmiiPins->refClk->select;
507  ETH_GPCTL.B.ALTI4 = rmiiPins->crsDiv->select;
508  ETH_GPCTL.B.ALTI6 = rmiiPins->rxd0->select;
509  ETH_GPCTL.B.ALTI7 = rmiiPins->rxd1->select;
510 
511  {
514 
515  IfxEth_Crsdv_In *crsDiv = rmiiPins->crsDiv;
516  IfxEth_Refclk_In *refClk = rmiiPins->refClk;
517  IfxEth_Rxd_In *rxd0 = rmiiPins->rxd0;
518  IfxEth_Rxd_In *rxd1 = rmiiPins->rxd1;
519 
520  IfxPort_setPinModeInput(crsDiv->pin.port, crsDiv->pin.pinIndex, mode);
521  IfxPort_setPinModeInput(refClk->pin.port, refClk->pin.pinIndex, mode);
522  IfxPort_setPinModeInput(rxd0->pin.port, rxd0->pin.pinIndex, mode);
523  IfxPort_setPinModeInput(rxd1->pin.port, rxd1->pin.pinIndex, mode);
524 
525  IfxPort_setPinPadDriver(crsDiv->pin.port, crsDiv->pin.pinIndex, speedGrade);
526  IfxPort_setPinPadDriver(refClk->pin.port, refClk->pin.pinIndex, speedGrade);
527  IfxPort_setPinPadDriver(rxd0->pin.port, rxd0->pin.pinIndex, speedGrade);
528  IfxPort_setPinPadDriver(rxd1->pin.port, rxd1->pin.pinIndex, speedGrade);
529  }
530 }
531 
532 
534 {
537 
538  IfxEth_Mdc_Out *mdc = rmiiPins->mdc;
539  IfxEth_Mdio_InOut *mdio = rmiiPins->mdio;
540  IfxEth_Txen_Out *txen = rmiiPins->txEn;
541  IfxEth_Txd_Out *txd0 = rmiiPins->txd0;
542  IfxEth_Txd_Out *txd1 = rmiiPins->txd1;
543 
544  (void)eth;
545 
546 #if 0
547  IfxPort_setPinPadDriver(mdc->pin.port, mdc->pin.pinIndex, speedGrade);
548  IfxPort_setPinPadDriver(mdio->pin.port, mdio->pin.pinIndex, speedGrade);
549 #endif
550  IfxPort_setPinPadDriver(txen->pin.port, txen->pin.pinIndex, speedGrade);
551  IfxPort_setPinPadDriver(txd0->pin.port, txd0->pin.pinIndex, speedGrade);
552  IfxPort_setPinPadDriver(txd1->pin.port, txd1->pin.pinIndex, speedGrade);
553 
554  IfxPort_setPinModeOutput(mdc->pin.port, mdc->pin.pinIndex, mode, mdc->select);
555  IfxPort_setPinModeOutput(txen->pin.port, txen->pin.pinIndex, mode, txen->select);
556  IfxPort_setPinModeOutput(txd0->pin.port, txd0->pin.pinIndex, mode, txd0->select);
557  IfxPort_setPinModeOutput(txd1->pin.port, txd1->pin.pinIndex, mode, txd1->select);
558 
559  // For MDIO, when P21.1 is used it should be configured as output
560  if ((mdio->pin.port == (&MODULE_P21)) && (mdio->pin.pinIndex == 1))
561  {
562  IfxPort_setPinModeOutput(mdio->pin.port, mdio->pin.pinIndex, mode, mdio->outSelect);
563  }
564 }
565 
566 
568 {
569  (void)eth;
570 
571  // enable receiver and RX DMA
572  ETH_OPERATION_MODE.B.SR = 1;
573  ETH_MAC_CONFIGURATION.B.RE = 1;
574  ETH_RECEIVE_POLL_DEMAND.U = 1;
575 }
576 
577 
579 {
580  (void)eth;
581 
582  ETH_MAC_CONFIGURATION.B.TE = 1;
583  ETH_OPERATION_MODE.B.ST = 1;
584  ETH_TRANSMIT_POLL_DEMAND.U = 1;
585 }
586 
587 
589 {
590  (void)eth;
591 
592  ETH_TRANSMIT_POLL_DEMAND.U = 0;
593  ETH_OPERATION_MODE.B.ST = 0;
594  ETH_MAC_CONFIGURATION.B.TE = 0;
595 }
596 
597 
599 {
600  eth->status.U = ETH_STATUS.U;
601 
602  // check if receiver suspended
603  if (eth->status.U & (4U << IFX_ETH_STATUS_RS_OFF))
604  {
605  if (eth->status.B.RU)
606  {
607  ETH_STATUS.U = (IFX_ETH_STATUS_RU_MSK << IFX_ETH_STATUS_RU_OFF);
608  }
609 
611  }
612 }
613 
614 
616 {
617  eth->status.U = ETH_STATUS.U;
618 
619  // check if suspended
620  if (eth->status.U & 0x00600000)
621  {
622  if (eth->status.B.TU)
623  {
624  // clear transmit unavailable and underflow flags
625  ETH_STATUS.U = (IFX_ETH_STATUS_TU_MSK << IFX_ETH_STATUS_TU_OFF) |
626  (IFX_ETH_STATUS_UNF_MSK << IFX_ETH_STATUS_UNF_OFF);
627  }
628 
630  }
631 }
632 
633 
634 void IfxEth_writeHeader(IfxEth *eth, uint8 *txBuffer, uint8 *destinationAddress, uint8 *sourceAddress, uint32 packetSize)
635 {
636  (void)eth;
637  uint32 i;
638 
639  /* Destination Address */
640  for (i = 0; i < 6; i++)
641  {
642  *txBuffer++ = *destinationAddress++;
643  }
644 
645  /* Source Address */
646  for (i = 0; i < 6; i++)
647  {
648  *txBuffer++ = *sourceAddress++;
649  }
650 
651  /* packet size */
652  *txBuffer++ = (uint8)(packetSize / 256);
653  *txBuffer = (uint8)(packetSize % 256);
654 }