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

📄 eth860.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/* ********************************************************************               */
/* Transmitter Packet.                                                                */
/*                                                                                    */
/* This routine is called by when a packet needs sending. The packet contains         */
/* a full ethernet frame to be transmitted. The length of the packet is               */
/* provided.                                                                          */

int eth860_xmit(PIFACE pi, DCU msg)    /*__fn__*/
{
int i;
int length;

    length = DCUTOPACKET(msg)->length;
    if (length < 64) length = 64;

    eth860_wait_ticks = (word) (ks_ticks_p_sec()/5);
    if (!eth860_wait_ticks)
        eth860_wait_ticks = ks_ticks_p_sec();
    eth860_retry = 0;

    pi->xmit_done_timer = eth860_wait_ticks;

/*    GSMR_L1 &= ~(GSMR_L_ENT);     */

  /* (re) Initialize transmitter          */
/*  CR = CR_INITTX | CR_SCC1 | CR_FLG;    */
/*  while (CR & CR_FLG)  {};              */
  
  /* Re Enable the transmitter and receiver          */
/*  GSMR_L1 |= GSMR_L_ENT;                           */


    /* start the xmit       */
    sendbd->buffer = DCUTODATA(msg);
    sendbd->length = length;
    sendbd->flags &= ~(BD_SCC_ETH_TX_COLLISION  |
                       BD_SCC_ETH_TX_HEARTBEAT  |
                       BD_SCC_ETH_TX_LATE       |
                       BD_SCC_ETH_TX_LIMIT      |
                       BD_SCC_ETH_TX_RETRY_MASK |
                       BD_SCC_ETH_TX_UNDERRUN   |
                       BD_SCC_ETH_TX_CARRIER);
    sendbd->flags |= (BD_SCC_ETH_TX_READY | BD_SCC_ETH_TX_INTERRUPT);
/*    sendbd->flags |= BD_SCC_ETH_TX_READY;     */

/* wait while current transmit completes               */
/*  while (sendbd->flags & BD_SCC_ETH_TX_READY) {};    */

/*      ks_invoke_output(pi);     tell eth860_xmit() it's sent      */

    return 0;
}

/* this routine is called from the interrupt routine to handle recv packets     */
static void eth860_receiver(PIFACE pi)
{
   DCU msg;
   volatile BUFFER_DESCRIPTOR *rcvbd;
   int toss;
#   if (DEBUG_ETH)
      aa_n_rcv_ints++;
#   endif
   int start_rx;

   start_rx = CurrentRx;

   for (;;)
   {
      if (BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].flags & BD_SCC_ETH_RX_EMPTY)
      {      /* the controller still has this DCU */
          if (BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].flags & BD_SCC_ETH_RX_WRAP)
              CurrentRx = 0;
          else
              CurrentRx += 1;
      }
      else
      {
         toss = 0;
            /* here's an incoming packet from the packet driver        */
         rcvbd = BUFFER_DESCRIPTORS+SCC1_RX_BD+CurrentRx;

         if (rcvbd->flags & (BD_SCC_ETH_RX_MISS | BD_SCC_ETH_RX_VIOLATION | BD_SCC_ETH_RX_NONALIGNED |
             BD_SCC_ETH_RX_LITTLE | BD_SCC_ETH_RX_CRC | BD_SCC_ETH_RX_OVERRUN | BD_SCC_ETH_RX_COLLISION))
         {
#        if (DEBUG_ETH)
           DEBUG_UWORD(rcvbd->flags);
           aa_n_bad_rcv_ints++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_MISS)       aa_n_bad_rcv_miss++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_VIOLATION)  aa_n_bad_rcv_vi++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_NONALIGNED) aa_n_bad_rcv_non++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_LITTLE)     aa_n_bad_rcv_little++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_CRC)        aa_n_bad_rcv_crc++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_OVERRUN)    aa_n_bad_rcv_ov++;
           if ( rcvbd->flags & BD_SCC_ETH_RX_COLLISION)  aa_n_bad_rcv_coll++;
#        endif
           toss = 1;
#        ifdef  RECEIVE_ALL_FRAMES
           if ( rcvbd->flags & BD_SCC_ETH_RX_MISS) toss = 0;
#        endif
           rcvbd->flags &=
           ~(BD_SCC_ETH_RX_MISS|BD_SCC_ETH_RX_VIOLATION|BD_SCC_ETH_RX_NONALIGNED|
           BD_SCC_ETH_RX_LITTLE|BD_SCC_ETH_RX_CRC|BD_SCC_ETH_RX_OVERRUN|BD_SCC_ETH_RX_COLLISION);
           mcstats.errors_in += 1;

         }
         else
            toss = 0;
         if (toss)
            msg = 0;
         else
               /* allocate a DCU for the incoming packet     */
            msg = os_alloc_packet_input(CFG_ETHERSIZE, ETH860_ALLOC);    
               /* If the alloc worked, pass the rcved packet up                              */
               /* If the alloc failed re-use input packet to not starve the controller       */
         if (msg)
         {
            RxDCU[CurrentRx]->length = BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].length-4;
/*DEBUG_ETHERNET_PACKET((rcvbd->buffer));                                             */
               /* invoke an LSR to remove the packet from the                         */
               /* receive list and and place it in the interface's IP queue           */
               /* and signal the signal the IP task by calling os_sndx_ip_exchg       */
#if (RTIP_VERSION > 24)
		    ks_invoke_input(pi, RxDCU[CurrentRx]);
#else
            os_sndx_input_list(pi, RxDCU[CurrentRx]);
            ks_invoke_input(pi);       
#endif
            mcstats.packets_in += 1;
            mcstats.bytes_in += RxDCU[CurrentRx]->length;
            RxDCU[CurrentRx] = msg;
         }
             
         BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].length = 0;
         BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].buffer = RxDCU[CurrentRx]->data;


         BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].flags |= BD_SCC_ETH_RX_EMPTY;

         if (BUFFER_DESCRIPTORS[SCC1_RX_BD+CurrentRx].flags & BD_SCC_ETH_RX_WRAP)
            CurrentRx = 0;
         else
            CurrentRx += 1;
      }
      if (start_rx == CurrentRx)
         break;
   }
}

/* ********************************************************************                      */
/* Statistic. return statistics about the device interface                                   */
/*                                                                                           */
/* This routine is called by user code that wishes to inspect driver statistics.             */
/* We call this routine in the demo program. It is not absolutely necessary                  */
/* to implement such a function (Leave it empty.), but it is a handy debugging               */
/* tool.                                                                                     */
/*                                                                                           */
/* The address of this function must be placed into the "devices" table in                   */
/* tcdevtbl.c either at compile time or before a device open is called.                      */
/*                                                                                           */
/*                                                                                           */
/* Non packet drivers should behave the same way.                                            */
/*                                                                                           */

BOOLEAN eth860_statistics(PIFACE  pi)                       /*__fn__*/
{
    UPDATE_SET_INFO(pi, interface_packets_in, mcstats.packets_in)
    UPDATE_SET_INFO(pi, interface_packets_out, mcstats.packets_out)
    UPDATE_SET_INFO(pi, interface_bytes_in, mcstats.bytes_in)
    UPDATE_SET_INFO(pi, interface_bytes_out, mcstats.bytes_out)
    UPDATE_SET_INFO(pi, interface_errors_in, mcstats.errors_in)
    UPDATE_SET_INFO(pi, interface_errors_out, mcstats.errors_out)
    UPDATE_SET_INFO(pi, interface_packets_lost, mcstats.packets_lost)
    return(TRUE);
}

/*--------------------------------------------------------------------------
*
* FUNCTION NAME: EthernetIntHandler 
*
* DESCRIPTION:
*
*     Process External Interrupt (assumes only interrupts from SCC1)
*     Comes here when '860 interrupts us with a received packet.                  
*
*     Main Processing Steps:
*
*        (1) Save off SCCE for SCC1 (SCC1 Event Register)
*
*        (2) Clear SCC1 Event Register
*
*        (3) Test SCC1 Event
*
*        (4) Clear SCC1 bit CPM Interrupt In-Service Register
*
*
*     NOTE: This ISR will only handle ONE RX event.
*
* EXTERNAL EFFECTS:  interrupt related registers
*
* PARAMETERS:
*
*     vector - interrupt vector (address)
*
* RETURNS: NONE
*
*-------------------------------------------------------------------------*/

void EthernetIntHandler(int vector)
{
   dword my_scce1;

   /*--------------------------------------      */
   /* Grab the SCC event register (16-333)       */
   /*--------------------------------------      */
   
    my_scce1 = IMMR->scc_regs[SCC1_REG].scc_scce;  
 
    /* Clear all events that will be serviced     */
   IMMR->scc_regs[SCC1_REG].scc_scce = my_scce1;
  
    n_interrupts += 1;

    if (!(my_scce1 & (SCCE_ETH_RXF | SCCE_ETH_TXB | SCCE_ETH_TXE)))
    {
        n_bogus_interrupts += 1;
    }

    if (my_scce1 & SCCE_ETH_RXF) /* Frame received - signal interrupt task  */
        eth860_receiver(myIface);

    if (my_scce1 & SCCE_ETH_TXB)   /* Buffer transmitted */
    {
        while (!(sentbd->flags & BD_SCC_ETH_TX_READY) && sentbd->buffer)
        {  /* transmit packet has been sent */
            /*if(sentbd->flags & 0x3ff) DEBUG_UWORD(sentbd->flags);     */

            sentbd->flags &= ~(BD_SCC_ETH_TX_COLLISION  |
                        BD_SCC_ETH_TX_HEARTBEAT  |
                        BD_SCC_ETH_TX_LATE       |
                        BD_SCC_ETH_TX_LIMIT      |
                        BD_SCC_ETH_TX_RETRY_MASK |
                        BD_SCC_ETH_TX_UNDERRUN   |
                        BD_SCC_ETH_TX_CARRIER);
            sentbd->buffer = 0;
            ks_invoke_output(myIface);    /* tell eth860_xmit() it's sent */
            if (sentbd->flags & BD_SCC_ETH_TX_WRAP)
                sentbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
            else 
                sentbd++;
        }
    }
    if (my_scce1 & SCCE_ETH_TXE)      /* transmit error */
    {
        ks_invoke_output(myIface);    /* signal eth860_xmit() he'll reset */
    }
   IMMR->cpmi_cisr = CIMR_SCC1;       /* Clear any existing in-service interrupt */
}



/*-------------------------------------------------------------------------
* FUNCTION NAME: ether_enable_ads
* DESCRIPTION:
*
*     Enable/Disable Ethernet on 821/860 ADS board.
*
* PARAMETERS: 
*     setting - 0 in lsb Disable Ethernet and turns off LED
*               1 in lsb Enable  Ethernet and turns on LED.
*-------------------------------------------------------------------------*/
void ether_enable_ads(word setting)
{
   BCSR *csr;
#if(ADS860)
   csr = (BCSR *)(IMMR->memc_br1 & 0xFFFF8000);
   if (setting & 0x01)
      csr->bcsr1 &= ~ETHEN;   /* Enable  Ethernet (turn on LED) */
   else
      csr->bcsr1 |= ETHEN;      /* Disable Ethernet (turn off LED) */
#elif(MPC860)
   csr =  (BCSR *)((IMMR->memc_br4 & 0xffff8000) | 0x00100000);
   if (setting & 0x01)
      csr->bcsr1 |= 0x9C;   /* Enable Ethernet10baset */
   else
      csr->bcsr1 &= ~0x80;      /* Disable Ethernet*/
#else
#error
#endif

} /* end ether_enable_ads */

#if(!RTKD860)
/*-------------------------------------------------------------------------
* FUNCTION NAME: rs232_1_enable_ads
* DESCRIPTION:
*
*     Enable/Disable RS232 port1 on 821/860 ADS and MBX boards.
*
* PARAMETERS: 
*     setting - 0 in lsb Disable port and (turns off LED on ADS)
*               1 in lsb Enable  port and turns on LED.
*-------------------------------------------------------------------------*/

void rs232_1_enable_ads(word setting)
{
   BCSR *csr;
#if (ADS860)
   csr = (BCSR *)(IMMR->memc_br1 & 0xFFFF8000);
   if (setting & 0x01)

      csr->bcsr1 &= ~RS232EN1;   /* Enable  RS232 port1 (turn on LED) */
   else
      csr->bcsr1 |= RS232EN1;      /* Disable RS232 port1 (turn off LED) */
#elif(MPC860)
   csr =  (BCSR *)((IMMR->memc_br4 & 0xffff8000) | 0x00100000);
   if (setting & 0x01)
      csr->bcsr1 &= ~0x03;   /* Enable  RS232 port1  */
   else
      csr->bcsr1 |= 0x01;      /* Disable RS232 port1  */
#else
#error
#endif
} /* end rs232_1_enable_ads */

/*-------------------------------------------------------------------------

⌨️ 快捷键说明

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