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

📄 irq.c

📁 altera epxa1的例子程序
💻 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 + -