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

📄 uart.c

📁 uart全功能实现.实现如下函数: U_Open, U_Close, U_GetBytes, U_PutBytes, U_GetBytesAvail, U_GetTxRoomL
💻 C
📖 第 1 页 / 共 5 页
字号:
* GLOBALS AFFECTED
*   external_global
*/
kal_uint8 U_GetUARTByte(UART_PORT port)
{

  kal_uint8 data;

  while(1)
  {
    kal_uint16 LSR;
    LSR = DRV_Reg(UART_LSR(UART_BaseAddr[port]));
    if (LSR & UART_LSR_DR)
    {
      data = (kal_uint8)DRV_Reg(UART_RBR(UART_BaseAddr[port]));
      

      if( (stack_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw)||
       (uart_support_autoescape()==KAL_FALSE&&UARTPort[port].DCB.flowControl==fc_sw))     
      {
         if(uart_escape_state==0)
         {
            if(data==0x77)            
               uart_escape_state=0x77;
            else            
               return data;
         }
         else if (uart_escape_state==0x77)
         {
            uart_escape_state=0x0; 
            switch(data)
            {
               case 0x01:
                  return UARTPort[port].DCB.xonChar;
                  break;
               case 0x02:
                  return UARTPort[port].DCB.xoffChar;
                  break;               
               case 0x03:
                  return 0x77;                  
                  break;      
               default:                     
                  break;      
            }                                            
         }                           
      }
     	else
     	{
     		return data;
     	}     	      
    }
  }
}

/*
* FUNCTION
*  PutUARTByte
*
* DESCRIPTION
*     This function is to write data to UART
*
* CALLS
*  This function is to transmit data through UART
*
* PARAMETERS
*  None
*
* RETURNS
*  the data from UART
*
* GLOBALS AFFECTED
*   external_global
*/
void PutUARTRingBufferData(UART_PORT port)
{
#ifndef __DMA_UART_VIRTUAL_FIFO__
   
   kal_uint16  index;
   kal_uint16  real_count;
   kal_uint8   TX_DATA;
   kal_uint32 UART_BASE = UART_BaseAddr[port];
  
   /*ISR*/
   Buf_GetBytesAvail(&(UARTPort[port].Tx_Buffer_ISR),real_count);
   for (index = 0;index < real_count;index++)
   {
         Buf_Pop(&(UARTPort[port].Tx_Buffer_ISR),TX_DATA);
         DRV_WriteReg(UART_THR(UART_BASE),(kal_uint16)TX_DATA);
   }
   /*Task*/
   Buf_GetBytesAvail(&(UARTPort[port].Tx_Buffer),real_count);
   for (index = 0;index < real_count;index++)
   {
         Buf_Pop(&(UARTPort[port].Tx_Buffer),TX_DATA);
         DRV_WriteReg(UART_THR(UART_BASE),(kal_uint16)TX_DATA);
   }
#endif   
}

void U_PutUARTByte(UART_PORT port, kal_uint8 data)
{
  kal_uint16 LSR;

  while(1)
  {
    LSR = DRV_Reg(UART_LSR(UART_BaseAddr[port]));
    if ( LSR & UART_LSR_THRE )
    {
      DRV_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
      break;
    }
  }
}
void PutUARTData(UART_PORT port, kal_uint8 escape_char, kal_uint8 data)
{
   
   if( (stack_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw)||
       (uart_support_autoescape()==KAL_FALSE))        
   {
      if (data == UARTPort[port].DCB.xonChar)
   	{
         PutUARTByte(port, escape_char);
         PutUARTByte(port, 0x01);            
   	}
   	else if (data == UARTPort[port].DCB.xoffChar)
   	{
   		PutUARTByte(port, escape_char);
         PutUARTByte(port, 0x02);            
   	}
   	else if (data == escape_char)
   	{
         PutUARTByte(port, escape_char);
         PutUARTByte(port, 0x03);            
   	}
   	else
   	{
   		PutUARTByte(port, data);
   	}         
   }
   else
   {
   	PutUARTByte(port, data);
   }   
}
void U_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len)
{
   kal_uint16 index;
   for(index=0;index<len;index++)
      PutUARTByte(port,*(data+index));
}
void PutUARTDatas(UART_PORT port, kal_uint8 escape_char, kal_uint8 *data,kal_uint16 len)
{
   kal_uint16 index;
   for(index=0;index<len;index++)
      PutUARTData(port,escape_char,*(data+index));
}

void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate)
{
   kal_uint32   tmp_div;
   kal_uint16   divisor;
   kal_uint16   byte;
   kal_uint32   remainder;
   kal_uint32   UART_BASE = UART_BaseAddr[port];

   if ( baudrate != UART_BAUD_AUTO ) /* no autobaud */
   {
                if (baudrate <= UART_BAUD_115200)
                {
              /* Set BaudRate   */             
              tmp_div = (UART_CLOCK)/(16*baudrate);
              divisor =  (kal_uint16)tmp_div;

              remainder = (UART_CLOCK)%(16*baudrate);
              
              if (remainder >= (8*baudrate))
                 divisor =  (kal_uint16)(tmp_div+1);
              else
                 divisor =  (kal_uint16)tmp_div;



#if defined(MT6205B)||defined(MT6226M) || defined(MT6218) || defined(MT6218B) || defined(MT6219)||defined(MT6217)|| defined(MT6228)|| defined(MT6229)|| (defined(MT6226))|| (defined(MT6227)) 
             DRV_WriteReg(UART_RATE_STEP(UART_BASE),0x0);
#endif

              /* GPIO_WriteAll(divisor); */
              byte = DRV_Reg(UART_LCR(UART_BASE));     /* DLAB start */
              DRV_WriteReg(UART_LCR(UART_BASE),(byte | UART_LCR_DLAB));

              DRV_WriteReg(UART_DLL(UART_BASE),(divisor & 0x00ff));
              DRV_WriteReg(UART_DLH(UART_BASE),((divisor >> 8)&0x00ff));
              DRV_WriteReg(UART_LCR(UART_BASE),byte);      /* DLAB End */
        #ifndef __PRODUCTION_RELEASE__
              uart_lcr_save[port] = byte;
        #endif   /*__PRODUCTION_RELEASE__*/
         }
#if defined(MT6205B)||defined(MT6226M) || defined(MT6218) || defined(MT6218B) || defined(MT6219)||defined(MT6217)|| defined(MT6228)|| defined(MT6229)|| (defined(MT6226))|| (defined(MT6227)) 
                else    //support high speed uart baudrate > 115200
                 {
        tmp_div = (UART_CLOCK)/(4*baudrate);
        divisor =  (kal_uint16)tmp_div;
                                remainder = (UART_CLOCK)%(4*baudrate);
              if (remainder >= (2*baudrate))
                 divisor =  (kal_uint16)(tmp_div+1);
              else
                 divisor =  (kal_uint16)tmp_div;

                                DRV_WriteReg(UART_RATE_STEP(UART_BASE),0x02);
              byte = DRV_Reg(UART_LCR(UART_BASE));     /* DLAB start */
              DRV_WriteReg(UART_LCR(UART_BASE),(byte | UART_LCR_DLAB));
              DRV_WriteReg(UART_DLL(UART_BASE),(divisor & 0x00ff));
              DRV_WriteReg(UART_DLH(UART_BASE),((divisor >> 8)&0x00ff));
              DRV_WriteReg(UART_LCR(UART_BASE),byte);      /* DLAB End */
                 }
#endif

        }
#if  defined(MT6218)||defined(MT6226M) || defined(MT6218B) || defined(MT6219)|| defined(MT6217)|| defined(MT6228)|| defined(MT6229)|| (defined(MT6226))|| (defined(MT6227)) 
        else
        {
           switch (UART_CLOCK)
           {
              case   13000000:
              	 DRV_WriteReg(UART_AUTO_BAUDSAMPLE(UART_BASE),AUTOBAUDSAMPLE_13M);
              	 DRV_WriteReg(UART_AUTOBAUD_EN(UART_BASE),AUTOBAUD_EN);
              break;
              case   26000000:
              	 DRV_WriteReg(UART_AUTO_BAUDSAMPLE(UART_BASE),AUTOBAUDSAMPLE_26M);
              	 DRV_WriteReg(UART_AUTOBAUD_EN(UART_BASE),AUTOBAUD_EN);
              break;
              case   52000000:
              	 DRV_WriteReg(UART_AUTO_BAUDSAMPLE(UART_BASE),AUTOBAUDSAMPLE_52M);
              	 DRV_WriteReg(UART_AUTOBAUD_EN(UART_BASE),AUTOBAUD_EN);
              break;
              default:
              break;
           }
              
        }
#endif
}
/*This function is to cover 6218B/6219 hw bug.
UART should not send receiving data to its FIFO when doing auto baud*/
void U_SetAutoBaud_Div(UART_PORT port)
{
   kal_uint32   UART_BASE = UART_BaseAddr[port];
   kal_uint8 byte;
   /*TY adds this compile option 20041006*/   
   if(uart_support_autoescape()==KAL_FALSE)
   {
      byte = DRV_Reg(UART_LCR(UART_BASE));     /* DLAB start */
      DRV_WriteReg(UART_LCR(UART_BASE),(byte | UART_LCR_DLAB));
      
      DRV_WriteReg(UART_DLL(UART_BASE),0xff);
      DRV_WriteReg(UART_DLH(UART_BASE),0xff);
      DRV_WriteReg(UART_LCR(UART_BASE),byte);      /* DLAB End */   
   }      
}   

void U_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config)
{
   kal_uint16   byte;
   kal_uint16   IER;
   kal_uint32   savedMask;
   kal_uint32   UART_BASE = UART_BaseAddr[port];

   savedMask = SaveAndSetIRQMask();
   IER = DRV_Reg(UART_IER(UART_BASE));
   DRV_WriteReg(UART_IER(UART_BASE),UART_IER_ALLOFF);
   RestoreIRQMask(savedMask);

   U_SetBaudRate(port, UART_Config->baud);

   /* Setup N81 */
   byte = DRV_Reg(UART_LCR(UART_BASE));     /* DLAB start */
   byte &= ~UART_DATA_MASK;
   switch(UART_Config->dataBits)
   {
      case len_5:
         byte |= UART_WLS_5;
         break;

      case len_6:
         byte |= UART_WLS_6;
         break;

      case len_7:
         byte |= UART_WLS_7;
         break;

      case len_8:
         byte |= UART_WLS_8;
         break;

      default:
         break;
   }
	byte &= ~UART_STOP_MASK;
   switch(UART_Config->stopBits)
   {
      case sb_1:
         byte |= UART_1_STOP;
         break;

      case sb_2:
         byte |= UART_2_STOP;
         break;

      case sb_1_5:
         byte |= UART_1_5_STOP;
         break;

      default:
         break;
   }

   byte &= ~UART_PARITY_MASK;
   switch(UART_Config->parity)
   {
      case pa_none:
         byte |= UART_NONE_PARITY;
         break;

      case pa_odd:
         byte |= UART_ODD_PARITY;
         break;

      case pa_even:
         byte |= UART_EVEN_PARITY;
         break;

      case pa_space:
         byte |= UART_SPACE_PARITY;
         break;

      default:
         break;
   }
   DRV_WriteReg(UART_LCR(UART_BASE),byte);            /* DLAB End */
   /* flowControl */
   byte = DRV_Reg(UART_LCR(UART_BASE));
   /* DRV_WriteReg(UART_LCR,(byte | UART_LCR_DLAB));   // DLAB start */
   DRV_WriteReg(UART_LCR(UART_BASE),0xbf);            /* Enchance setting */
   switch(UART_Config->flowControl)
   {
      case fc_none:
         DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_ALLOFF);
         break;

      case fc_hw:
#ifdef MT6208
         if (port == uart_port1)
            DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_AutoRTSCTS);
         else
            DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_ALLOFF);
#else /*!MT6208*/
         DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_AutoRTSCTS);
#endif   /*MT6208*/
         break;

      case fc_sw:
         DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_SWFlowCtrlX1);                               
         if(uart_support_autoescape()==KAL_TRUE)
         {  
            /*For META, Dont use auto escape*/ 
				if(stack_query_boot_mode() != FACTORY_BOOT)
				{
					#if (!defined(MT6205B)&&!defined(MT6208)&&!defined(FPGA)) 
               /*For AutoEscape*/
               DRV_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]),0x77);
               DRV_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x1);
               #endif
            }
         }              
         break;

      default:    
         break;
   }
   #ifdef __DMA_UART_VIRTUAL_FIFO__
   if(UART_VFIFO_support[port])
     	DRV_WriteReg(UART_RXDMA(UART_BASE),UART_RXDMA_ON);
   #endif
   /* XON and XOFF characters */
   DRV_WriteReg(UART_XON1(UART_BASE),UART_Config->xonChar);
   DRV_WriteReg(UART_XOFF1(UART_BASE),UART_Config->xoffChar);
   DRV_WriteReg(UART_XON2(UART_BASE),UART_Config->xonChar);
   DRV_WriteReg(UART_XOFF2(UART_BASE),UART_Config->xoffChar);
   DRV_WriteReg(UART_LCR(UART_BASE),byte);         /* DLAB End */
#ifndef __PRODUCTION_RELEASE__
   uart_lcr_save[port] = byte;
#endif   /*__PRODUCTION_RELEASE__*/

   if (UART_Config->DSRCheck)
   {
      if (DRV_Reg(UART1_MSR) & UART_MSR_DSR)
      {
         switch(port)
         {
            case uart_port1:
               DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART1,PDN_UART1);
               break;
            case uart_port2:
               DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART2,PDN_UART2);
               break;
#ifdef __UART3_SUPPORT__
            case uart_port3:
               #if ( (!defined(MT6217)) && (!defined(MT6218B)) )              
               DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);
               #endif
               break;
#endif   /*__UART3_SUPPORT__*/
            default:
               ASSERT(0);
               break;
         }
      }
      else
      {
         switch(port)
         {
            case uart_port1:
               DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART1,PDN_UART1);
               break;
            case uart_port2:
               DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART2,PDN_UART2);
               break;
#ifdef __UART3_SUPPORT__
            case uart_port3:
               #if ( (!defined(MT6217)) && (!defined(MT6218B)) )              
               DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);
               #endif        
               break;
#endif   /*__UART3_SUPPORT__*/
            default:
               ASSERT(0);
               break;
         }
      }
   }
#if 0 /* power down control is moved to UART_TurnOnPower(). */
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/

⌨️ 快捷键说明

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