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

📄 eth860.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
   break;
case 192:
   IMMR->brgc1 = B19200;  /* 19200 baud */
   break;
case 96:
   IMMR->brgc1 = B9600;  /* 9600 baud */
   break;
case 24:
   IMMR->brgc1 = B2400;  /* 2400 baud */
   break;
case 12:
   IMMR->brgc1 = B1200;  /* 1200 baud */
   break;
default:
   DEBUG_ERROR("smc_uart_open - bad baud rate = ", EBS_INT1, uinfo->baud_rate, 0);
   return(FALSE);
}

IMMR->si_simode = SIMODE_SMC1CS_BRG1;  /* BRG 1 */

   /* set up rx buffer descriptors - defined in mpc860ad.h       */

   CurrentRxBuf = 0;
   for (i=0; i<SMC1RxBDs; i++)
   {
      BUFFER_DESCRIPTORS[SMC1_RX_BD+i].flags = BD_SMC_UART_RX_EMPTY | BD_SMC_UART_RX_INTERRUPT;
      BUFFER_DESCRIPTORS[SMC1_RX_BD+i].length = 0;
      BUFFER_DESCRIPTORS[SMC1_RX_BD+i].buffer = uart_inbuf + (4*i);
   }
   BUFFER_DESCRIPTORS[SMC1_RX_BD+i-1].flags |= BD_SMC_UART_RX_WRAP;

   for (i=0; i<SMC1TxBDs; i++)
   {
      BUFFER_DESCRIPTORS[SMC1_TX_BD+i].flags = BD_SMC_UART_TX_INTERRUPT;
      BUFFER_DESCRIPTORS[SMC1_TX_BD+i].length = 0;
      uartTxDCU[i] = os_alloc_packet_input(CFG_RS232_XMBUFSIZE, ETH860_ALLOC);  /* get a DCU */
      BUFFER_DESCRIPTORS[SMC1_TX_BD+i].buffer = uartTxDCU[i]->data;
   }
   BUFFER_DESCRIPTORS[SMC1_TX_BD+i-1].flags |= BD_SMC_UART_TX_WRAP;


   /*******************************************************      */
   /* Common To All Protocols Parameter RAM Initialization       */
   /*******************************************************      */

/* Set RXBD pointer in SMC1 parameter ram      */

   uart_recbd = BUFFER_DESCRIPTORS+SMC1_RX_BD;
   bd_union.bd = uart_recbd;
   SMC1_PRAM[0].rbase = bd_union.rbase[1]; /* least sig word */     

/* Set TXBD pointer in SMC1 parameter ram      */

   uart_sendbd = (BUFFER_DESCRIPTORS+SMC1_TX_BD);
   uart_sentbd = (BUFFER_DESCRIPTORS+SMC1_TX_BD);
   bd_union.bd = uart_sendbd;
   SMC1_PRAM[0].tbase = bd_union.tbase[1]; /* least sig word */     

   SMC1_PRAM[0].rfcr = 0x18;  /* Byte ordering, DMA FC */
   SMC1_PRAM[0].tfcr = 0x18;
   SMC1_PRAM[0].mrblr = 1;   /* max chars on receive */
   SMC1_PRAM[0].max_idl = 0; /* no idle timeout */
   SMC1_PRAM[0].brkln = 0;
   SMC1_PRAM[0].brkec = 0;
   SMC1_PRAM[0].brkcr = 1;

/* Initialize the CP with the new rx and tx parameters       */
   IMMR->cp_cr = CPCR_INIT_TX_RX_PARAMS |
                 CPCR_SMC1_DSP1_CH | 
                 CPCR_FLG;              /* ISSUE COMMAND  */

   while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);  /* remove */
   
   /*  Interrupts!       */
   /* set mask bits to enable interrupts*/
   IMMR->smc_regs[SMC1_REG].smc_smcm = (SMCE1_BSY | SMCE1_TX | SMCE1_RX);    
   IMMR->smc_regs[SMC1_REG].smc_smce = 0xFF;    /* clear any old event bits */

   IMMR->smc_regs[SMC1_REG].smc_smcmr = 0x4820;  /* UART mode, 8N1 */
   IMMR->smc_regs[SMC1_REG].smc_smcmr = 0x4823;  /* Tx, Rx enabled */

   rs232_1_enable_ads(1);  /* enable rs232 860 boards */ 

   /*----------------------------------------------------------------------      */
   /* Clear Pending Interrupts in CIPR -- Clear bits by writing 1 (16-482)       */
   /*----------------------------------------------------------------------      */

   IMMR->cpmi_cipr &= ~CIMR_SMC1;   /* Clear any existing pending interrupt */
   IMMR->cpmi_cisr  =  CIMR_SMC1;   /* Clear any existing in-service interrupt */

   /*---------------------------------------------------            */
   /* Enable SMC1 Interrupts to the CP Interrupt                    */
   /* Controller by writing 0x00000010 to CIMR (16-483)             */
   /*---------------------------------------------------            */

   IMMR->cpmi_cimr |= CIMR_SMC1;

  return(TRUE);

#else /* (SMC1UART, SMC2UART) */
#error
#endif
}


/* ********************************************************************             */
/* close the UART driver interface.                                            */
/*                                                                                  */
/* This routine is called when the device interface is no longer needed             */
/* it should stop the driver from delivering packets to the upper levels            */
/* and shut off packet delivery to the network.                                     */
/*                                                                                  */
/* The address of this function must be placed into the "devices" table in          */
/* iface.c either at compile time or before a device open is called.                */
/*                                                                                  */
/*                                                                                  */
/* Non packet drivers should behave the same way.                                   */
/*                                                                                  */
void smc_uart_close(PIFACE pi)                                
{
   int i;

   rs232_1_enable_ads(0);  /* disable rs232 860 boards */ 
   /* reset mask bits to disable interrupts*/
   IMMR->smc_regs[SMC1_REG].smc_smcm = 0;    

   IMMR->smc_regs[SMC1_REG].smc_smcmr &= ~0x0003;  /* Tx, Rx disabled */

   /*---------------------------------------------------    */
   /* Disable SMC1 Interrupts to the CP Interrupt           */
   /* Controller by clearing 0x00000010 in CIMR (16-483)    */
   /*---------------------------------------------------    */

   IMMR->cpmi_cimr &= ~CIMR_SMC1;

/* Return all DCU's back to the system */

   for (i=0; i<SMC1TxBDs; i++)
   {
        os_free_packet(uartTxDCU[i]);
   }
}

/*--------------------------------------------------------------------------
*
* FUNCTION NAME: UARTIntHandler 
*
* DESCRIPTION:
*
*     Process External Interrupt (assumes only interrupts from SMC1)
*     Comes here when '860 interrupts us with a received packet.                  
*
*     Main Processing Steps:
*
*        (1) Save off SMCE for SMC1 (SMC1 Event Register)
*
*        (2) Clear SMC1 Event Register
*
*        (3) Test SMC1 Event
*
*        (4) Clear SMC1 bit CPM Interrupt In-Service Register
*
*
*
* EXTERNAL EFFECTS:  interrupt related registers
*
* PARAMETERS:
*
*     vector - interrupt vector (address)
*
* RETURNS: NONE
*
*-------------------------------------------------------------------------*/

void SMCUARTIntHandler(int vector)
{
   VUBYTE my_smce1;

   /*--------------------------------------      */
   /* Grab the SMC event register (16-361)       */
   /*--------------------------------------      */
   
    my_smce1 = IMMR->smc_regs[SMC1_REG].smc_smce;  
 
    /* Clear all events that will be serviced     */
   IMMR->smc_regs[SMC1_REG].smc_smce = my_smce1;
  
    n_SMC1_interrupts += 1;

    if (!(my_smce1 & (SMCE1_BSY | SMCE1_TX | SMCE1_RX)))
    {
        n_bogus_SMC1_interrupts += 1;
    }

    if (my_smce1 & SMCE1_RX) /* Character received - signal interrupt task  */
    {
    n_SMC1_RX_interrupts += 1;
        smc_receiver(uartInfo);
    }

    if (my_smce1 & SMCE1_TX)   /* Buffer transmitted - signal interrupt task */
    {
     n_SMC1_TX_interrupts += 1;
//     while (!(uart_sentbd->flags & BD_SMC_UART_TX_READY) & (uart_sentbd->length))
//     {
       n_SMC1_CHARS_out += uart_sentbd->length;
       uart_sentbd->length = 0;
       if (uart_sentbd->flags & BD_SMC_UART_TX_WRAP)
         uart_sentbd = (BUFFER_DESCRIPTORS+SMC1_TX_BD);
       else
         uart_sentbd++;
//     }
     ks_invoke_output(uartIface);
    }
    if (my_smce1 & SMCE1_BSY)      /* receive error - no bd's available */
    {
     n_SMC1_BSY_interrupts += 1;
    }
   IMMR->cpmi_cisr = CIMR_SMC1;       /* Clear any existing in-service interrupt */
}
/* ********************************************************************             */
/* Send serial data via the SMC UART driver interface.                              */
/*                                                                                  */
/* This routine is called from uart_send or is called directly with a send buffer	*/
/* and number of characters to send. This routine sends as many as it can and		*/
/* returns the number sent. Characters are copied into send buffers initialized as	*/
/* part of buffer descriptors. This routine marks buffers for the 860 SMC to send	*/
/* while the output ISR re-enables the sent buffers.						*/
/*                                                                                  */
int smc_uart_send(char *pdata, int n_bytes)                                
{
int i;
int n_left, n_this_packet;
int n_sent = 0;
char *pbuffer,*pcurrent;

n_left = n_bytes;
pcurrent = pdata;

/* continue to transmit while there are free bd's and there are characters left to go */
while (!(uart_sendbd->flags & BD_SMC_UART_TX_READY) & (uart_sendbd->length==0) & (n_left>0))
{
    if(n_left <= CFG_RS232_XMBUFSIZE)	/* break send buffer into buffer sized chunks */
	n_this_packet = n_left;
    else
	n_this_packet = CFG_RS232_XMBUFSIZE;

    n_sent += n_this_packet;
    n_left -= n_this_packet;

    /* copy send data into the send buffer descriptor and send it*/
    pbuffer = uart_sendbd->buffer;
    for(i=0;i<n_this_packet;i++) *pbuffer++ = *pcurrent++;
    uart_sendbd->length =(unsigned short)n_this_packet;
    uart_sendbd->flags |= BD_SMC_UART_TX_READY;
	
    if (uart_sendbd->flags & BD_SMC_UART_TX_WRAP)
       uart_sendbd = (BUFFER_DESCRIPTORS+SMC1_TX_BD);
    else
       uart_sendbd++;
}
return (n_sent);
}

/* ********************************************************************             */
/* This is the SMC UART input handler called from the SMC interrupt handler.		*/
/*                                                                                  */
void smc_receiver(PUART_INFO uinfo)
{
byte chr;
PCIRC_BUFF pq;
int start_rx,rx;

    start_rx=CurrentRxBuf;

    for (;;)
    {
      if (BUFFER_DESCRIPTORS[SMC1_RX_BD+CurrentRxBuf].flags & BD_SMC_UART_RX_EMPTY)
      {
        if (BUFFER_DESCRIPTORS[SMC1_RX_BD+CurrentRxBuf].flags & BD_SMC_UART_RX_WRAP)
          CurrentRxBuf = 0;
        else
          CurrentRxBuf += 1;
      }
      else /* Here we have a buffer that is not empty but we may have error condition */
      {
        uart_recbd = BUFFER_DESCRIPTORS+SMC1_RX_BD+CurrentRxBuf;
        if (uart_recbd->flags &    (BD_SMC_UART_RX_OVERRUN |
						BD_SMC_UART_RX_PARITY |
						BD_SMC_UART_RX_FRAMING ))
        {
          if (uart_recbd->flags & BD_SMC_UART_RX_OVERRUN)
		rs232_error(uinfo->minor_number,0);
          if (uart_recbd->flags & BD_SMC_UART_RX_PARITY)
		rs232_error(uinfo->minor_number,1);
          if (uart_recbd->flags & BD_SMC_UART_RX_FRAMING)
		rs232_error(uinfo->minor_number,2);
	    n_SMC1_ERR_in += 1;
        }
        else /* Here we have good input */
        {
          pq = &uinfo->input_queue;
          chr=uart_inbuf[(4*CurrentRxBuf)];
          /* if buffer is not full, queue it   */
          if (!cq_full(pq))
          {
            /* Signal if in raw mode or if it is a framing   */
            /* character                                     */
            cq_enque(pq,chr);       /* Que the character */
            if (uinfo->raw_mode || (chr == uinfo->framing_char))
            {
              ks_invoke_interrupt(uinfo->rs232_pi);
            }
            n_SMC1_CHARS_in += 1;
          }
          else
          {
            /* Tell rs232 package that we lost a character   */
            rs232_error(uinfo->minor_number, 3);
            n_SMC1_LOST_in += 1;
          }
        }

        /* Make sure error bits are reset and reset the buffer */
        uart_recbd->flags &=    ~(BD_SMC_UART_RX_OVERRUN |
						B

⌨️ 快捷键说明

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