00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include <board.h>
00104 #include <string.h>
00105
00106 #include "MiniIp.h"
00107
00108
00109
00110
00111
00112 #define TX_BUFFERS 32
00113 #define RX_BUFFERS 32
00114
00115 #define BUFFER_SIZE 1536
00116 #define DUMMY_SIZE 2
00117 #define DUMMY_BUFF_SIZE 128
00118
00119
00120 #define GMAC_RCV_OFFSET 0
00121
00122
00123 #define GMAC_CAF_DISABLE 0
00124 #define GMAC_CAF_ENABLE 1
00125
00126
00127 #define GMAC_NBC_DISABLE 0
00128 #define GMAC_NBC_ENABLE 1
00129
00130
00131
00132 #define GMAX_ARP_REQUEST 100
00133 #define GMIN_ARP_REPLY 90
00134
00135
00136 #define GMAX_TRY_LINK 500
00137
00138
00139 #define TWCK 400000
00140
00141 #define AT24MAC_SERIAL_NUM_ADD 0x5F
00142
00143 #define PAGE_SIZE 16
00144
00145 #define EEPROM_PAGES 16
00146
00147 #define BOARD_PINS_TWI_EEPROM PINS_TWI0
00148
00149 #define BOARD_ID_TWI_EEPROM ID_TWIHS0
00150
00151 #define BOARD_BASE_TWI_EEPROM TWIHS0
00152
00153
00154
00155
00156 static Twid twid;
00157
00158
00159 #if !defined(BOARD_GMAC_POWER_ALWAYS_ON)
00160 static const Pin gmacPwrDn[] = {BOARD_GMAC_PIN_PWRDN};
00161 #endif
00162
00163
00164 static const Pin gmacPins[] = {BOARD_GMAC_RUN_PINS};
00165 static const Pin gmacResetPin = BOARD_GMAC_RESET_PIN;
00166
00167 static const Pin twiPins[] = BOARD_PINS_TWI_EEPROM;
00168
00169
00170 static uint8_t GMacAddress[6] = {0x3a, 0x1f, 0x34, 0x08, 0x54, 0x54};
00171
00172
00173 static uint8_t GIpAddress[4] = {192, 168, 1, 3 };
00174 static uint8_t GDesIpAddress[4] = {192, 168, 1, 2 };
00175
00176
00177 static sGmacd gGmacd;
00178
00179
00180 static GMacb gGmacb;
00181
00182
00183 COMPILER_SECTION(".ram_nocache")
00184 COMPILER_ALIGNED(8) static sGmacTxDescriptor gTxDs[TX_BUFFERS],
00185 gDummyTxDs[DUMMY_SIZE];
00186
00187
00188
00189 COMPILER_ALIGNED(8) static fGmacdTransferCallback gTxCbs[TX_BUFFERS],
00190 gDummyTxCbs[DUMMY_SIZE];
00191
00192
00193 COMPILER_SECTION(".ram_nocache")
00194 COMPILER_ALIGNED(8) static sGmacRxDescriptor gRxDs[RX_BUFFERS],
00195 gDummyRxDs[DUMMY_SIZE];
00196
00197
00198
00199
00200
00201 COMPILER_ALIGNED(32) static uint8_t pTxBuffer[TX_BUFFERS * BUFFER_SIZE],
00202 pTxDummyBuffer[DUMMY_SIZE * DUMMY_BUFF_SIZE];
00203
00204
00205 COMPILER_ALIGNED(32) static uint8_t pRxBuffer[RX_BUFFERS * BUFFER_SIZE],
00206 pRxDummyBuffer[DUMMY_SIZE * DUMMY_BUFF_SIZE];
00207
00208
00209 static uint8_t GEthBuffer[BUFFER_SIZE * TX_BUFFERS * 2];
00210
00211 static uint8_t gbIsIpAddrInit = 1;
00212 static uint8_t gtotal_request;
00213 static uint8_t gtotal_reply;
00214
00215
00216
00217
00218
00219
00220
00221 void GMAC_Handler(void)
00222 {
00223 GMACD_Handler(&gGmacd, GMAC_QUE_0);
00224 }
00225
00226
00227
00228
00229 static void GDisplayEthernetHeader(PEthHeader pEth, uint32_t size)
00230 {
00231 printf("======= Ethernet %4u bytes, HEADER ==========\n\r",
00232 (unsigned int)size);
00233 printf(" @Mac dst = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00234 pEth->et_dest[0], pEth->et_dest[1], pEth->et_dest[2],
00235 pEth->et_dest[3], pEth->et_dest[4], pEth->et_dest[5]);
00236 printf(" @Mac src = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00237 pEth->et_src[0], pEth->et_src[1], pEth->et_src[2],
00238 pEth->et_src[3], pEth->et_src[4], pEth->et_src[5]);
00239 printf(" Protocol = %d\n\r", pEth->et_protlen);
00240 }
00241
00242 static void GDisplayArpHeader(PArpHeader pArp, uint32_t size)
00243 {
00244 printf("======= ARP %4u bytes, HEADER ==========\n\r", (unsigned int)size);
00245 printf(" Hardware type = %d\n\r", SWAP16(pArp->ar_hrd) );
00246 printf(" protocol type = 0x%04x\n\r", SWAP16(pArp->ar_pro) );
00247 printf(" Hardware addr lg = %d\n\r", pArp->ar_hln);
00248 printf(" Protocol addr lg = %d\n\r", pArp->ar_pln);
00249 printf(" Operation = %d\n\r", SWAP16(pArp->ar_op) );
00250 printf(" Sender hardware addr = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00251 pArp->ar_sha[0], pArp->ar_sha[1], pArp->ar_sha[2],
00252 pArp->ar_sha[3], pArp->ar_sha[4], pArp->ar_sha[5]);
00253 printf(" Sender protocol addr = %d.%d.%d.%d\n\r",
00254 pArp->ar_spa[0], pArp->ar_spa[1], pArp->ar_spa[2], pArp->ar_spa[3]);
00255 printf(" Target hardware addr = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00256 pArp->ar_tha[0], pArp->ar_tha[1], pArp->ar_tha[2],
00257 pArp->ar_tha[3], pArp->ar_tha[4], pArp->ar_tha[5]);
00258 printf(" Target protocol addr = %d.%d.%d.%d\n\r",
00259 pArp->ar_tpa[0], pArp->ar_tpa[1], pArp->ar_tpa[2], pArp->ar_tpa[3]);
00260 }
00261
00262 static void GDisplayIpHeader(PIpHeader pIpHeader, uint32_t size)
00263 {
00264 printf("======= IP %4u bytes, HEADER ==========\n\r", (unsigned int) size);
00265 printf(" IP Version = v.%d\n\r", (pIpHeader->ip_hl_v & 0xF0) >> 4);
00266 printf(" Header Length = %d\n\r", pIpHeader->ip_hl_v & 0x0F);
00267 printf(" Type of service = 0x%x\n\r", pIpHeader->ip_tos);
00268 printf(" Total IP Length = 0x%X\n\r",
00269 (((pIpHeader->ip_len) >> 8) & 0xff) + (((pIpHeader->ip_len) << 8) & 0xff00) );
00270 printf(" ID = 0x%X\n\r",
00271 (((pIpHeader->ip_id) >> 8) & 0xff) + (((pIpHeader->ip_id) << 8) & 0xff00) );
00272 printf(" Header Checksum = 0x%X\n\r",
00273 (((pIpHeader->ip_sum) >> 8) & 0xff) + (((pIpHeader->ip_sum) << 8) & 0xff00) );
00274 printf(" Protocol = ");
00275
00276 switch (pIpHeader->ip_p) {
00277 case IP_PROT_ICMP:
00278 printf("ICMP\n\r");
00279 break;
00280
00281 case IP_PROT_IP:
00282 printf("IP\n\r");
00283 break;
00284
00285 case IP_PROT_TCP:
00286 printf("TCP\n\r");
00287 break;
00288
00289 case IP_PROT_UDP:
00290 printf("UDP\n\r");
00291 break;
00292
00293 default:
00294 printf("%d (0x%X)\n\r", pIpHeader->ip_p, pIpHeader->ip_p);
00295 break;
00296 }
00297
00298 printf(" IP Src Address = %d:%d:%d:%d\n\r",
00299 pIpHeader->ip_src[0],
00300 pIpHeader->ip_src[1],
00301 pIpHeader->ip_src[2],
00302 pIpHeader->ip_src[3]);
00303
00304 printf(" IP Dest Address = %d:%d:%d:%d\n\r",
00305 pIpHeader->ip_dst[0],
00306 pIpHeader->ip_dst[1],
00307 pIpHeader->ip_dst[2],
00308 pIpHeader->ip_dst[3]);
00309 printf("----------------------------------------\n\r");
00310 }
00311
00312
00313
00314
00315 static void garp_init_ip_addr(uint8_t *pData)
00316 {
00317 uint32_t i;
00318 PArpHeader pArp = (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00319
00320 if (SWAP16(pArp->ar_op) == ARP_REQUEST) {
00321
00322 if (gbIsIpAddrInit == 0) {
00323
00324 printf("first arp request, Check @ip. src=%d.%d.%d.%d dst=%d.%d.%d.%d ",
00325 pArp->ar_spa[0], pArp->ar_spa[1], pArp->ar_spa[2], pArp->ar_spa[3],
00326 pArp->ar_tpa[0], pArp->ar_tpa[1], pArp->ar_tpa[2], pArp->ar_tpa[3]);
00327
00328 if ((pArp->ar_tpa[0] == pArp->ar_spa[0]) &&
00329 (pArp->ar_tpa[1] == pArp->ar_spa[1]) &&
00330 (pArp->ar_tpa[2] == pArp->ar_spa[2]) &&
00331 (pArp->ar_tpa[3] >= 250) &&
00332 (pArp->ar_tpa[3] <= 254)) {
00333 for (i = 0; i < 4; i++)
00334 GIpAddress[i] = pArp->ar_tpa[i];
00335
00336 printf("=> OK\n\r");
00337 gbIsIpAddrInit = 1;
00338
00339 } else
00340 printf("=> KO!\n\r");
00341 }
00342 }
00343 }
00344
00345
00346
00347 static void garp_request(uint8_t *pData)
00348 {
00349 uint32_t i;
00350 uint8_t gmac_rc = GMACD_OK;
00351
00352 PEthHeader pEth = (PEthHeader)(pData + GMAC_RCV_OFFSET);
00353 PArpHeader pArp = (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00354
00355 pEth->et_protlen = SWAP16(ETH_PROT_ARP);
00356
00357 pArp->ar_hrd = SWAP16(0x0001);
00358 pArp->ar_pro = SWAP16(ETH_PROT_IP);
00359 pArp->ar_hln = 6;
00360 pArp->ar_pln = 4;
00361 pArp->ar_op = SWAP16(ARP_REQUEST);
00362
00363
00364 for (i = 0; i < 6; i++) {
00365
00366 pEth->et_dest[i] = 0xff;
00367 pEth->et_src[i] = GMacAddress[i];
00368 pArp->ar_tha[i] = 0x00;
00369 pArp->ar_sha[i] = GMacAddress[i];
00370 }
00371
00372
00373 for (i = 0; i < 4; i++) {
00374 pArp->ar_tpa[i] = GDesIpAddress[i];
00375 pArp->ar_spa[i] = GIpAddress[i];
00376 }
00377
00378 gmac_rc = GMACD_Send(&gGmacd,
00379 (pData + GMAC_RCV_OFFSET),
00380 42,
00381 NULL, GMAC_QUE_0);
00382
00383 if (gmac_rc != GMACD_OK)
00384 printf("-E- ARP_REQUEST Send - 0x%x\n\r", gmac_rc);
00385 }
00386
00387
00388
00389
00390 static void garp_process_packet(uint8_t *pData, uint32_t size)
00391 {
00392 uint32_t i, j;
00393 uint8_t gmac_rc = GMACD_OK;
00394
00395 PEthHeader pEth = (PEthHeader)pData;
00396 PArpHeader pArp = (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00397
00398 if (SWAP16(pArp->ar_op) == ARP_REQUEST) {
00399
00400
00401 pArp->ar_op = SWAP16(ARP_REPLY);
00402
00403
00404 for (i = 0; i < 6; i++) {
00405
00406 pEth->et_dest[i] = pEth->et_src[i];
00407 pEth->et_src[i] = GMacAddress[i];
00408 pArp->ar_tha[i] = pArp->ar_sha[i];
00409 pArp->ar_sha[i] = GMacAddress[i];
00410 }
00411
00412
00413 for (i = 0; i < 4; i++) {
00414 pArp->ar_tpa[i] = pArp->ar_spa[i];
00415 pArp->ar_spa[i] = GIpAddress[i];
00416 }
00417
00418 gmac_rc = GMACD_Send(&gGmacd,
00419 (pData + GMAC_RCV_OFFSET),
00420 size,
00421 NULL, GMAC_QUE_0);
00422
00423 if (gmac_rc != GMACD_OK)
00424 printf("-E- ARP Send - 0x%x\n\r", gmac_rc);
00425 }
00426
00427 if (SWAP16(pArp->ar_op) == ARP_REPLY) {
00428
00429 for (i = 0, j = 0; i < 4; i++) {
00430 if (pArp->ar_tpa[i] != GIpAddress[i]) {j++; break;}
00431
00432 if (pArp->ar_spa[i] != GDesIpAddress[i]) {j++; break;}
00433 }
00434
00435 if (!j)
00436 gtotal_reply++;
00437 }
00438 }
00439
00440
00441
00442
00443 static void gip_process_packet(uint8_t *pData)
00444 {
00445 uint32_t i;
00446 uint32_t icmp_len;
00447 uint32_t gmac_rc = GMACD_OK;
00448
00449 PEthHeader pEth = (PEthHeader)pData;
00450 PIpHeader pIpHeader = (PIpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00451
00452 PIcmpEchoHeader pIcmpEcho = (PIcmpEchoHeader)((char *)pIpHeader + 20);
00453
00454 switch (pIpHeader->ip_p) {
00455
00456 case IP_PROT_ICMP:
00457
00458
00459 if (pIcmpEcho->type == ICMP_ECHO_REQUEST) {
00460 pIcmpEcho->type = ICMP_ECHO_REPLY;
00461 pIcmpEcho->code = 0;
00462 pIcmpEcho->cksum = 0;
00463
00464
00465 icmp_len = (SWAP16(pIpHeader->ip_len) - 20);
00466
00467 if (icmp_len % 2) {
00468 *((uint8_t *)pIcmpEcho + icmp_len) = 0;
00469 icmp_len ++;
00470 }
00471
00472 icmp_len = icmp_len / sizeof(unsigned short);
00473
00474 pIcmpEcho->cksum =
00475 SWAP16(IcmpChksum((unsigned short *) pIcmpEcho, icmp_len));
00476
00477
00478 for (i = 0; i < 4; i++) {
00479 GIpAddress[i] = pIpHeader->ip_dst[i];
00480 pIpHeader->ip_dst[i] = pIpHeader->ip_src[i];
00481 pIpHeader->ip_src[i] = GIpAddress[i];
00482 }
00483
00484
00485 for (i = 0; i < 6; i++) {
00486
00487
00488
00489 pEth->et_dest[i] = pEth->et_src[i];
00490 pEth->et_src[i] = GMacAddress[i];
00491 }
00492
00493
00494
00495 gmac_rc = GMACD_Send(&gGmacd,
00496 (pData + GMAC_RCV_OFFSET),
00497 SWAP16(pIpHeader->ip_len) + 14 + GMAC_RCV_OFFSET,
00498 NULL, GMAC_QUE_0);
00499
00500 if (gmac_rc != GMACD_OK)
00501 printf("-E- ICMP Send - 0x%x\n\r", (unsigned int) gmac_rc);
00502 }
00503
00504 break;
00505
00506 default:
00507 break;
00508 }
00509 }
00510
00511
00512
00513
00514
00515 static void geth_process_packet(uint8_t *pData, uint32_t size)
00516 {
00517 uint16_t pkt_format;
00518
00519 PEthHeader pEth = (PEthHeader)(pData + GMAC_RCV_OFFSET);
00520 PIpHeader pIpHeader = (PIpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00521 IpHeader ipHeader;
00522
00523 pkt_format = SWAP16(pEth->et_protlen);
00524
00525 switch (pkt_format) {
00526
00527 case ETH_PROT_ARP:
00528
00529
00530 GDisplayEthernetHeader(pEth, size);
00531 GDisplayArpHeader((PArpHeader)(pData + 14 + GMAC_RCV_OFFSET), size);
00532
00533
00534 garp_init_ip_addr(pData);
00535
00536
00537 if (gbIsIpAddrInit == 0) return;
00538
00539 garp_process_packet(pData, size);
00540
00541
00542 break;
00543
00544
00545 case ETH_PROT_IP:
00546
00547 if (gbIsIpAddrInit == 0) return;
00548
00549
00550 memcpy(&ipHeader, pIpHeader, sizeof(IpHeader));
00551
00552
00553 gip_process_packet(pData);
00554
00555
00556 GDisplayIpHeader(&ipHeader, size);
00557 break;
00558
00559 default:
00560 break;
00561 }
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 int main(void)
00575 {
00576 sGmacd *pGmacd = &gGmacd;
00577 GMacb *pGmacb = &gGmacb;
00578 uint32_t frmSize;
00579 uint32_t delay;
00580 sGmacInit Que0, Que;
00581 uint8_t OrigiGMacAddr[16];
00582 uint32_t i;
00583
00584
00585 WDT_Disable(WDT);
00586
00587
00588 SCB_EnableICache();
00589 SCB_EnableDCache();
00590
00591 printf("-- GMAC Example %s --\n\r", SOFTPACK_VERSION);
00592 printf("-- %s\n\r", BOARD_NAME);
00593 printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00594 COMPILER_NAME);
00595
00596
00597 TimeTick_Configure();
00598
00599
00600 PIO_Configure(twiPins, PIO_LISTSIZE(twiPins));
00601
00602 PMC_EnablePeripheral(BOARD_ID_TWI_EEPROM);
00603 TWI_ConfigureMaster(BOARD_BASE_TWI_EEPROM, TWCK, BOARD_MCK);
00604 TWID_Initialize(&twid, BOARD_BASE_TWI_EEPROM);
00605
00606 printf("-- EK`s IP %d.%d.%d.%d\n\r",
00607 GIpAddress[0], GIpAddress[1], GIpAddress[2], GIpAddress[3]);
00608 printf("-- PC`s IP %d.%d.%d.%d\n\r",
00609 GDesIpAddress[0], GDesIpAddress[1], GDesIpAddress[2], GDesIpAddress[3]);
00610
00611 TWID_Read(&twid, AT24MAC_SERIAL_NUM_ADD, 0x9A, 1, OrigiGMacAddr, PAGE_SIZE, 0);
00612
00613 if ((OrigiGMacAddr[0] == 0xFC) && (OrigiGMacAddr[1] == 0xC2)
00614 && (OrigiGMacAddr[2] == 0x3D)) {
00615 for (i = 0; i < 6; i++)
00616 GMacAddress[i] = OrigiGMacAddr[i];
00617 }
00618
00619 GMAC_SetAddress(gGmacd.pHw, 0, GMacAddress);
00620 printf("-- MAC %x:%x:%x:%x:%x:%x\n\r",
00621 GMacAddress[0], GMacAddress[1], GMacAddress[2],
00622 GMacAddress[3], GMacAddress[4], GMacAddress[5]);
00623
00624 printf("Connect the board to a host PC via an ethernet cable\n\r");
00625
00626
00627 memset(&Que0, 0, sizeof(Que0));
00628 Que0.bIsGem = 1;
00629 Que0.bDmaBurstLength = 4;
00630 Que0.pRxBuffer = pRxBuffer;
00631 Que0.pRxD = gRxDs;
00632 Que0.wRxBufferSize = BUFFER_SIZE;
00633 Que0.wRxSize = RX_BUFFERS;
00634 Que0.pTxBuffer = pTxBuffer;
00635 Que0.pTxD = gTxDs;
00636 Que0.wTxBufferSize = BUFFER_SIZE;
00637 Que0.wTxSize = TX_BUFFERS;
00638 Que0.pTxCb = gTxCbs;
00639
00640
00641
00642 memset(&Que, 0, sizeof(Que));
00643 Que.bIsGem = 1;
00644 Que.bDmaBurstLength = 4;
00645 Que.pRxBuffer = pRxDummyBuffer;
00646 Que.pRxD = gDummyRxDs;
00647 Que.wRxBufferSize = DUMMY_BUFF_SIZE;
00648 Que.wRxSize = DUMMY_SIZE;
00649 Que.pTxBuffer = pTxDummyBuffer;
00650 Que.pTxD = gDummyTxDs;
00651 Que.wTxBufferSize = DUMMY_BUFF_SIZE;
00652 Que.wTxSize = DUMMY_SIZE;
00653 Que.pTxCb = gDummyTxCbs;
00654
00655 GMACD_Init(pGmacd, GMAC, ID_GMAC, GMAC_CAF_ENABLE, GMAC_NBC_DISABLE);
00656 GMACD_InitTransfer(pGmacd, &Que, GMAC_QUE_2);
00657 GMACD_InitTransfer(pGmacd, &Que, GMAC_QUE_1);
00658 GMACD_InitTransfer(pGmacd, &Que0, GMAC_QUE_0);
00659
00660
00661
00662 NVIC_ClearPendingIRQ(GMAC_IRQn);
00663 NVIC_EnableIRQ(GMAC_IRQn);
00664
00665 GMACB_Init(pGmacb, pGmacd, BOARD_GMAC_PHY_ADDR);
00666 GMACB_ResetPhy(pGmacb);
00667
00668
00669 if (!GMACB_InitPhy(pGmacb, BOARD_MCK, &gmacResetPin, 1, gmacPins,
00670 PIO_LISTSIZE(gmacPins))) {
00671 printf("PHY Initialize ERROR!\n\r");
00672 return 0;
00673 }
00674
00675 printf("GMACB_AutoNegotiate\n\r");
00676
00677 if (!GMACB_AutoNegotiate(pGmacb)) {
00678 printf("Auto Negotiate ERROR!\n\r");
00679 return 0;
00680 }
00681
00682 delay = 0;
00683 gtotal_request = 0;
00684 gtotal_reply = 0;
00685
00686 while (1) {
00687 if (gtotal_request >= GMAX_ARP_REQUEST)break;
00688
00689 if ((delay++) >= (BOARD_MCK / 1000000)) {
00690 delay = 0;
00691 gtotal_request++;
00692 printf("arp... \n\r");
00693 garp_request(GEthBuffer);
00694 }
00695
00696
00697 if (GMACD_OK != GMACD_Poll(pGmacd, GEthBuffer, sizeof(GEthBuffer),
00698 &frmSize, GMAC_QUE_0))
00699 continue;
00700
00701 if (frmSize > 0) {
00702
00703 printf("Process_packet ...\n\r");
00704 geth_process_packet(GEthBuffer, frmSize);
00705 }
00706 }
00707
00708
00709 NVIC_DisableIRQ(GMAC_IRQn);
00710
00711 printf("EK sends out %d ARP request and gets %d reply\n\r",
00712 gtotal_request, gtotal_reply);
00713
00714 while (1);
00715 }