Description
Source
Call Graph
Start Line: 354
void EMAC_Handler(void)
{
volatile EmacTxTDescriptor *pTxTd;
volatile EMAC_TxCallback *pTxCb;
unsigned int isr;
unsigned int rsr;
unsigned int tsr;
unsigned int rxStatusFlag;
unsigned int txStatusFlag;
//TRACE_DEBUG("EMAC_Handler\n\r");
isr = AT91C_BASE_EMAC->EMAC_ISR & AT91C_BASE_EMAC->EMAC_IMR;
rsr = AT91C_BASE_EMAC->EMAC_RSR;
tsr = AT91C_BASE_EMAC->EMAC_TSR;
// RX packet
if ((isr & AT91C_EMAC_RCOMP) || (rsr & AT91C_EMAC_REC)) {
rxStatusFlag = AT91C_EMAC_REC;
// Frame received
EmacStatistics.rx_packets++;
// Check OVR
if (rsr & AT91C_EMAC_OVR) {
rxStatusFlag |= AT91C_EMAC_OVR;
EmacStatistics.rx_ovrs++;
}
// Check BNA
if (rsr & AT91C_EMAC_BNA) {
rxStatusFlag |= AT91C_EMAC_BNA;
EmacStatistics.rx_bnas++;
}
// Clear status
AT91C_BASE_EMAC->EMAC_RSR |= rxStatusFlag;
// Invoke callbacks
if (rxTd.rxCb) {
rxTd.rxCb(rxStatusFlag);
}
}
// TX packet
if ((isr & AT91C_EMAC_TCOMP) || (tsr & AT91C_EMAC_COMP)) {
txStatusFlag = AT91C_EMAC_COMP;
EmacStatistics.tx_comp ++;
// A frame transmitted
// Check RLE
if (tsr & AT91C_EMAC_RLES) {
txStatusFlag |= AT91C_EMAC_RLES;
EmacStatistics.tx_errors++;
}
// Check COL
if (tsr & AT91C_EMAC_COL) {
txStatusFlag |= AT91C_EMAC_COL;
EmacStatistics.collisions++;
}
// Check BEX
if (tsr & AT91C_EMAC_BEX) {
txStatusFlag |= AT91C_EMAC_BEX;
EmacStatistics.tx_exausts++;
}
// Check UND
if (tsr & AT91C_EMAC_UND) {
txStatusFlag |= AT91C_EMAC_UND;
EmacStatistics.tx_underruns++;
}
// Clear status
AT91C_BASE_EMAC->EMAC_TSR |= txStatusFlag;
// Sanity check: Tx buffers have to be scheduled
ASSERT(!CIRC_EMPTY(&txTd),
"-F- EMAC Tx interrupt received meanwhile no TX buffers has been scheduled\n\r");
// Check the buffers
while (CIRC_CNT(txTd.head, txTd.tail, TX_BUFFERS)) {
pTxTd = txTd.td + txTd.tail;
pTxCb = txTd.txCb + txTd.tail;
// Exit if buffer has not been sent yet
if ((pTxTd->status & EMAC_TX_USED_BIT) == 0) {
break;
}
// Notify upper layer that packet has been sent
if (*pTxCb) {
(*pTxCb)(txStatusFlag);
}
CIRC_INC( txTd.tail, TX_BUFFERS );
}
// If a wakeup has been scheduled, notify upper layer that it can send
// other packets, send will be successfull.
if( (CIRC_SPACE(txTd.head, txTd.tail, TX_BUFFERS) >= txTd.wakeupThreshold)
&& txTd.wakeupCb) {
txTd.wakeupCb();
}
}
}