📄 irq.c
字号:
#include <stdio.h>
#include "../stripe.h"
#define INT_SOURCE_STATUS (EXC_INT_CTRL00_BASE + 0x08)
#include "adam.h"
#include "serial.h"
extern type_eth_descriptors eth;
ULONG timems1 = 0;
int irq(void);
int irq(void)
{
ULONG rdata, rdata2;
ULONG int_source;
ULONG timer_sr;
ULONG mddata, mddata1, mddata5, mddata18;
// printf("\nIRQ()\n");
int_source = *(ULONG *)(INT_SOURCE_STATUS);
// ethernet on int_pld1
// phy on int_pld2
// ethernet core
if (int_source & 0x02)
{
// printf("\nETH IRQ()\n");
rdata = *(volatile ULONG *)(DMA_INT_SRC);
// printf("dma_int_src = %08lx\n",rdata);
while (rdata) // add timeout .. in case irq's are not cleared
{
if (rdata & 0x00000004)
{
printf("AHB interrupt\n");
printf("ahb_signalled_error=%ld, ahb_received_error=%ld", (rdata>>19)&1, (rdata>>20)&1);
*(volatile ULONG *)(DMA_INT_SRC) = 0x00180000; // clear ahb int
}
if (rdata & 0x00000020)
printf("SWI interrupt\n");
if (rdata & 0x00000100)
{
printf("Excessive Buffer descriptors interrupt\n");
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000100; // clear int
}
if (rdata & 0x00000200)
{
// printf("MAC Control Completed interrupt\n");
// printf("TxCtlFrameStatus = %08lx (exp 0x00324080)\n",*(ULONG *)(MAC_TX_CTLFRM_STATUS));
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000200; // clear int
}
if (rdata & 0x00000400)
{
printf("NR Abort interrupt\n");
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000400; // clear int
}
if (rdata & 0x00010000)
{
printf("Excessive Deferrals interrupt\n");
*(volatile ULONG *)(DMA_INT_SRC) = 0x00010000; // clear int
}
if (rdata & 0x00008000) // LINK interrupt
{
printf("LINK interrupt\n");
// link interrupts require direct connection of the phy status pins
// i.e. mii_conn = low
rdata2 = *(volatile ULONG *)(MAC_MAC_CTL);
*(volatile ULONG *)(MAC_MAC_CTL) = rdata2 | 0x00000100; // clear int link
*(volatile ULONG *)(DMA_INT_SRC) = 0x00008000; // clear int link
}
if (rdata & 0x00001000) // BUFFER_LIST_EXHAUSTED interrupt
{
printf("BUFFER_LIST_EXHAUSTED interrupt\n");
// this is not sufficient to resolve the situation ...
*(volatile ULONG *)(DMA_INT_SRC) = 0x00001000; // clear buffer_list_exhausted
}
if (rdata & 0x00000800) // FDA_EHAUSTED interrupt
{
printf("FDA_EHAUSTED interrupt\n");
// this is not sufficient to resolve the situation ...
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000800; // clear fda_exhausted
}
if (rdata & 0x00000040) // EARLY_NOTIFY interrupt
{
// printf("EARLY_NOTIFY interrupt\n");
// if you're really impatient, the first buffer (but not necessarily the
// whole packet) is now available, ip header processing could now start ...
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000040; // clear early_notify
}
if (rdata & 0x00000001) // TX interrupt
{
// printf("TX interrupt\n");
// this is not the best place to trap tx errors
// as the txstatus is cleared as soon as the next packet begins
// the status should be taken from the tx descriptors
rdata = *(volatile ULONG *)MAC_TX_STAT;
/*
if (rdata & 0x1350)
{
printf("MAC_TX_STAT = %08lx\n", rdata);
if (rdata & 0x0010) printf("*** excessive collisions ***\n");
if (rdata & 0x0040) printf("*** paused ***\n");
if (rdata & 0x0100) printf("*** underrun ***\n");
if (rdata & 0x0200) printf("*** excessive deferrals ***\n");
if (rdata & 0x1000) printf("*** late collision ***\n");
}
*/
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000001; // clear tx int
}
if (rdata & 0x00000002) // RX interrupt
{
// printf("RX interrupt\n");
// this is not the best place to trap rx errors
// as the rxstatus is cleared as soon as the next packet begins
// the status should be taken from the rx_fda descriptors
/*
rdata = *(volatile ULONG *)MAC_RX_STAT;
if (rdata & 0x0f10)
{
printf("MAC_RX_STAT = %08lx\n", rdata);
if (rdata & 0x0010) printf("*** lenerr ***\n");
if (rdata & 0x0100) printf("*** alignment error ***\n");
if (rdata & 0x0200) printf("*** crc error ***\n");
if (rdata & 0x0400) printf("*** overflow ***\n");
if (rdata & 0x0800) printf("*** long error ***\n");
}
*/
*(volatile ULONG *)(DMA_INT_SRC) = 0x00000002; // clear rx int
}
rdata = *(volatile ULONG *)(DMA_INT_SRC);
}
}
// ethernet phy device
if (int_source & 0x04)
{
printf("\nPHY_IRQ()\n");
// read MR17, interrupt status, read to clear
mddata = eth_mdread(0x1f, 17);
if (mddata & 0x0001)
{
printf("AUTO NEGOTIATION COMPLETE - ");
mddata18 = eth_mdread(0x1f, 18);
printf("%s\n", (mddata18 & 0x1000) ? "FAIL" : "OK");
printf(" %s\n", (mddata18 & 0x0800) ? "FULL DUPLEX" : "HALF DUPLEX");
printf(" %s\n", (mddata18 & 0x0400) ? "100BASE-TX" : "10BASE-T");
// should make sure the MAC is set correctly ...
eth.fullduplex = (mddata18 & 0x0800) ? 1 : 0;
rdata = read_csr(MAC_MAC_CTL);
write_csr(MAC_MAC_CTL, (rdata & 0xfffffff7) | ((eth.fullduplex) ? 8 : 0)); // set duplex mode
}
if (mddata & 0x0002) printf("REMOTE FAULT\n");
if (mddata & 0x0004)
{
printf("LINK STATUS CHANGE - ");
mddata1 = eth_mdread(0x1f, 01);
printf(" %s\n", (mddata1 & 0x0004) ? "UP" : "DOWN");
}
if (mddata & 0x0008) printf("LINK PARTNER ACKNOWLEDGE\n");
if (mddata & 0x0010) printf("PARALLEL DETECT FAULT\n");
if (mddata & 0x0020)
{
printf("PAGE RECEIVE\n");
mddata5 = eth_mdread(0x1f, 05);
printf("link partner ability\n");
printf(" ACKNOWLEDGE %s\n", (mddata5 & 0x4000) ? "YES" : "NO");
printf(" REMOTE FAULT %s\n", (mddata5 & 0x2000) ? "YES" : "NO");
printf(" PAUSE %s\n", (mddata5 & 0x0400) ? "YES" : "NO");
printf(" 100BASE-T4 %s\n", (mddata5 & 0x0200) ? "YES" : "NO");
printf(" 100BASE-TX FULL DUPLEX %s\n", (mddata5 & 0x0100) ? "YES" : "NO");
printf(" 100BASE-TX %s\n", (mddata5 & 0x0080) ? "YES" : "NO");
printf(" 10BASE-T FULL DUPLEX %s\n", (mddata5 & 0x0040) ? "YES" : "NO");
printf(" 10BASE-T %s\n", (mddata5 & 0x0020) ? "YES" : "NO");
}
if (mddata & 0x0040) printf("RECEIVE ERROR\n");
if (mddata & 0x0080) printf("JABBER\n");
}
// timer0
timer_sr = *(volatile ULONG *)(EXC_TIMER0_SR);
if (timer_sr & 0x8)
{
// clear interupt
*(volatile ULONG *)(EXC_TIMER0_CR) = 0x1c;
}
// timer1 - ms
timer_sr = *(volatile ULONG *)(EXC_TIMER1_SR);
if (timer_sr & 0x8)
{
timems1 ++;
// clear interupt
*(volatile ULONG *)(EXC_TIMER1_CR) = 0x1c;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -