00001
00035 #include "ksz8851snl.h"
00036 #include "ethspi.h"
00037 #include "em_gpio.h"
00038 #include <stdio.h>
00039
00041 static uint16_t frameId = 0;
00042 static uint8_t macAddress[6];
00044 #if KSZ8851SNL_DEBUG
00045 static void KSZ8851SNL_SetDigitalLoopbackMode(void);
00046 static void KSZ8851SNL_DumpRegisters(void);
00047 #endif
00048 static void KSZ8851SNL_ExceptionHandler(enum exceptionType_e exc_type, char* param);
00049 static void KSZ8851SNL_ReleaseIncosistentFrame(void);
00050 static uint8_t KSZ8851SNL_DwordAllignDiff(uint8_t val);
00053
00056 void KSZ8851SNL_EnableInterupts(void)
00057 {
00058 uint16_t data;
00059
00060 data = INT_MASK_EXAMPLE;
00061 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00062 }
00063
00064
00065
00075 uint16_t KSZ8851SNL_CheckIrqStat(void)
00076 {
00077 uint16_t data, ISR_stat, found_INT;
00078 found_INT = 0;
00079 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &ISR_stat);
00080
00081
00082 data = NO_INT;
00083 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00084
00085
00086 if (ISR_stat & INT_RX_DONE)
00087 {
00088
00089 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00090 data = INT_RX_DONE;
00091 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00092 found_INT |= INT_RX_DONE;
00093 }
00094
00095 if (ISR_stat & INT_LINK_CHANGE)
00096 {
00097
00098 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00099 data = INT_LINK_CHANGE;
00100 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00101 found_INT |= INT_LINK_CHANGE;
00102 }
00103
00104 if (ISR_stat & INT_RX_OVERRUN)
00105 {
00106
00107 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00108 data = INT_RX_OVERRUN;
00109 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00110 found_INT |= INT_RX_OVERRUN;
00111 }
00112
00113 if (ISR_stat & INT_TX_STOPPED)
00114 {
00115
00116 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00117 data = INT_TX_STOPPED;
00118 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00119 found_INT |= INT_TX_STOPPED;
00120 }
00121
00122 if (ISR_stat & INT_RX_STOPPED)
00123 {
00124
00125 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00126 data = INT_RX_STOPPED;
00127 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00128 found_INT |= INT_RX_STOPPED;
00129 }
00130
00131 if (ISR_stat & INT_RX_WOL_FRAME)
00132 {
00133
00134 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00135 data = INT_RX_WOL_FRAME;
00136 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00137 found_INT |= INT_RX_WOL_FRAME;
00138 }
00139
00140 if (ISR_stat & INT_MAGIC)
00141 {
00142
00143 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00144 data = INT_MAGIC;
00145 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00146 found_INT |= INT_MAGIC;
00147 }
00148
00149 if (ISR_stat & INT_LINKUP)
00150 {
00151
00152 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00153 data = INT_LINKUP;
00154 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00155 found_INT |= INT_LINKUP;
00156 }
00157
00158 if (ISR_stat & INT_ENERGY)
00159 {
00160
00161 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00162 data = INT_ENERGY;
00163 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00164 found_INT |= INT_ENERGY;
00165 }
00166
00167 if (ISR_stat & INT_SPI_ERROR)
00168 {
00169
00170 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00171 data = INT_SPI_ERROR;
00172 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00173 found_INT |= INT_SPI_ERROR;
00174 }
00175
00176 if (ISR_stat & INT_TX_SPACE)
00177 {
00178
00179 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00180 data = INT_TX_SPACE;
00181 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00182 found_INT |= INT_TX_SPACE;
00183 }
00184 return found_INT;
00185 }
00186
00187
00188
00195 uint16_t KSZ8851SNL_CurrFrameSize(void)
00196 {
00197 uint16_t data;
00198
00199
00200 ETHSPI_ReadRegister(RX_FRH_BC_REG, 2, &data);
00201
00202 data &= RX_BYTE_CNT_MASK;
00203
00204 return data;
00205 }
00206
00207
00208
00217 static uint8_t KSZ8851SNL_DwordAllignDiff(uint8_t val)
00218 {
00219 if (val % 4 == 0) return 0;
00220 else return val % 4;
00221 }
00222
00223
00224
00234 static void KSZ8851SNL_ExceptionHandler(enum exceptionType_e exc_type, char* param)
00235 {
00236 uint16_t data;
00237 (void)param;
00238
00239 data = NO_INT;
00240 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00241 switch (exc_type)
00242 {
00243 case ERROR:
00244 DEBUG_PRINT("ERROR:%s\n", param);
00245 while (1) ;
00246 case INFO:
00247 DEBUG_PRINT("INFO:%s\n", param);
00248 break;
00249 }
00250
00251 data = INT_MASK_EXAMPLE;
00252 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00253 }
00254
00255
00256
00264 void KSZ8851SNL_ReadMIBCounters(char* param)
00265 {
00266 EFM_ASSERT(param != NULL);
00267 uint16_t data, dataLow, dataHigh;
00268 DEBUG_PRINT("#################################################################\n");
00269 DEBUG_PRINT("Dumping MIB Counters values @%s\n", param);
00270 int i;
00271 for (i = 0; i < 0x20; i++)
00272 {
00273 data = MIB_MASK | i;
00274 ETHSPI_WriteRegister(IND_ACC_CTRL_REG, 2, &data);
00275 ETHSPI_ReadRegister(IND_ACC_DATA_LOW_REG, 2, &dataLow);
00276 ETHSPI_ReadRegister(IND_ACC_DATA_HIGH_REG, 2, &dataHigh);
00277 DEBUG_PRINT("MIB_REG[%2X] contains %X - %X\n", i, dataHigh, dataLow);
00278 }
00279 DEBUG_PRINT("#################################################################\n");
00280 }
00281
00282
00283 #if KSZ8851SNL_DEBUG
00284
00288 static void KSZ8851SNL_DumpRegisters(void)
00289 {
00290 uint16_t data;
00291
00292 DEBUG_PRINT("#################################################################\n");
00293 DEBUG_PRINT("Dumping Register values\n");
00294
00295 DEBUG_PRINT("#################################################################\n");
00296 DEBUG_PRINT("Dumping ALL Register values\n");
00297
00298 int i;
00299 for (i = 0; = 0x00; i < 0xFF; i += 0x02)
00300 {
00301 ETHSPI_ReadRegister(i, 2, &data);
00302 DEBUG_PRINT("REG[0x%X] contains 0x%X\n", i, data);
00303 }
00304 DEBUG_PRINT("#################################################################\n");
00305 DEBUG_PRINT("Dumping used registers values\n");
00306
00307 ETHSPI_ReadRegister(LOW_QMU_MAC_REG, 2, &data);
00308 DEBUG_PRINT("REG[%2X] contains %2X\n", LOW_QMU_MAC_REG, data);
00309 ETHSPI_ReadRegister(MID_QMU_MAC_REG, 2, &data);
00310 DEBUG_PRINT("REG[%2X] contains %2X\n", MID_QMU_MAC_REG, data);
00311 ETHSPI_ReadRegister(HIGH_QMU_MAC_REG, 2, &data);
00312 DEBUG_PRINT("REG[%2X] contains %2X\n", HIGH_QMU_MAC_REG, data);
00313 ETHSPI_ReadRegister(OBC_REG, 2, &data);
00314 DEBUG_PRINT("REG[%2X] contains %2X\n", OBC_REG, data);
00315 ETHSPI_ReadRegister(GLOBAL_RESET_REG, 2, &data);
00316 DEBUG_PRINT("REG[%2X] contains %2X\n", GLOBAL_RESET_REG, data);
00317 ETHSPI_ReadRegister(TX_FLOW_CTRL_REG, 2, &data);
00318 DEBUG_PRINT("REG[%2X] contains %2X\n", TX_FLOW_CTRL_REG, data);
00319 ETHSPI_ReadRegister(RX_FLOW_CTRL1_REG, 2, &data);
00320 DEBUG_PRINT("REG[%2X] contains %2X\n", RX_FLOW_CTRL1_REG, data);
00321 ETHSPI_ReadRegister(RX_FLOW_CTRL2_REG, 2, &data);
00322 DEBUG_PRINT("REG[%2X] contains %2X\n", RX_FLOW_CTRL2_REG, data);
00323 ETHSPI_ReadRegister(TX_MEM_INFO_REG, 2, &data);
00324 DEBUG_PRINT("REG[%2X] contains %2X\n", TX_MEM_INFO_REG, data);
00325 ETHSPI_ReadRegister(RX_FRH_STAT_REG, 2, &data);
00326 DEBUG_PRINT("REG[%2X] contains %2X\n", RX_FRH_STAT_REG, data);
00327 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00328 DEBUG_PRINT("REG[%2X] contains %2X\n", TXQ_CMD_REG, data);
00329 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00330 DEBUG_PRINT("REG[%2X] contains %2X\n", RXQ_CMD_REG, data);
00331 ETHSPI_ReadRegister(TX_FD_PTR_REG, 2, &data);
00332 DEBUG_PRINT("REG[%2X] contains %2X\n", TX_FD_PTR_REG, data);
00333 ETHSPI_ReadRegister(RX_FD_PTR_REG, 2, &data);
00334 DEBUG_PRINT("REG[%2X] contains %2X\n", RX_FD_PTR_REG, data);
00335 ETHSPI_ReadRegister(INT_ENABLE_REG, 2, &data);
00336 DEBUG_PRINT("REG[%2X] contains %2X\n", INT_ENABLE_REG, data);
00337 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00338 DEBUG_PRINT("REG[%2X] contains %2X\n", INT_STATUS_REG, data);
00339 ETHSPI_ReadRegister(RX_FRAME_THRES_REG, 2, &data);
00340 DEBUG_PRINT("REG[%2X] contains %2X\n", RX_FRAME_THRES_REG, data);
00341 ETHSPI_ReadRegister(TX_NEXT_FRS_REG, 2, &data);
00342 DEBUG_PRINT("REG[%2X] contains %2X\n", TX_NEXT_FRS_REG, data);
00343 ETHSPI_ReadRegister(CIDER_REG, 2, &data);
00344 DEBUG_PRINT("REG[%2X] contains %2X\n", CIDER_REG, data);
00345 ETHSPI_ReadRegister(PHY_RST_REG, 2, &data);
00346 DEBUG_PRINT("REG[%2X] contains %2X\n", PHY_RST_REG, data);
00347 ETHSPI_ReadRegister(PHY1_CTRL_REG, 2, &data);
00348 DEBUG_PRINT("REG[%2X] contains %2X\n", PHY1_CTRL_REG, data);
00349 ETHSPI_ReadRegister(PORT1_CTRL_REG, 2, &data);
00350 DEBUG_PRINT("REG[%2X] contains %2X\n", PORT1_CTRL_REG, data);
00351 DEBUG_PRINT("#################################################################\n");
00352 }
00353 #endif
00354
00355
00356
00359 void KSZ8851SNL_Init(void)
00360 {
00361 uint16_t data;
00362
00363
00364 ETHSPI_Init();
00365
00366
00367 data = GLOBAL_SOFT_RESET;
00368 ETHSPI_WriteRegister(GLOBAL_RESET_REG, 2, &data);
00369 ETHSPI_ReadRegister(GLOBAL_RESET_REG, 2, &data);
00370 data &= ~GLOBAL_SOFT_RESET;
00371 ETHSPI_WriteRegister(GLOBAL_RESET_REG, 2, &data);
00372
00373
00374 data = QMU_MODULE_SOFT_RESET;
00375 ETHSPI_WriteRegister(GLOBAL_RESET_REG, 2, &data);
00376 ETHSPI_ReadRegister(GLOBAL_RESET_REG, 2, &data);
00377 data &= ~QMU_MODULE_SOFT_RESET;
00378 ETHSPI_WriteRegister(GLOBAL_RESET_REG, 2, &data);
00379
00380 #ifdef DIGITAL_PHY_LOOPBACK
00381 KSZ8851SNL_SetDigitalLoopbackMode();
00382 #endif
00383
00384
00385 ETHSPI_ReadRegister(CIDER_REG, 2, &data);
00386
00387
00388
00389
00390 if ((data & CHIP_ID_MASK) != KSZ8851SNL_CHIP_ID)
00391 {
00392 KSZ8851SNL_ExceptionHandler(ERROR, "ETH: Incorrect Device ID");
00393 }
00394
00395
00396 KSZ8851SNL_GetMacAddress(macAddress);
00397
00398
00399
00400
00401 int i;
00402 for (i = 0; (i < 6); i += 2)
00403 {
00404 data = (macAddress[i] << MSB_POS) | macAddress[i + 1];
00405 ETHSPI_WriteRegister(HIGH_QMU_MAC_REG - i, 2, &data);
00406 }
00407
00408
00409 data = FD_PTR_AUTO_INC;
00410 ETHSPI_WriteRegister(TX_FD_PTR_REG, 2, &data);
00411
00412
00413 data |= TX_FLOW_CTRL_FLUSH_QUEUE;
00414 ETHSPI_WriteRegister(TX_FLOW_CTRL_REG, 2, &data);
00415
00416
00417
00418
00419
00420
00421
00422 data = TX_FLOW_CTRL_EXAMPLE;
00423 ETHSPI_WriteRegister(TX_FLOW_CTRL_REG, 2, &data);
00424
00425
00426 data = FD_PTR_AUTO_INC;
00427 ETHSPI_WriteRegister(RX_FD_PTR_REG, 2, &data);
00428
00429
00430 data = ONE_FRAME_THRES;
00431 ETHSPI_WriteRegister(RX_FRAME_THRES_REG, 2, &data);
00432
00433
00434
00435
00436
00437
00438
00439 data = RX_FLOW_CTRL1_EXAMPLE;
00440 ETHSPI_WriteRegister(RX_FLOW_CTRL1_REG, 2, &data);
00441
00442
00443
00444
00445
00446
00447 data = RX_FLOW_CTRL2_EXAMPLE;
00448 ETHSPI_WriteRegister(RX_FLOW_CTRL2_REG, 2, &data);
00449
00450
00451
00452
00453
00454
00455 data = RXQ_CMD_EXAMPLE;
00456 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00457
00458
00459 ETHSPI_ReadRegister(PORT1_CTRL_REG, 2, &data);
00460 data |= PORT1_AUTO_NEG_RESTART;
00461 ETHSPI_WriteRegister(PORT1_CTRL_REG, 2, &data);
00462
00463
00464 ETHSPI_ReadRegister(PORT1_CTRL_REG, 2, &data);
00465 if ((data & PORT1_AUTO_NEG_RESTART) != PORT1_AUTO_NEG_RESTART)
00466 {
00467 data &= ~PORT1_FORCE_FULL_DUPLEX;
00468 ETHSPI_WriteRegister(PORT1_CTRL_REG, 2, &data);
00469 }
00470
00471 data = WATERMARK_6KB;
00472 ETHSPI_WriteRegister(FLOW_CTRL_LOW_WATERMARK, 2, &data);
00473
00474
00475 data = WATERMARK_4KB;
00476 ETHSPI_WriteRegister(FLOW_CTRL_HIGH_WATERMARK, 2, &data);
00477
00478
00479 data = CLEAR_INT;
00480 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 data = INT_MASK_EXAMPLE;
00491 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00492
00493
00494 ETHSPI_ReadRegister(TX_FLOW_CTRL_REG, 2, &data);
00495 data |= TX_FLOW_CTRL_ENABLE;
00496 ETHSPI_WriteRegister(TX_FLOW_CTRL_REG, 2, &data);
00497
00498
00499 ETHSPI_ReadRegister(RX_FLOW_CTRL1_REG, 2, &data);
00500 data |= RX_FLOW_CTRL_ENABLE;
00501 ETHSPI_WriteRegister(RX_FLOW_CTRL1_REG, 2, &data);
00502
00503 KSZ8851SNL_ExceptionHandler(INFO, "ETH: Initialization complete");
00504 }
00505
00506
00507
00515 void KSZ8851SNL_Send(uint16_t pTXLength, uint8_t *pTXData)
00516 {
00517 EFM_ASSERT(pTXData != NULL);
00518
00519 uint16_t txmir;
00520 uint16_t data, reqSize;
00521 uint8_t outbuf[4];
00522
00523
00524 ETHSPI_ReadRegister(TX_MEM_INFO_REG, 2, &data);
00525 txmir = data & TX_MEM_AVAIL_MASK;
00526
00527 reqSize = pTXLength + EXTRA_SIZE;
00528 if (txmir < reqSize)
00529 {
00530 KSZ8851SNL_ExceptionHandler(INFO, "I will wait until mem is available\n");
00531
00532 ETHSPI_WriteRegister(TX_NEXT_FRS_REG, 2, &reqSize);
00533 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00534 data |= TXQ_MEM_AVAILABLE_INT;
00535 ETHSPI_WriteRegister(TXQ_CMD_REG, 2, &data);
00536
00537
00538 while (1)
00539 {
00540 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00541 if ((data & INT_TX_SPACE) == INT_TX_SPACE)
00542 {
00543 break;
00544 }
00545 }
00546 KSZ8851SNL_ExceptionHandler(INFO, "Done\n");
00547
00548
00549 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00550 data &= ~INT_TX_SPACE;
00551 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00552 }
00553
00554
00555 data = NO_INT;
00556 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00557
00558
00559 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00560 data |= RXQ_START;
00561 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00562
00563
00564 outbuf[0] = (frameId++ & frameId_MASK) | TX_INT_on_COMPLETION;
00565 outbuf[1] = 0;
00566 outbuf[2] = pTXLength & LSB_MASK;
00567 outbuf[3] = pTXLength >> MSB_POS;
00568
00569
00570 ETHSPI_StartWriteFIFO();
00571
00572 ETHSPI_WriteFifoContinue(4, outbuf);
00573
00574
00575 ETHSPI_WriteFifoContinue(pTXLength, pTXData);
00576
00577
00578 ETHSPI_WriteFifoContinue(KSZ8851SNL_DwordAllignDiff(pTXLength), pTXData);
00579
00580
00581 ETHSPI_StopFIFO();
00582
00583
00584 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00585 data &= ~RXQ_START;
00586 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00587
00588
00589 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00590 data |= TXQ_ENQUEUE;
00591 ETHSPI_WriteRegister(TXQ_CMD_REG, 2, &data);
00592
00593
00594 while (1)
00595 {
00596 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00597 if (!(data & TXQ_ENQUEUE))
00598 break;
00599 }
00600
00601
00602 data = INT_MASK_EXAMPLE;
00603 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00604 }
00605
00606
00607
00614 void KSZ8851SNL_InitiateLongTransmit(uint16_t pTXLength)
00615 {
00616 uint16_t txmir;
00617 uint16_t data, reqSize;
00618 uint8_t outbuf[4];
00619
00620
00621 ETHSPI_ReadRegister(TX_MEM_INFO_REG, 2, &data);
00622 txmir = data & TX_MEM_AVAIL_MASK;
00623
00624 reqSize = pTXLength + EXTRA_SIZE;
00625 if (txmir < reqSize)
00626 {
00627 KSZ8851SNL_ExceptionHandler(INFO, "I will wait until mem is available\n");
00628
00629 ETHSPI_WriteRegister(TX_NEXT_FRS_REG, 2, &reqSize);
00630 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00631 data |= TXQ_MEM_AVAILABLE_INT;
00632 ETHSPI_WriteRegister(TXQ_CMD_REG, 2, &data);
00633
00634
00635 while (1)
00636 {
00637 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00638 if ((data & INT_TX_SPACE) == INT_TX_SPACE)
00639 {
00640 break;
00641 }
00642 }
00643 KSZ8851SNL_ExceptionHandler(INFO, "Done\n");
00644
00645
00646 ETHSPI_ReadRegister(INT_STATUS_REG, 2, &data);
00647 data &= ~INT_TX_SPACE;
00648 ETHSPI_WriteRegister(INT_STATUS_REG, 2, &data);
00649 }
00650
00651
00652 data = NO_INT;
00653 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00654
00655
00656 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00657 data |= RXQ_START;
00658 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00659
00660
00661 outbuf[0] = (frameId++ & frameId_MASK) | TX_INT_on_COMPLETION;
00662 outbuf[1] = 0;
00663 outbuf[2] = pTXLength & LSB_MASK;
00664 outbuf[3] = pTXLength >> MSB_POS;
00665
00666
00667 ETHSPI_StartWriteFIFO();
00668
00669 ETHSPI_WriteFifoContinue(4, outbuf);
00670 }
00671
00672
00673
00681 void KSZ8851SNL_LongTransmit(uint16_t pTXLength, uint8_t *pTXData)
00682 {
00683 EFM_ASSERT(pTXData != NULL);
00684
00685 ETHSPI_WriteFifoContinue(pTXLength, pTXData);
00686 }
00687
00688
00689
00698 void KSZ8851SNL_TerminateLongTransmit(uint16_t pTXLength, uint8_t *pTXData)
00699 {
00700 EFM_ASSERT(pTXData != NULL);
00701
00702 uint16_t data;
00703
00704
00705 ETHSPI_WriteFifoContinue(KSZ8851SNL_DwordAllignDiff(pTXLength), pTXData);
00706
00707
00708 ETHSPI_StopFIFO();
00709
00710
00711 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00712 data &= ~RXQ_START;
00713 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00714
00715
00716 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00717 data |= TXQ_ENQUEUE;
00718 ETHSPI_WriteRegister(TXQ_CMD_REG, 2, &data);
00719
00720
00721 while (1)
00722 {
00723 ETHSPI_ReadRegister(TXQ_CMD_REG, 2, &data);
00724 if (!(data & TXQ_ENQUEUE))
00725 break;
00726 }
00727
00728
00729 data = INT_MASK_EXAMPLE;
00730 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00731 }
00732
00733
00734
00738 static void KSZ8851SNL_ReleaseIncosistentFrame(void)
00739 {
00740 uint16_t data;
00741
00742 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00743 data |= RXQ_RELEASE_CUR_FR;
00744 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00745 KSZ8851SNL_ExceptionHandler(INFO, "The frame was inconsistent\n");
00746 }
00747
00748
00749 #if KSZ8851SNL_DEBUG
00750
00754 static void KSZ8851SNL_SetDigitalLoopbackMode(void)
00755 {
00756 uint16_t data;
00757
00758 data = PHY_RESET;
00759 ETHSPI_WriteRegister(PHY_RST_REG, 2, &data);
00760
00761
00762
00763
00764 data = DIGITAL_LOOPBACK | FORCE_FULL_DUPLEX | FORCE_100;
00765 data &= ~AUTO_NEG;
00766 ETHSPI_WriteRegister(PHY1_CTRL_REG, 2, &data);
00767
00768 KSZ8851SNL_ExceptionHandler(INFO, "Loopback mode initiated");
00769 }
00770 #endif
00771
00772
00773
00784 uint16_t KSZ8851SNL_Receive(uint8_t *pRXData, uint16_t *pRXLength)
00785 {
00786 uint16_t data;
00787 uint8_t *pDummy = pRXData;
00788 uint16_t rxFrameCount, rxftr;
00789 uint16_t rxStatus;
00790
00791 EFM_ASSERT(pRXData != NULL);
00792 EFM_ASSERT(pRXLength != NULL);
00793
00794
00795 ETHSPI_ReadRegister(RX_FRAME_THRES_REG, 2, &rxftr);
00796
00797 rxFrameCount = rxftr >> MSB_POS;
00798
00799 while (rxFrameCount > 0)
00800 {
00801
00802 ETHSPI_ReadRegister(RX_FRH_STAT_REG, 2, &rxStatus);
00803
00804
00805 if (!(rxStatus >> RECEIVED_FRAME_VALID_POS == 0) || ((rxStatus & RECEIVE_VALID_FRAME_MASK) == RECEIVE_VALID_FRAME_MASK))
00806 {
00807
00808 KSZ8851SNL_ReleaseIncosistentFrame();
00809 }
00810 else
00811 {
00812
00813 ETHSPI_ReadRegister(RX_FRH_BC_REG, 2, pRXLength);
00814
00815 *pRXLength &= RX_BYTE_CNT_MASK;
00816
00817 if (*pRXLength <= 0)
00818 {
00819
00820 KSZ8851SNL_ReleaseIncosistentFrame();
00821
00822 rxFrameCount--;
00823
00824 continue;
00825 }
00826
00827
00828 data = FD_PTR_AUTO_INC;
00829 ETHSPI_WriteRegister(RX_FD_PTR_REG, 2, &data);
00830
00831
00832 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00833 data |= RXQ_START;
00834 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00835
00836
00837 ETHSPI_StartReadFIFO();
00838
00839
00840 ETHSPI_ReadFifoContinue(4, pDummy);
00841 ETHSPI_ReadFifoContinue(2, pDummy);
00842 ETHSPI_ReadFifoContinue(2, pDummy);
00843
00844
00845 ETHSPI_ReadFifoContinue(2, pDummy);
00846 *pRXLength -= 2;
00847
00848
00849 ETHSPI_ReadFifoContinue(*pRXLength, pRXData);
00850
00851
00852 ETHSPI_StopFIFO();
00853
00854
00855 ETHSPI_ReadRegister(RXQ_CMD_REG, 2, &data);
00856 data &= ~RXQ_START;
00857 ETHSPI_WriteRegister(RXQ_CMD_REG, 2, &data);
00858
00859
00860 data = INT_MASK_EXAMPLE;
00861 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00862
00863
00864 *pRXLength -= 4;
00865
00866
00867
00868
00869
00870 return *pRXLength;
00871 }
00872
00873
00874 rxFrameCount--;
00875
00876
00877 data = INT_MASK_EXAMPLE;
00878 ETHSPI_WriteRegister(INT_ENABLE_REG, 2, &data);
00879 }
00880 return 0;
00881 }
00882
00883
00884
00890 void KSZ8851SNL_GetMacAddress(uint8_t *macAddress)
00891 {
00892
00893
00894 EFM_ASSERT(macAddress != NULL);
00895
00896
00897 macAddress[0] = HIGH_QMU_MAC_H;
00898 macAddress[1] = HIGH_QMU_MAC_L;
00899 macAddress[2] = MID_QMU_MAC_H;
00900
00901 int i;
00902 for (i = 0; i < 3; i++)
00903 {
00904 macAddress[5 - i] = (DEVINFO->UNIQUEL & (BYTE_MASK << i * BYTE_SIZE)) >> i * BYTE_SIZE;
00905 }
00906 }
00907