⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ether_test.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 3 页
字号:
		printf ("DMA Overrun Error = %d\n", pRfd->dmaOverrun);
		printf ("Frame Too Short Error = %d\n", pRfd->frameTooshort);
		printf ("Receive Collision Error = %d\n", pRfd->rxColl);
		return (ERROR);
	}

#if 0
	printf ("Packet Actual Size = %d\n", pRfd->actCount);
#endif

	if (checkPacket (pCmdBlock->transmit.txData, pRfd->rxData, ETHERMTU) == ERROR)
	{
		printf ("data verify error.\n");
		return (ERROR);
	}
    
	if (forever_flag == FALSE) printf ("data OK.\n");
#endif

	return (OK);
}


/*
 * "Poor Man's Malloc" - return a pointer to a block of memory at least
 * The block returned will have been zeroed.
 */
static char *malloc (int numBytes) /* number of bytes needed */
{
	volatile char *rtnPtr;	/* ptr to return to caller */
	long	new_mem_pool;	/* For figuring new pool base address */

	rtnPtr = mem_pool;	/* Return pointer to start of free pool */

	/* Now calculate new base of free memory pool (round to >= 16 bytes) */
	new_mem_pool = (UINT32) mem_pool;
	new_mem_pool = ((new_mem_pool + numBytes + 0x10) & (~((UINT32) 0x0f)));
	mem_pool = (volatile char *) new_mem_pool;

	bzero (rtnPtr, numBytes);

	return ((char *) rtnPtr);
}


/* "Poor Man's bzero" - zero's a block of memory. */
static void bzero (volatile char *ptr, long num_bytes)
{
volatile long i;		/* loop counter */

	/* zero out space */
	for (i = 0; i < num_bytes; *ptr++ = 0, i++)
	  ;
}


/*
 * Write "value" to PORT register of PRO/100.
 */
static void portWrite (UINT32 value)
{
	*PORT_REG(adapter[0]) = value;
}


/******************************************************************************
*
* sendCommand - send a command to the 82557 via the on-chip SCB
*
* Send a command to the 82557.  On the 82557, the Channel Attention signal
* has been replaced by an on-chip SCB.  Accesses to the Command Word portion
* of the SCB automatically forces the '557 to look at the various data
* structures which make up its interface.
*/
static void sendCommand (UINT8 cuc, UINT8 ruc, UINT32 scb_general_ptr)
{
	register CMD_STAT_U temp_cmdStat;
	volatile union cmdBlock *pBlock = (union cmdBlock *)scb_general_ptr;
	volatile int loop_ctr;
	
	/* Mask adapter interrupts to prevent the interrupt handler from
	   playing with the SCB */
	mask_557_ints();

	/* must wait for the Command Unit to become idle to prevent
       us from issueing a CU_START to an active Command Unit */
    for (loop_ctr = BUSY_WAIT_LIMIT; loop_ctr > 0; loop_ctr--)
    {
        if ((pSCB->cmdStat.words.status & SCB_S_CUMASK) == SCB_S_CUIDLE)
            break;
    }
    if (loop_ctr == 0)
    {
        printf("sendCommand: CU won't go idle, command ignored\n");
		unmask_557_ints();
        return;
    }

	/* when setting the command word, read the current word from
	   the SCB and preserve the upper byte which contains the interrupt
	   mask bit */
	temp_cmdStat.words.command = (pSCB->cmdStat.words.command & 0xff00);
	temp_cmdStat.words.status = 0;

	/* set up the Command and Receive unit commands */
	temp_cmdStat.bits.cuc = cuc & 0x07;
	temp_cmdStat.bits.ruc = ruc & 0x07;

	/* Clear flag */
	waitSem = 0;

	/* write the General Pointer portion of the SCB first */
	pSCB->scb_general_ptr = scb_general_ptr;

	/* write the Command Word of the SCB */
	pSCB->cmdStat.words.command = temp_cmdStat.words.command;

	/* only wait for command which will complete immediately */
	if ((scb_general_ptr != 0/* NULL*/) && (ruc != RU_START))
	{
		/* wait for command acceptance and completion */
		for (loop_ctr = BUSY_WAIT_LIMIT; loop_ctr > 0; loop_ctr--)
		{
			if ((pSCB->cmdStat.bits.cuc == 0) && (pBlock->nop.c == 1))
				break;
		}
		if (loop_ctr == 0)
		{
			printf("sendCommand: Timeout on command complete\n");
			printf("Cmd Complete bit = %02X\n", pBlock->nop.c);
			printf("CU command       = 0x%02X\n", cuc);
			printf("RU command       = 0x%02X\n", ruc);
			printf("SCB Gen Ptr      = 0x%X\n", scb_general_ptr);
			printf("scb status       = 0x%04X\n", pSCB->cmdStat.words.status);
			printf("scb command      = 0x%04X\n", pSCB->cmdStat.words.command);
		}
	}

#if 0
	/* DEBUG */
	printf("scb command = 0x%04X\n", pSCB->cmdStat.words.command);
	printf("scb status  = 0x%04X\n", pSCB->cmdStat.words.status);
#endif

	unmask_557_ints();
	return;
}


/*
 * Do a port reset on 82557.
 */
static void resetChip ()
{
	portWrite (PORT_RESET);	/* bits 4-31 not used for reset */

	/* wait 5 msec for device to stabilize */
	Wait(5);
}


/*
 * Setup contents of a packet.
 */
static void makePacket (UINT8 *pPacket, int length)
{
int byteNum;	/* Current byte number */

	for (byteNum = 0; byteNum < length; byteNum++)
		*pPacket++ = byteNum + ' ';
}


/*
 * Verify contents of a received packet to what was transmitted.
 * Returns OK if they match, ERROR if not.
 */
static int checkPacket (pTxBuffer, pRxBuffer, length)
UINT8 *pTxBuffer;		/* Pointer data that was transmitted */
UINT8 *pRxBuffer;		/* Pointer data that was received */
int	length;				/* How many bytes to check */
{
int byteNum;	/* Current byte number */

#if 0
     printf ("\n");
     printf ("Transmit Buffer at 0x%08X\n", pTxBuffer);
     printf ("Receive  Buffer at 0x%08X\n", pRxBuffer);
#endif
     for (byteNum = 0; byteNum < length; byteNum++)
     {
		if (*pTxBuffer++ != *pRxBuffer++)
		{
			printf("Error at byte 0x%x\n", byteNum);
			printf("Expected 0x%02X, got 0x%02X\n", *(pTxBuffer - 1), *(pRxBuffer - 1));
            return (ERROR);
		}
     }
     return (OK);
}


/*
 * Interrupt handler for i82557.  It acknowledges the interrupt
 * by setting the ACK bits in the command word and issuing a
 * channel attention.  It then updates the global status variable
 * and gives the semaphore to wake up the main routine.
 */
int i557IntHandler (int arg)  /* should return int */
{
register CMD_STAT_U temp_cmdStat;
register int rxFlag = FALSE;

    temp_cmdStat.words.status = pSCB->cmdStat.words.status;

    /* check to see if it was the PRO/100 */
    if (temp_cmdStat.words.status & I557_INT)
    {
		/* Wait for command word to clear - indicates no pending commands */
		while (pSCB->cmdStat.words.command)
			;

		/* Update global status variable */
		i557Status = temp_cmdStat.words.status;

#if 0
		printf ("i557IntHandler: i557Status = 0x%04x\n", i557Status);
#endif

		/* If the interrupt was due to a received frame... */
		if (temp_cmdStat.bits.statack_fr)
		    rxFlag = TRUE;

		temp_cmdStat.words.status = temp_cmdStat.words.status & I557_INT;

		/* Acknowledge interrupt by setting ack bits */
		pSCB->cmdStat.words.status = temp_cmdStat.words.status;

		/* Wait for command word to clear - indicates IACK accepted */
		while (pSCB->cmdStat.words.command)
			;

#if 0
		/* DEBUG */
		printf ("give waitSem\n");
#endif

		/* Update global status variable and unblock task */
		waitSem = 1;

		if (rxFlag == TRUE)
			rxSem = 1;

		return(1);		/* serviced - return 1 */
	}
    
	return(0);			/* nothing serviced - return 0 */
}



/*
 * Take the semaphore and block until i557 interrupt or timeout.
 * Returns OK if an interrupt occured, ERROR if a timeout.
 */
static int waitForInt()
{
int num_ms = 0; 

	while ((waitSem == 0) && (num_ms != 2000)) /* wait max 2secs for the interrupt */
	{	
		delay_ms(1);
		num_ms++;
	}

    if (!waitSem)
    {
		printf("Wait error!\n"); 
		return (ERROR);
    }
    else
		return (OK);
	
}


static int waitForRxInt()
{
int num_ms = 0; 

	while ((rxSem == 0) && (num_ms != 2000)) /* wait max 2secs for the interrupt */
	{	
		delay_ms(1);
		num_ms++;
	}

    if (!rxSem)
    {
		printf("Rx Wait error!\n"); 
		return (ERROR);
    }
    else
		return (OK);
}


static UINT16 readMDI (int unit, UINT8	phyAdd, UINT8	regAdd)
{

register MDI_CONTROL_U mdiCtrl;
int num_ms = 0; 


	/* prepare for the MDI operation */
	mdiCtrl.bits.ready = MDI_NOT_READY;
	mdiCtrl.bits.intEnab = MDI_POLLED;	/* no interrupts */
	mdiCtrl.bits.op = MDI_READ_OP;
	mdiCtrl.bits.phyAdd = phyAdd & 0x1f;
	mdiCtrl.bits.regAdd = regAdd & 0x1f;

	/* start the operation */
	*MDI_CTL_REG(adapter[unit]) = mdiCtrl.word;

	/* delay a bit */
	Wait (1);

	/* poll for completion */
	mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);

	while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) /* wait max 2secs */
	{	
		mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);
		delay_ms(1);
		num_ms++;
	}	
	
	if (num_ms >= 2000)
	{
		printf ("readMDI Timeout!\n");
		return (-1);
	}
	else 
		return ((UINT16)mdiCtrl.bits.data);
}


static void writeMDI (int unit, UINT8 phyAdd, UINT8 regAdd, UINT16 data)
{
	
register MDI_CONTROL_U mdiCtrl;
int num_ms = 0;


	/* prepare for the MDI operation */
	mdiCtrl.bits.ready = MDI_NOT_READY;
	mdiCtrl.bits.intEnab = MDI_POLLED;  /* no interrupts */
	mdiCtrl.bits.op = MDI_WRITE_OP;
	mdiCtrl.bits.phyAdd = phyAdd & 0x1f;
	mdiCtrl.bits.regAdd = regAdd & 0x1f;
	mdiCtrl.bits.data = data & 0xffff;

	/* start the operation */
	*MDI_CTL_REG(adapter[unit]) = mdiCtrl.word;

	/* delay a bit */
	Wait (1);

	/* poll for completion */
	mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);

	while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) 
	{
		mdiCtrl.word = *MDI_CTL_REG(adapter[unit]);
		delay_ms(1);
		num_ms++;
	}	
	if (num_ms >= 2000)
		printf ("writeMDI Timeout!\n");
 
	return;
}


static void Wait (int msecs)
{
	delay_ms(msecs);
}


static int get_ether_addr (
                int     unit,
                UINT8   *buffer,
                int     print_flag      /* TRUE to print the information */
		)
{
     UINT16 temp_node_addr[3] = {0,0,0};
     register int i;

    /* Get the adapter's node address */
    if (eeprom_read (adapter[unit],IA_OFFSET,temp_node_addr,3) != OK)
    {
         printf ("Error reading the IA address from Serial EEPROM.\n");
         return (ERROR);
    }
 
    buffer[0] = (UINT8)(temp_node_addr[0] & 0x00ff);
    buffer[1] = (UINT8)((temp_node_addr[0] & 0xff00)>>8);
    buffer[2] = (UINT8)(temp_node_addr[1] & 0x00ff);
    buffer[3] = (UINT8)((temp_node_addr[1] & 0xff00)>>8);
    buffer[4] = (UINT8)(temp_node_addr[2] & 0x00ff);
    buffer[5] = (UINT8)((temp_node_addr[2] & 0xff00)>>8);
 
    if (print_flag == TRUE)
    {
        printf("Ethernet Address = [ ");
        for (i=0; i<6; i++)
        {
            printf("0x%02X ", buffer[i]);
        }
        printf("]\n\n");
    }
    return (OK);
}


void bcopy(UINT32* src, UINT32* dst, int num_bytes)
{
int i;
	for (i = 0; i < num_bytes; i++)
		*dst++ = *src++;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -