void MACInit(void) { BYTE i; /* SBC45EC - use port B*/ #if defined(BRD_SBC44EC) TRISB = 0xe0; //RB0-4 are outputs //NIC_DISABLE_IOCHRDY can be defined if the MAC should NOT use the IOCHRDY signal on the RTL8019AS chip. // - For SBC44EC PIC port pin B5 will be available for user IO. Solder jumper SJ5 must be opened! #if !defined(NIC_DISABLE_IOCHRDY) NIC_IOCHRDY_TRIS = 1; //IOCHRDY is an input #endif /* SBC45EC - use port A*/ #elif defined(BRD_SBC45EC) TRISA = 0xd0; //RA0-3 and RA5 are outputs //NIC_DISABLE_IOCHRDY can be defined if the MAC should NOT use the IOCHRDY signal on the RTL8019AS chip. // - For SBC45EC PIC port pin A4 will be available for user IO. Solder jumper SJ5 must be opened! #if !defined(NIC_DISABLE_IOCHRDY) NIC_IOCHRDY_TRIS = 1; //IOCHRDY is an input #endif /* SBC65EC - use port E*/ #elif defined(BRD_SBC65EC) TRISE = 0x00; //RE0-7 are outputs //NIC_DISABLE_IOCHRDY can be defined if the MAC should NOT use the IOCHRDY signal on the RTL8019AS chip. // - For SBC65EC and SBC68EC this frees up PIC pin RG4. This pin is currently however not routed to an connectors //#if !defined(NIC_DISABLE_IOCHRDY) NIC_IOCHRDY = 1; NIC_IOCHRDY_TRIS = 1; //IOCHRDY is an input //#endif #endif //Reset all error counters #ifdef MAC_CNTR1_3 cntr0.Val = 0; cntr1.Val = 0; cntr2.Val = 0; #endif #if (DEBUG_MAC >= LOG_WARN) cntrSum = 0; #endif // On Init, all transmit buffers are free. for ( i = 0; i < MAX_DATA_BUFFERS; i++ ) { //Set to NIC SRAM page TxBuffers[i].Index = TXSTART + (i * (MAC_TX_BUFFER_SIZE/NIC_PAGE_SIZE)); TxBuffers[i].bFree = TRUE; } MACCurrTxbuf = 0; NICReset(); DelayMs(5); // Give RTL8019AS time to load EEPROM values - takes about 2ms NICPut(NIC_RESET, NICGet(NIC_RESET)); //Writing to NIC_RESET register caused NIC to reset // mimimum Delay of 1.6 ms DelayMs(5); // Give RTL8019AS time to load EEPROM values - takes about 2ms //Some documentation states that reset bit is unreliable - only check it for 100ms //if ( (NICGet(ISR) & 0x80) != 0 ) { #if defined(BRD_SBC44EC) || defined(BRD_SBC45EC) //Because the EEPROM read pin is floating on some boards, the registers initialized by the //EEPROM will all contain non defined values. Write them with correct values //MACInitEepromRegs(); // TEST TEST #endif // Select Page 0 AND issue STOP Command NICPut(CMDR, 0x21); DelayMs(5); // Initialize Data Configuration Register NICPut(DCR, DCRVAL); // Clear Remote Byte Count Registers NICPut(RBCR0, 0); NICPut(RBCR1, 0); // Initialize Receive Configuration Register NICPut(RCR, 0x04); // Place NIC in LOOPBACK mode 1 NICPut(TCR, 0x02); // Initialize Transmit buffer queue NICPut(TPSR, TxBuffers[MACCurrTxbuf].Index); // Initialize Receive Buffer Ring NICPut(PSTART, RXSTART); NICPut(PSTOP, RXSTOP); NICPut(BNRY, RXSTART); //Receive buffer GET pointer // Initialize Interrupt Mask Register // Clear all status bits NICPut(ISR, 0xff); // No interrupt enabled. NICPut(IMR, 0x00); // Select Page 1 NICPut(CMDR, 0x61); // Initialize Physical Address Registers NICPut(PAR0, MY_MAC_BYTE1); NICPut(PAR0+1, MY_MAC_BYTE2); NICPut(PAR0+2, MY_MAC_BYTE3); NICPut(PAR0+3, MY_MAC_BYTE4); NICPut(PAR0+4, MY_MAC_BYTE5); NICPut(PAR0+5, MY_MAC_BYTE6); // Initialize Multicast registers for ( i = 0; i < 8; i++ ) NICPut(MAR0+i, 0xff); // Initialize CURRent pointer - this is the RX Buffer PUT pointer NICPut(CURRP, RXSTART); // TCP layer uses this value to calculate window size. Without init the // first window size value sent would be wrong if no packet has been received before. MACCurrRxbuf = RXSTART; // Page 0, Abort Remote DMA and Activate the transmitter. NICPut(CMDR, 0x22); // Set Normal Mode NICPut(TCR, 0x00); } #if defined(BRD_SBC44EC) || defined(BRD_SBC45EC) //Because the EEPROM read pin is floating on some boards, the registers initialized by the //EEPROM will all contain non defined values. Write them with correct values //MACInitEepromRegs(); // TEST TEST #endif //Disable RTL8019AS interrupts. All INT lines go tri-state, and PIC pin is available to user. The //PIC port pin that becomes available is: // - For SBC44EC this has no affect - no PIC pins are connected to the interrupt pins // - For SBC45EC this has no affect - no PIC pins are connected to the interrupt pins // - For SBC65EC and SBC68EC this frees up PIC pin RB0. #if (defined(BRD_SBC65EC) || defined(BRD_SBC68EC)) && defined(NIC_DISABLE_INT0) NICPut(CMDR, 0xe0); //Select page 3 NICPut(RTL9346CR, 0xc0); //Config register write enable NICPut(RTLCONF1, 0); //Interrupt disable - will cause INT0 to be high impedance. NICPut(RTL9346CR, 0x00); //Normal operating mode NICPut(CMDR, 0x20); //Reset to default = Page 0 #endif }
void MACInit(void) { int8 i; // On Init, all transmit buffers are free. for ( i = 0; i < MAX_DATA_BUFFERS; i++ ) { TxBuffers[i].Index = TXSTART + (i * (MAC_TX_BUFFER_SIZE/NIC_PAGE_SIZE)); TxBuffers[i].bFree = TRUE; } NICCurrentTxBuffer = 0; NICReset(); delay_ms(2); NICPut(NIC_RESET, NICGet(NIC_RESET)); delay_ms(2); // mimimum Delay of 1.6 ms // Continue only if reset state is entered. if ( (NICGet(ISR) & 0x80) != 0 ) { // Select Page 0 NICPut(CMDR, 0x21); delay_ms(2); // Initialize Data Configuration Register NICPut(DCR, DCRVAL); // Clear Remote Byte Count Registers NICPut(RBCR0, 0); NICPut(RBCR1, 0); // Initialize Receive Configuration Register NICPut(RCR, 0x04); // Place NIC in LOOPBACK mode 1 NICPut(TCR, 0x02); // Initialize Transmit buffer queue NICPut(TPSR, TxBuffers[NICCurrentTxBuffer].Index); // Initialize Receive Buffer Ring NICPut(PSTART, RXSTART); NICPut(PSTOP, RXSTOP); NICPut(BNRY, (BYTE)(RXSTOP-1)); // Initialize Interrupt Mask Register // Clear all status bits NICPut(ISR, 0xff); // No interrupt enabled. NICPut(IMR, 0x00); // Select Page 1 NICPut(CMDR, 0x61); // Initialize Physical Address Registers NICPut(PAR0, MY_MAC_BYTE1); NICPut(PAR0+1, MY_MAC_BYTE2); NICPut(PAR0+2, MY_MAC_BYTE3); NICPut(PAR0+3, MY_MAC_BYTE4); NICPut(PAR0+4, MY_MAC_BYTE5); NICPut(PAR0+5, MY_MAC_BYTE6); // Initialize Multicast registers for ( i = 0; i < 8; i++ ) NICPut(MAR0+i, 0xff); // Initialize CURRent pointer NICPut(CURRP, RXSTART); // Remember current receive page NICReadPtr = RXSTART; // Page 0, Abort Remote DMA and Activate the transmitter. NICPut(CMDR, 0x22); // Set Normal Mode NICPut(TCR, 0x00); } }
VOID NICWatchDogEvtTimerFunc( IN WDFTIMER Timer ) /*++ Routine Description: This DPC is used to do both link detection during hardware init and after that for hardware hang detection. Arguments: Return Value: None --*/ { PFDO_DATA FdoData = NULL; LARGE_INTEGER DueTime; NTSTATUS status = STATUS_SUCCESS; FdoData = FdoGetData(WdfTimerGetParentObject(Timer)); DueTime.QuadPart = NIC_CHECK_FOR_HANG_DELAY; if(!FdoData->CheckForHang){ // // We are still doing link detection // status = NICLinkDetection(FdoData); if(status == STATUS_PENDING) { // Wait for 100 ms FdoData->bLinkDetectionWait = TRUE; DueTime.QuadPart = NIC_LINK_DETECTION_DELAY; }else { FdoData->CheckForHang = TRUE; } }else { // // Link detection is over, let us check to see // if the hardware is stuck. // if(NICCheckForHang(FdoData)){ status = NICReset(FdoData); if(!NT_SUCCESS(status)){ goto Exit; } } } WdfTimerStart(FdoData->WatchDogTimer, // Timer DueTime.QuadPart // DueTime ); return; Exit: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "WatchDogTimer is exiting %x\n", status); return; }