📄 cs8900.c.svn-base
字号:
tcpipCb1 = func1;
tcpipCb2 = func2;
tcpipCb3 = func3;
tcpipCb3(linkState);
}
#if ETHER_DEBUG
else
{
#if (!ETHER_TEST)
sysPrnUart("ether init NOT over!\n");
#endif
}
#endif
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
void etherTask(MessageId tEvent, LC_BYTE *pbData, LC_WORD wLen)
{
switch (tEvent)
{
case EV_ACTIVATE_REQ:
etherTaskActiveMsg();
break;
case EV_TIMER1EVENT: /* loop timer event. */
etherLinkCheck();
break;
#if MSG_WAKEUP
case 2: /* check send queue. */
#if ETHER_DEBUG
if (wLen != 1)
{
sysPrnUart("ethernet internal msg len %d error!\n", wLen);
break;
}
#endif
etherSendQueueRetry(*pbData);
break;
#endif
default:
sysPrnUart("ether task recv unknown event[0x%08x]!\n", tEvent);
break;
}
oseFreeMem(pbData);
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static void etherLinkCheck(void)
{
LC_BYTE curState = UP;
if (etherInitOver)
{
if ((readReg(PP_LineSTAT) & PP_LineSTAT_LinkOK) == 0)
{
curState = DOWN;
}
if (curState != linkState)
{
linkState = curState;
if (tcpipCb3)
{
tcpipCb3(curState);
}
}
}
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static void etherInterrupt(void)
{
LC_INT status;
while (status = readWord(ISQ_PORT))
{
switch(status & ISQ_EventMask)
{
#if ETHER_DEBUG
/*sysPrnUart("%d\n", status);*/
#endif
case ISQ_RxEvent:
#if ETHER_DEBUG
etherStatistic.dwRecvInt++;
#endif
triggerType |= RECV_INT_TRIGGER;
etherRx();
break;
case ISQ_TxEvent:
if (status & (PP_TER_TxOK | PP_TER_CRS | PP_TER_SQE |
PP_TER_Late | PP_TER_16Collisions) != PP_TER_TxOK)
{
etherStatistic.dwSendError++;
}
#if ETHER_DEBUG
etherStatistic.dwSendInt++;
#endif
etherSendQueueWakeup(SEND_INT_TRIGGER);
break;
case ISQ_BufEvent:
#if ETHER_DEBUG
etherStatistic.dwBuffInt++;
#endif
if (status & PP_BER_Rdy4Tx)
{
etherSendQueueWakeup(BUF_INT_TRIGGER);
}
break;
case ISQ_RxMissEvent:
etherStatistic.dwRxMiss += (status >> 6);
break;
case ISQ_TxColEvent:
etherStatistic.dwTxCol += (status >> 6);
break;
}
}
rEINTPEND |= (1 << 9);
ClearPending(0x1 << ETHER_INT_BIT);
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static void etherRx(void)
{
LC_WORD status;
LC_INT len;
LC_WORD *addr;
LC_WORD itemSize;
LC_WORD i;
dsm_item_type *dsm, *next;
status = readWord(RX_FRAME_PORT);
len = readWord(RX_FRAME_PORT); /* not include CRC */
if (status & PP_RER_RxOK == 0)
{
etherStatistic.dwInvalidRecvFrame++;
return;
}
if (len > ETHER_PKT_MAX)
{
etherStatistic.dwRecvPktTooLong++;
return;
}
if (!len)
{
etherStatistic.dwRecvPktTooShort++;
return;
}
if (!tcpipCb1)
{
return;
}
/* use the whole buffer of the dsm item, no offset. */
itemSize = dsm_get_item_size(DSM_DS_LARGE_ITEM_POOL);
dsm = dsm_new_buffer_all(DSM_DS_LARGE_ITEM_POOL, len);
if (!dsm)
{
etherStatistic.dwDsmMallocFailed++;
return;
}
i = len >> 1;
addr = (LC_WORD *)dsm->data_ptr;
next = dsm;
for (; i > 0; i--)
{
*addr = readWord(RX_FRAME_PORT);
next->used += 2;
if (next->used == itemSize)
{
next = next->pkt_ptr;
if (!next)
{
#if ETHER_DEBUG
if (i - 1)
{
etherStatistic.dwEtherDsmLogicError++;
sysPrnUart("etherRx! [%d %d]\n", i, len);
}
#endif
goto recv_done;
}
addr = (LC_WORD *)next->data_ptr;
}
else
{
addr++;
}
}
if (len & 1)
{
*addr = readWord(RX_FRAME_PORT);
next->used += 1;
}
recv_done:
etherStatistic.dwRecvFrame++;
etherStatistic.dwRecvByte += len;
#if ETHER_DEBUG
recv_dsm = dsm;
#endif
tcpipCb1(dsm);
oseActiveDt(ETHER_INT_BIT);
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static void etherSendQueueRetry(LC_BYTE type)
{
dsm_item_type *dsm;
LC_INT cnt;
LC_INT result;
LC_WORD len;
if ((cnt = q_cnt(ðerSendQueue)) == 0)
{
triggerType &= ~(SEND_INT_TRIGGER | BUF_INT_TRIGGER);
return;
}
while (cnt)
{
dsm = (dsm_item_type *)q_get(ðerSendQueue);
#if ETHER_DEBUG
if (!dsm)
{
sysPrnUart("ether send queue error!\n");
q_init(ðerSendQueue);
triggerType &= ~(SEND_INT_TRIGGER | BUF_INT_TRIGGER);
return;
}
#endif
/* I'm sure, length is valid.*/
len = dsm_length_packet(dsm);
result = etherDrvTx(dsm, len);
if (result == BUS_NOT_RDY)
{
#if ETHER_DEBUG
if (type != SEND_INT_TRIGGER) /* amazing. */
{
sysPrnUart("etherSendQueueRetry!\n");
}
#endif
triggerType &= ~(SEND_INT_TRIGGER | BUF_INT_TRIGGER);
/* wait for next interrupt. */
return;
}
cnt--;
}
triggerType &= ~(SEND_INT_TRIGGER | BUF_INT_TRIGGER);
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static void etherSendQueueWakeup(LC_BYTE type)
{
#if MSG_WAKEUP
/* ONLY record when msg wakeup. */
triggerType |= type;
/* only wake up send queue once per INT. */
if (0 == msgWakeup)
{
msgWakeup = 1;
oseActiveDt(ETHER_INT_BIT);
}
#else
etherSendQueueRetry(type);
#endif
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
void etherStatisticRestart(void)
{
memset (ðerStatistic, 0, sizeof (struct ifStatistic));
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static LC_INT etherDrvTx(dsm_item_type *dsm, LC_WORD wPktLen)
{
dsm_item_type *next;
LC_WORD i, wBufLen;
/*volatile*/ LC_WORD *addr;
/* initiate a transmit sequence */
writeWord(TX_CMD_PORT, PP_TxCmd_TxStart_Full);
writeWord(TX_LEN_PORT, wPktLen);
/* Test to see if the chip has allocated memory for the packet */
if ((readReg(PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0)
{
return BUS_NOT_RDY;
}
/* Write the contents of the packet */
i = wPktLen >> 1;
wBufLen = dsm->used;
next = dsm;
addr = (LC_WORD *)dsm->data_ptr;
for (; i > 0; i--)
{
writeWord(TX_FRAME_PORT, *addr);
wBufLen -= 2;
if (0 == wBufLen)
{
next = next->pkt_ptr;
if (0 == next)
{
#if ETHER_DEBUG
if (i - 1)
{
etherStatistic.dwTcpipDsmLogicError++;
sysPrnUart("etherDrvTx! [%d %d ]\n", i, wPktLen);
}
#endif
goto packet_free;
}
addr = (LC_WORD *)next->data_ptr;
wBufLen = next->used;
}
else
{
addr++;
}
}
if (wPktLen & 1)
{
writeWord(TX_FRAME_PORT, *addr);
}
packet_free:
etherStatistic.dwSendFrame++;
etherStatistic.dwSendByte += wPktLen;
dsm_free_packet(&dsm);
return 0;
}
/*==============================================================================
* Function :
* Description :
* In Parameter :
** Type :
** Description :
* Out Parameter :
** Type :
** Description :
* Return :
* Other :
==============================================================================*/
static void etherDt(void)
{
#if ETHER_DEBUG
LC_BYTE buf[ETHER_PRN_SIZE * 3];
LC_WORD len;
#endif
#if MSG_WAKEUP
if (msgWakeup)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -