?? lan91c96.c
字號:
// Get the transmit status. WriteWord(LAN91C96_PTR_READ, &ioRegsP[LAN91C96_POINTER]); resultCode = ReadWord(&ioRegsP[LAN91C96_DATA_HIGH]); // Select Bank 0. WriteByte(BANK0, &ioRegsP[LAN91C96_BANK_SELECT]); // Clear the statistics register. ReadWord(&ioRegsP[LAN91C96_COUNTER]); // Re-enable TXENA in the Transmit Control Register. WriteWord(LAN91C96_TCR_TXENA, &ioRegsP[LAN91C96_TCR]); // Select Bank 2 WriteByte(BANK2, &ioRegsP[LAN91C96_BANK_SELECT]); // Release the memory in the buffer for the frame that failed. WriteWord(LAN91C96_MMUCR_RELEASE_TX, &ioRegsP[LAN91C96_MMU]); // Prepare for timeout by getting the initial time interval. hal_clock_read(&start) ;//ostCtxP->getTimer_fnp(ostCtxP); // Wait for the request to complete by monitoring the NO BUSY bit in // the MMU Command Register. while (!ReadWord(&ioRegsP[LAN91C96_MMU]) & LAN91C96_MMUCR_NO_BUSY) { // Get the current time interval. hal_clock_read(&currTimerValue) ; if(hal_elapsed_ticks((unsigned long *)&start) > timeout) { //printf("timeout during DeallocateTxPacket\n") ; // Report timeout error. return (-1); } } // Get the Interrupt Status Register. intStatus = ReadByte(&ioRegsP[LAN91C96_INT_STATS]); // Enable transmit interrupt if set. if (intStatus & LAN91C96_IST_TX_INT) { // Acknowledge the Transmit interrupt. WriteByte(LAN91C96_ACK_TX_INT, &ioRegsP[LAN91C96_INT_ACK]); } return (0);}/********************************************************************************** FUNCTION:* LAN91C96LoopBack** DESCRIPTION:* Enable/Disable internal loopback.** INPUT PARAMETERS:* LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure* INT flag = 0 = disable loopback, 1 = enable loopback.** RETURNS:* 0 - Success* non-zero - Error** GLOBAL EFFECTS:* LAN91C96 left in desired state.** ASSUMPTIONS:* None.** CALLS:* WriteByte - To write a byte to either the attribute or I/O space.* WriteWord - To write a word to either the attribute or I/O space.* ReadWord - Read a word from either the attribute or I/O space.** CALLED BY:* Test code.** PROTOTYPE:* INT LAN91C96LoopBack(LAN91C96_ContextT *ctxP, INT flag);*********************************************************************************/INT LAN91C96LoopBack(LAN91C96_ContextT *ctxP, INT flag){ PVUINT32 ioRegsP = ctxP->LAN91C96IoP; // Get pointer to I/O space UINT16 TCR; // Select Bank 0 WriteByte(BANK0, &ioRegsP[LAN91C96_BANK_SELECT]); // Get the Transmit Control Register. TCR = ReadWord(&ioRegsP[LAN91C96_TCR]); // Non-zero flag indicate internal loopback desired. if (flag) { // Set internal loopback. TCR |= (LAN91C96_TCR_LOOP | LAN91C96_TCR_FDUPLX); } else { // Clear internal loopback. TCR &= ~(LAN91C96_TCR_LOOP | LAN91C96_TCR_FDUPLX); // Force a reset when coming out of internal loopback. ctxP->setupFlag = FALSE; } // Update the Transmit Control Register. WriteWord(TCR, &ioRegsP[LAN91C96_TCR]); return (0);}/********************************************************************************** FUNCTION:* LAN91C96DumpFrame** DESCRIPTION:* Display the Ethernet frame.** INPUT PARAMETERS:* LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure* UINT PDUFlag = 0 - display header only, 1 - display header and PDU* PUCHAR frame - Pointer to the Ethernet frame.* UINT length - Number of bytes in frame.** RETURNS:* None.** GLOBAL EFFECTS:* None.** ASSUMPTIONS:* None.** CALLS:* DM_Printf** CALLED BY:* Test code, LAN91C96TransmitPacket, LAN91C96ReceivePacket** PROTOTYPE:* VOID LAN91C96DumpFrame(LAN91C96_ContextT *ctxP, INT PDUFlag,* PUCHAR frame, UINT16 length);*********************************************************************************/VOID LAN91C96DumpFrame(LAN91C96_ContextT *ctxP, INT PDUFlag, PUCHAR frame, UINT16 length){ UINT x; if (PDUFlag) { printf("Frame Buffer Address: 0x%x", *frame); } /*DM_Printf("To: %02x:%02x:%02x:%02x:%02x:%02x", frame[0], frame[1], frame[2], frame[3], frame[4], frame[5]); DM_Printf("From: %02x:%02x:%02x:%02x:%02x:%02x", frame[6], frame[7], frame[8], frame[9], frame[10], frame[11]); DM_Printf("Type: 0x%x, Length: %u", ntohs(*((PUINT16)(frame + 12))), length);*/ if (PDUFlag) { for (x = 14; x < length; x += 8) { /*DM_Printf("%02x %02x %02x %02x %02x %02x %02x %02x", frame[x], frame[x + 1], frame[x + 2], frame[x + 3], frame[x + 4], frame[x + 5], frame[x + 6], frame[x + 7]);*/ } }}/********************************************************************************** FUNCTION:* LAN91C96DumpRegisters** DESCRIPTION:* This routine display internal information about the LAN91C96.** INPUT PARAMETERS:* LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure** RETURNS:* None.** GLOBAL EFFECTS:* None.** ASSUMPTIONS:* None.** CALLS:* ReadWord - Read a word from either the attribute or I/O space.* WriteWord - To write a word to either the attribute or I/O space.* DM_Printf - Display text string.** CALLED BY:* Application or test code.** PROTOTYPE:* VOID LAN91C96DumpRegisters(LAN91C96_ContextT *ctxP);*********************************************************************************/VOID LAN91C96DumpRegisters(LAN91C96_ContextT *ctxP){ PVUINT32 ioRegsP = ctxP->LAN91C96IoP; // Get pointer to I/O space UINT16 bankSelect, bank0, bank1, bank2, bank3, bank4; int x; /*DM_Printf("LAN91C96 Bank Registers:"); DM_Printf("Offset Bank0 Bank1 Bank2 Bank3 Bank4");*/ // Read current bank select register. bankSelect = ReadWord(&ioRegsP[LAN91C96_BANK_SELECT]); for (x = 0; x < 16; x += 2) { // Select bank 0 register. WriteWord(0, &ioRegsP[LAN91C96_BANK_SELECT]); // Read register contains. bank0 = ReadWord(&ioRegsP[x]); // Select bank 1 register. WriteWord(1, &ioRegsP[LAN91C96_BANK_SELECT]); // Read register contains. bank1 = ReadWord(&ioRegsP[x]); // Select bank 2 register. WriteWord(2, &ioRegsP[LAN91C96_BANK_SELECT]); // Read register contains. bank2 = ReadWord(&ioRegsP[x]); // Select bank 3 register. WriteWord(3, &ioRegsP[LAN91C96_BANK_SELECT]); // Read register contains. bank3 = ReadWord(&ioRegsP[x]); // Select bank 4 register. WriteWord(4, &ioRegsP[LAN91C96_BANK_SELECT]); // Read register contains. bank4 = ReadWord(&ioRegsP[x]); /*DM_Printf("%02X %04X %04X %04X %04X %04X", x, bank0, bank1, bank2, bank3, bank4);*/ } // Restore bank select register. WriteWord(bankSelect, &ioRegsP[LAN91C96_BANK_SELECT]); /*DM_Printf("LAN91C96 Registers Complete\n");*/}/********************************************************************************** FUNCTION:* LAN91C96GetInfo** DESCRIPTION:* This routines returns MAC address.** INPUT PARAMETERS:* LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure* DM_NetworkInfo_T *info - Pointer to info structure.** RETURNS:* The MAC address in DM_NetworkInfo_T.** GLOBAL EFFECTS:* None.** ASSUMPTIONS:* None.** CALLS:* memcpy - copy one buffer to another.** CALLED BY:* Application or test code.** PROTOTYPE:* VOID LAN91C96GetInfo(LAN91C96_ContextT *ctxP, DM_NetworkInfo_T *info);*********************************************************************************/VOID LAN91C96GetInfo(LAN91C96_ContextT *ctxP, DM_NetworkInfo_T *info){ // Return the MAC address. memcpy(info->mac, ctxP->MACAddress, 6);}/********************************************************************************** FUNCTION:* LAN91C96TransmitPacket** DESCRIPTION:* This routine transmits the specified packet.** INPUT PARAMETERS:* LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure* PUINT16 buffer - Pointer to the buffer to transmit.* INT length - Size of the transmit buffer.** RETURNS:* 0 - Success* non-zero - Error** GLOBAL EFFECTS:* None.** ASSUMPTIONS:* None.** CALLS:* AllocateTxPacket - Get a transmit packet from the LAN91C96.* DeallocateTxPacket - Return the transmit packet back to the LAN91C96.* WriteByte - To write a byte to either the attribute or I/O space.* WriteWord - To write a word to either the attribute or I/O space.* ReadByte - Read a byte from either the attribute or I/O space.* ReadWord - Read a word from either the attribute or I/O space.* GetTimeStamp - Get a tick count.* GetDeltaTimeStamp - Get the time delta.* DM_Printf - Display text string.* DM_ErrPrintf - Display error string.* LAN91C96DumpFrame - Display packet.* DisplayTxStatus - Display the transmit status register.* LOGERROR - Logs errors encountered.** CALLED BY:* Application or test code.** PROTOTYPE:* INT LAN91C96TransmitPacket(LAN91C96_ContextT *ctxP,* PUINT16 buffer, INT length);*********************************************************************************/INT LAN91C96TransmitPacket(LAN91C96_ContextT *ctxP, PUINT16 buffer, INT length){ PVUINT32 ioRegsP = ctxP->LAN91C96IoP; // Get pointer to I/O space UINT start, currTimerValue ; UINT timeout = (UINT)((LAN91C96_TO_TRANSMIT * 3686400) >> 20); UCHAR intStatus; UINT16 bufferSize, resultCode, x; UINT16 frameHandle = 0; PUINT16 dataP = buffer; // Get a time reference. GetTimeStamp(ctxP); // Clear the error log. ctxP->loggedError = 0; // Check dump flag. if (ctxP->dumpFlag) { // Display transmit frame. //printf("Transmit Packet:"); LAN91C96DumpFrame(ctxP, 0, (PUCHAR)buffer, length); } // Allocate a transmit frame from the LAN91C96. if (AllocateTxPacket(ctxP, length, &frameHandle)) { //printf("AllocateTxPacket in LAN91C96TransmitPacket failed\n") ; return (ctxP->loggedError); } // Calculate the memory needed. This includes the status word, byte count // data and control rounded up. bufferSize = sizeof(UINT16) + sizeof(UINT16) + length + 1; if (bufferSize & 1) { // Round the size up. bufferSize++; } // Write the allocated packet number into the Packet Number Register. WriteWord(frameHandle, &ioRegsP[LAN91C96_PNR]); // Set the Auto Increment bit in the Pointer Register to increment the // internal address on access to the data register. WriteWord(LAN91C96_PTR_AUTO_INCR, &ioRegsP[LAN91C96_POINTER]); // Write the status word. See page 36 of the LAN91C96 specification. WriteWord(0, &ioRegsP[LAN91C96_DATA_HIGH]); // Write the byte count. WriteWord(bufferSize, &ioRegsP[LAN91C96_DATA_HIGH]); // Copy the data to the LAN91C96. for (x = 0; x < (length >> 1); x++) { // Write the data. WriteWord(*dataP++, &ioRegsP[LAN91C96_DATA_HIGH]); } // Now check for an odd number of bytes. if (length & 1) { // Write the control byte and last data byte. WriteWord((((LAN91C96_CONTROL_CRC | LAN91C96_CONTROL_ODD) << 8) | (*(dataP) & 0xFF)), &ioRegsP[LAN91C96_DATA_HIGH]); } else { // Write just the control byte. WriteWord((LAN91C96_CONTROL_CRC << 8), &ioRegsP[LAN91C96_DATA_HIGH]); } // Enqueue the frame number into the TX FIFO. WriteWord(LAN91C96_MMUCR_ENQUEUE, &ioRegsP[LAN91C96_MMU]); // Prepare for timeout by getting the initial time interval. hal_clock_read(&start) ; // Check the Interrupt Status Register for Transmit Empty. while (!((intStatus = ReadByte(&ioRegsP[LAN91C96_INT_STATS])) & LAN91C96_IST_TX_EMPTY_INT)) { hal_clock_read(&currTimerValue) ; if (hal_elapsed_ticks((unsigned long *)&start) > timeout) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -