?? ethloop.c
字號(hào):
//****************************************************************************
//
// File Name: EthLoop.c
//
// Purpose: The LoopTest program performs two tests:
// 1. EEPROM Test:
// -Write and verifies reset and driver configuration blocks.
// -Reset the CS8900
// -Verifies that the registers read in by the reset configuration block
// are correct.
// 2. LoopBack Test:
// -Sets up the CS8900 registers for loop back.
// -Bids for and transmits a frame.
// -Polls teh receive register for the receive frame
// -Verifies that the data is correct.
//
// Copyright (c) 2001 Cirrus Logic, Inc.
//
//*****************************************************************************
//
// The following is the basic flow of the loopback test program
//
// This procedure assumes you are using 10B-T. Use a "loopback" cable,
// included in the EDB7312 evaluation kit in a small bag with the title
// "Ethernet Loopback Connector for EthLoop.c Code".
// A regular 10B-T cable connected to a hub will not work.
//
// Configure RxCTL for Promiscious mode, RxOK
// (1) Write 0x0104 to IOBase+0xA (PacketPage Pointer)
// (2) Write 0x0180h to IOBase+0xC (PacketPage Data Port)
//
// Configure TestCTL (FDX, DisableLT)
// (3) Write 0x0118 to IOBase+0xA (PacketPage Pointer)
// (4) Write 0x4080 to IOBase+0xC (PacketPage Data Port)
//
// Set 10BaseT, SerRxOn, SerTxOn in LineCTL
// (5) Write 0x0112 to IOBase+0xA (PacketPage Pointer)
// (6) Write 0x00C0 to IOBase+0xC (PacketPage Data Port)
//
// Write the TX command
// (7) Write 00C0h to IOBase+0x4 (PacketPage Pointer)
//
// Write the frame length (XX = number of bytes to TX)
// (8) Write 00XXh to IOBase+0x6 (PacketPage Pointer)
//
// Read BusST to verify it is set as 0x0118 (Rdy4TxNow is set)
// (9) Write 0x0138 to IOBase+0xA (PacketPage Pointer)
// (10) Read IOBase+0xC Should read 0x0118
//
// Copy the TX frame to the on-chip buffer
// (11) Write XX/2 words to IOBase+0x0 (TX Data Port)
//
// At this point frame should go out on the wire.
//
// To read the TX'd frame:
//
// Read RxEvent for RxOK (0x0104)
// (12) Write 0x0124 to IOBase+0xA (PacketPage Pointer)
// (13) Read IOBase+0xC Should read 0x0104 or 0x0504h
//
// Read IOBase+0 This will be the RxStatus (RxEvent) word again.
// Read IOBase+0 again. This will be the RxLength (number of bytes received).
// Read IOBase+0 (RxLength/2) times to read complete frame.
//
//************************************************************************
#include "EthLoop.h"
#include "EpromDat.h"
#include "ep7312.h"
#include <stdio.h>
int entry( void );
void reset( void);
int LoopBackTest( void );
//***********************************************************************
//
// entry() - calls the EEPROM test and the loop back test.
//
//***********************************************************************
int entry( void )
{
unsigned long *pulPtr = (unsigned long *)HwBaseAddress;
unsigned long test;
// Initialize CS2 for 16-bit 4 wait states.
// start by clearing the CS2 field
pulPtr[HwMemConfig1 >> 2] &= 0xff00ffff;
// now get the boot width and set CS4 accordingly
// boot width is in bits 27 and 28 of HwStatus
test = (pulPtr[HwStatus >> 2] >> 27) & 0x3; // boot width is in bits 27 and 28 of HwStatus
switch(test)
{
case 0: // we booted in 32-bit mode
pulPtr[HwMemConfig1 >> 2] |= (0x00000090 | (1 << 16));
break;
case 1: // we booted in 8-bit mode
pulPtr[HwMemConfig1 >> 2] |= (0x00000090 | (3 << 16));
break;
case 2: // we booted in 16-bit mode
/* The correct setting for CS[2] here is 0x00. This is the current value from above */
/* So, I don't know why this assignment is here. */
/* It's presence causes the processor to hang at the assignment. */
/* pulPtr[HwMemConfig1 >> 2] |= (0x00000090 | (0 << 16)); -Gabriel Field */
break;
}
EepromTest();
LoopBackTest( );
return(0);
}
//**************************************************************************
// LoopBackTest()
//**************************************************************************
int LoopBackTest( void )
{
unsigned short int i, j, receive_frame_size, temp;
printf("\nBegin LoopBack test..............\n");
// Initialize the part
//
// Configure RxCTL for Promiscious mode, RxOK
// (1) Write 0x0104 to IOBase+0xA (PacketPage Pointer)
// (2) Write 0x0180h to IOBase+0xC (PacketPage Data Port)
//
outport( (IO_BASE + PP_POINTER ), 0x0104 );
outport( (IO_BASE + PP_DATA ), 0x0180 );
//
// Configure TestCTL (FDX, DisableLT, ENDEC loop ) */
// (3) Write 0x0118 to IOBase+0xA (PacketPage Pointer)
// (4) Write 0x4080 to IOBase+0xC (PacketPage Data Port)*/
//
outport( (IO_BASE + PP_POINTER ), 0x0118 );
outport( (IO_BASE + PP_DATA ), 0x4000 );
//
// Set 10BaseT, SerRxOn, SerTxOn in LineCTL
// (5) Write 0x0112 to IOBase+0xA (PacketPage Pointer)
// (6) Write 0x00C0 to IOBase+0xC (PacketPage Data Port)
//
outport( (IO_BASE + PP_POINTER ), 0x0112 );
outport( (IO_BASE + PP_DATA ), 0x00c0 );
for (i = 0; i < NO_FRAMES_TO_SEND ; i++)
{
//
// Write the TX command
// (7) Write 00C0h to IOBase+0x4
//
outport( (IO_BASE + TX_CMD ), 0x00c0 );
//
// Write the frame length (XX = number of bytes to TX)
//(8) Write 00XXh to IOBase+0x6
//
outport( ( IO_BASE + TX_LENGTH ), SIZE_OF_FRAME * 2 );
//
//(9) Write 0x0138 to IOBase+0xA (PacketPage Pointer)
//
outport( (IO_BASE + PP_POINTER), 0x0138 );
//
// delay for a while
//
for ( j = 0; j < 10000; j++);
//
// (10) Read IOBase+0xC, Should read 0x0118 to indicate Ready
// for a transfer now.
//
if ( (temp=inport(IO_BASE + PP_DATA)) != 0x0118)
{
printf("\n\n Bid for transmit failed");
printf("\nRegister PP_DATA = %4.4x", temp);
return(FAILURE);
}
//
// Copy the TX frame to the on-chip buffer
// (11) Write XX/2 words to IOBase+0x0 (TX Data Port)
for (j = 0; j < SIZE_OF_FRAME; j++)
{
outport( IO_BASE , WORD_DATA );
}
//
// Delay for a while
//
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
for ( j = 0; j < 30000; j++);
//
// Read RxEvent for RxOK (0x0104)
// (12) Write 0x0124 to IOBase+0xA (PacketPage Pointer)
// (13) Read IOBase+0xC Should read 0x0104h or 0x0504h
//
outport ( (IO_BASE + PP_POINTER), 0x0124);
if ((temp = inport (IO_BASE + PP_DATA)) != 0x0104)
{
printf("\n\n Frame not received");
printf("\nRegister 0x0124 PP_DATA = %4.4x \n", temp);
reset();
return( FAILURE );
}
//
// Read IOBase+0 This should be the RxStatus (RxEvent) word again.
//
if ( (temp = inport ( IO_BASE )) != 0x0104)
{
printf("\n\n Frame not received -- reading data port");
printf("\nRegister 0x0124 PP_DATA = %4.4x", temp);
reset();
return( FAILURE );
}
//
// Read IOBase+0 again. This should be the RxLength (number of bytes received).
//
receive_frame_size = inport( IO_BASE );
if (SIZE_OF_FRAME < 30) /*size in words, i.e. pad characters added*/
if (receive_frame_size != 60) /* size in bytes because of pad characters*/
{
printf("\n\n Frame received is not the right size < 60");
printf("\n\n receive_frame_size = %4.4x", receive_frame_size);
reset();
return(FAILURE);
}
if (SIZE_OF_FRAME >= 30)
if (receive_frame_size != (SIZE_OF_FRAME * 2))
{
printf("\n\n Frame received is not the right size >= 60");
printf("\n\n receive_frame_size = %4.4x ; Should be %4.4x",
receive_frame_size, (SIZE_OF_FRAME * 2));
reset();
return(FAILURE);
}
//
// Read IOBase+0 (RxLength/2) times to read complete frame.
//
for (j = 0; j < SIZE_OF_FRAME ; j++ )
{
if ( (temp = inport( IO_BASE )) != WORD_DATA)
{
printf("\n\nFrame data does not match what was sent");
printf("\n Received Data = %4.4x", temp);
reset();
return(FAILURE);
}
}
if (SIZE_OF_FRAME < 30) /* need to issue a skip to flush pad chars*/
{
outport( IO_BASE + PP_POINTER , 0x0102);
temp = inport ( IO_BASE + PP_DATA );
outport( IO_BASE + PP_DATA , ( temp | SKIP ) );
}
}
reset();
printf("\nLoopback Test Completed Successfully!\n");
return(SUCCESS);
}
//*************************************************************************
//
// reset()
//
//*************************************************************************
void reset()
{
unsigned short int temp,j;
//
// Reset the CS8900A device
//
outport( ( IO_BASE + PP_POINTER ), 0x0114 );
outport( ( IO_BASE + PP_DATA ), 0x0040 );
//
// delay for a while
//
for (j=0; j<30000; j++);
//
// Wait for reset complete
//
for (;;) {
outport ( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0080) != 0) break;
}
}
//*************************************************************************
//
// EepromTest()
//
//*************************************************************************
int EepromTest( void )
{
printf("Reset CS8900.\n");
reset();
printf("Begin EEPROM test...........\n");
if ( initEEPROM() == FAILURE ) {
return(FAILURE);
}
parse_lines(EepromData);
printf("Write data into EEPROM\n");
if ( burn_it() != SUCCESS ) {
return(FAILURE);
}
printf("Reset CS8900.\n");
reset();
printf("Read back EERPOM data and verify it.\n");
readBack();
return(SUCCESS);
}
//*************************************************************************
// initEEPROM():
//*************************************************************************
int initEEPROM( )
{
unsigned short int temp;
//
// Check the SelfST register, bit 9, for EEPROM present.
//
outport( (IO_BASE + PP_POINTER), 0x0136);
temp=inport(IO_BASE + PP_DATA);
if ( (temp & 0x0200) == 0 ) {
printf("CS8900 - EEPROM not present.\n");
return(FAILURE);
}
printf("CS8900 - EEPROM present.\n");
//
// Check Self Status register, bit 10, for checksum error.
// 1 = Checksum ok, 0 = checksum error
//
if ( (temp & 0x0400) == 0 ) {
printf("EEPROM CheckSum Error.\n");
}
else {
printf("EEPROM CheckSum Correct.\n");
}
return(SUCCESS);
}
/**************************************************************************
* ReadEE():
* Returns word from EEPROM from address EE_word_offset
*************************************************************************/
unsigned short int readEE(unsigned short int EE_word_offset )
{
unsigned short int j, temp;
//
// Wait until SIBUSY is clear. Check bit 8 if Self Status register.
// 1 = busy, 0 = not busy
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if (((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
//
// Send EEPROM command
//
outport( ( IO_BASE + PP_POINTER ), 0x0040 );
outport( ( IO_BASE + PP_DATA ), (0x0200+EE_word_offset));
//
// Wait until SIBUSY is clear
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
//
// delay for a while
//
for (j=0; j<30000; j++);
//
// Read data from EEPROM and return.
//
outport( (IO_BASE + PP_POINTER), 0x0042);
temp=inport(IO_BASE + PP_DATA);
return(temp);
}
/**************************************************************************
* WriteEE():
* Writes outword to the EEPROM @ address EE_Word_offset. Returns a
* read back of the word just written.
*************************************************************************/
unsigned short int writeEE(unsigned short int EE_word_offset,
unsigned short int outword )
{
unsigned short int j,temp;
//
// Wait until SIBUSY is clear. Check bit 8 of Self Status register.
// 1 = busy, 0 = not busy
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -