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