Exemple #1
0
// =============================================================================
// 功能:字符终端直接接收函数,采用轮询方式,直接读寄存器,用于stdin初始化前
// 参数:str,发送字符串指针
//      len,发送的字节数
// 返回:0,发生错误;result,发送数据长度,字节单位
// =============================================================================
char Uart_GetCharDirect(void)
{
    u16 CR_Bak;
    char result;

    CR_Bak = PutStrDirectReg->UART_IER;             //Save INT
    __UART_SendIntDisable(PutStrDirectReg,0);       //disable send INT
    __UART_SendIntDisable(PutStrDirectReg,1);       //disable send INT when dma
    while(__UART_RxHadChar(GetCharDirectReg) == false) ;
    result = GetCharDirectReg->UART_RHR;
    PutStrDirectReg->UART_IER = CR_Bak;             //restore send INT
    return result;
}
Exemple #2
0
// =============================================================================
// 功能: 配置uart为DMA方式或配置为非DMA方式时,配置各寄存器,
// 参数:reg,串口寄存器指针
//       cmd,命令号
//       Port,端口号,即串口号
// 返回: 无
// =============================================================================
void __UART_DMA_Config(tagUartReg* Reg,u32 cmd,u32 Port)
{
    //将串口相关的寄存器reset并除能接收和发送
    Reg->UART_CR = ((1<<2)|(1<<3)|(1<<5)|
                (1<<7)|(1<<8));         //接收发送都除能了

    if(cmd == CN_UART_DMA_UNUSED)//不使用DMA
    {
    	s_UART_DmaUsed[Port] = false;

         //关闭非dma时使用的中断,开始dma使用的uart接收中断
         //发送中断只在启动发送时开启
        __UART_RecvIntDisable(Reg, cn_dma_used);
        __UART_SendIntDisable(Reg, cn_dma_used);
        __UART_RecvIntEnable(Reg, cn_dma_unused);
        Reg->UART_PTCR = ((1<<1)|(1<<9));//disable DMA rx tx
        Reg->UART_CR = ((1<<4)|(1<<6));// tx rx enable
    }
    else    //使用DMA
    {
    	s_UART_DmaUsed[Port] = true;

        //关闭非dma时使用的中断,开始dma使用的uart接收中断
        __UART_RecvIntEnable(Reg, cn_dma_used);
        __UART_RecvIntDisable(Reg, cn_dma_unused);
        __UART_SendIntDisable(Reg, cn_dma_unused);

        //配置dma参数
		Reg->UART_TCR   = 0;
		Reg->UART_TNCR  = 0;
        Reg->UART_RCR   = 0;
		Reg->UART_RNCR  = 0;

        __UART_dma_recv_config(Reg,Port,1);

        Reg->UART_PTCR = ((1<<0)|(1<<8));//enable DMA rx tx
        Reg->UART_CR = ((1<<4)|(1<<6));// tx rx enable
    }
}
Exemple #3
0
// =============================================================================
// 功能:字符终端直接发送函数,采用轮询方式,直接写寄存器,用于printk,或者stdout
//       没有初始化
// 参数:str,发送字符串指针
//      len,发送的字节数
// 返回:0,发生错误;result,发送数据长度,字节单位
// =============================================================================
s32 Uart_PutStrDirect(const char *str,u32 len)
{
    u32 result = 0,timeout = TxByteTime * len;
    u16 CR_Bak;

    CR_Bak = PutStrDirectReg->UART_IER;             //Save INT
    __UART_SendIntDisable(PutStrDirectReg,0);       //disable send INT
    __UART_SendIntDisable(PutStrDirectReg,1);       //disable send INT when dma
    for(result=0; result < len+1; result ++)
    {
        // 超时或者发送缓冲为空时退出
        while((false == __UART_TxTranEmpty(PutStrDirectReg))&& (timeout > 10))
        {
            timeout -=10;
            Djy_DelayUs(10);
        }
        if( (timeout <= 10) || (result == len))
            break;
        PutStrDirectReg->UART_THR = str[result];
    }
    PutStrDirectReg->UART_IER = CR_Bak;             //restore send INT
    return result;
}
Exemple #4
0
// =============================================================================
// 功能: 打印函数,直接写串口方式,目前主要由djy_printk独享,用于调试关键代码段
// 参数: 所需要发送的字符串,当然,前提是你提供的一定是字符串'\0'结束
// 返回: 发送的字节个数
// =============================================================================
u32 Uart_SendServiceDirectly(char *str)
{
    u32  result=0,len,timeout=100*mS;
	tagUartReg *Reg;
	u32 BaseAddr,Port;

	if(!strcmp(gc_pCfgStddevName,"UART0") && (sUartInited & (0x01 << CN_UART0)))
	{
		BaseAddr = CN_UART0_BASE;
		Port = CN_UART0;
	}
	else if(!strcmp(gc_pCfgStddevName,"UART1")&& (sUartInited & (0x01 << CN_UART1)))
	{
		BaseAddr = CN_UART1_BASE;
		Port = CN_UART1;
	}
	else if(!strcmp(gc_pCfgStddevName,"USART0")&& (sUartInited & (0x01 << CN_USART0)))
	{
		BaseAddr = CN_USART0_BASE;
		Port = CN_USART0;
	}
	else if(!strcmp(gc_pCfgStddevName,"USART1")&& (sUartInited & (0x01 << CN_USART1)))
	{
		BaseAddr = CN_USART1_BASE;
		Port = CN_USART1;
	}
	else
		return 0;

    len = strlen(str);
    Reg = (tagUartReg *)BaseAddr;

    __UART_SendIntDisable(Reg,s_UART_DmaUsed[Port]);	//disable send INT
    for(result=0; result < len; result ++)
    {
    	// 超时或者发送缓冲为空时退出
        while((false == __UART_TxTranEmpty(Reg))&& (timeout > 0))
        {
            timeout--;
            Djy_DelayUs(1);
        }
        if(timeout == 0)
            break;
        Reg->UART_THR = str[result];
    }
    __UART_SendIntEnable(Reg,s_UART_DmaUsed[Port]);		//enable send INT
    return result;
}
Exemple #5
0
// =============================================================================
// 功能: 串口设备的控制函数,与具体的硬件寄存器设置相关
// 参数: Reg,UART的寄存器基址.
//       cmd,操作类型
//       data,含义依cmd而定
// 返回: 无意义.
// =============================================================================
ptu32_t __UART_Ctrl(tagUartReg *Reg,u32 cmd, u32 data1,u32 data2)
{
	u8 Port;
    switch((u32)Reg)
    {
    case CN_UART0_BASE: Port = CN_UART0;break;
    case CN_UART1_BASE: Port = CN_UART1;break;
    case CN_USART0_BASE: Port = CN_USART0;break;
    case CN_USART1_BASE: Port = CN_USART1;break;
    default:return 0;
    }

    switch(cmd)
    {
        case CN_UART_START:
            __UART_RecvIntEnable(Reg,s_UART_DmaUsed[Port]);
            __UART_SendIntEnable(Reg,s_UART_DmaUsed[Port]);
            break;
        case CN_UART_STOP:
            __UART_RecvIntDisable(Reg,s_UART_DmaUsed[Port]);
            __UART_SendIntDisable(Reg,s_UART_DmaUsed[Port]);
            break;
        case CN_UART_SET_BAUD:  //设置Baud
                __UART_SetBaud(Reg,data1);
            break;
        case CN_UART_RX_PAUSE:      //暂停接收
            __UART_RecvIntEnable(Reg,s_UART_DmaUsed[Port]);
            break;
        case CN_UART_RX_RESUME:      //恢复接收
            __UART_RecvIntDisable(Reg,s_UART_DmaUsed[Port]);
            break;
        case CN_UART_RECV_HARD_LEVEL:    //因为UART没有FIFO,因此配置DMA接收
        	__UART_dma_recv_config(Reg,Port,data1);
            break;
        case CN_UART_HALF_DUPLEX_SEND:
            __UART_half_duplex_send(Port);
            break;
        case CN_UART_HALF_DUPLEX_RECV:
            __UART_half_duplex_recv(Port);
            break;
        case CN_UART_DMA_USED:
        case CN_UART_DMA_UNUSED:
            __UART_DMA_Config(Reg,cmd,Port);
            break;
        default: break;
    }
    return 0;
}
Exemple #6
0
// =============================================================================
// 功能: 使用中断方式效率能够大大提升软件执行效率;包括接收、发送和异常等,接收到数据
//       后,调用通用接口模块,写入软件缓冲区;发送数据时,调用通用接口模块,从软件缓
//       冲区读出数据,写入硬件发送寄存器;此外,根据芯片,可通过DMA方式发送
// 参数: 中断号.
// 返回: 0.
// =============================================================================
uint32_t UART_ISR(ufast_t IntLine)
{
    static struct tagUartCB *UCB;
    tagUartReg *Reg;
    uint32_t timeout = 1000,num;
    uint8_t ch,*puart_dma_send_buf,*puart_dma_recv_buf;
    uint32_t IIR=0,Port,DmaBufLen,DmaRcvLen;

    switch(IntLine)
    {
        case CN_INT_LINE_UART0:
        	Port = CN_UART0;
            UCB = pUartCB[Port];
            Reg =  (tagUartReg *)CN_UART0_BASE;
            DmaBufLen = UART0_DMA_BUF_LEN;
            DmaRcvLen = s_UART0_DmaRcvLen;
            puart_dma_send_buf = (uint8_t*)UART0_DmaSendBuf;
            puart_dma_recv_buf = (uint8_t*)UART0_DmaRecvBuf;
            break;

        case CN_INT_LINE_UART1:
        	Port = CN_UART1;
        	UCB = pUartCB[Port];
            Reg =  (tagUartReg *)CN_UART1_BASE;
            DmaBufLen = UART1_DMA_BUF_LEN;
            DmaRcvLen = &s_UART1_DmaRcvLen;
            puart_dma_send_buf = (uint8_t*)UART1_DmaSendBuf;
            puart_dma_recv_buf = (uint8_t*)UART1_DmaRecvBuf;
            break;

        case CN_INT_LINE_USART0:
        	Port = CN_USART0;
        	UCB = pUartCB[Port];
            Reg =  (tagUartReg *)CN_UART1_BASE;
            DmaBufLen = USART0_DMA_BUF_LEN;
            DmaRcvLen = &s_USART0_DmaRcvLen;
            puart_dma_send_buf = (uint8_t*)USART0_DmaSendBuf;
            puart_dma_recv_buf = (uint8_t*)USART0_DmaRecvBuf;
            break;

        case CN_INT_LINE_USART1:
        	Port = CN_USART1;
        	UCB = pUartCB[Port];
            Reg =  (tagUartReg *)CN_UART1_BASE;
            DmaBufLen = USART1_DMA_BUF_LEN;
            DmaRcvLen = &s_USART1_DmaRcvLen;
            puart_dma_send_buf = (uint8_t*)USART1_DmaSendBuf;
            puart_dma_recv_buf = (uint8_t*)USART1_DmaRecvBuf;
            break;
        default:
            return 0;
    }

    IIR = Reg->UART_SR;

    if(s_UART_DmaUsed[Port] == cn_dma_unused)//非DMA方式发送和接收
    {
        if((IIR & (1<<0)) && (Reg->UART_IMR &(1<<0)))//rxrdy int
        {
            ch = Reg->UART_RHR;
            num = UART_PortWrite(UCB,&ch,1,0);
            if(num != 1)
            {
                UART_ErrHandle(UCB,CN_UART_BUF_OVER_ERR);
            }
        }
        //tx empty int
        if((IIR &(1<<9)) && (Reg->UART_IMR &(1<<9)))
        {
            num = UART_PortRead(UCB,&ch,1,0);
            while((!__UART_TxTranEmpty(Reg)) && (timeout-- > 0));
            if(num != 0)
                Reg->UART_THR = ch;
            else
            {
                __UART_SendIntDisable(Reg,s_UART_DmaUsed[Port]);
            }
        }
    }
    else            //DMA方式发送和接收
    {
        if((IIR & (1<<3)) && (Reg->UART_IMR &(1<<3)))//endrx int
        {
        	if(DmaRcvLen > DmaBufLen)					//计算从DMA BUF中读多少数据
        		num = DmaBufLen;
        	else
        		num = DmaRcvLen;
            UART_PortWrite(UCB,puart_dma_recv_buf,num,0);

            DmaRcvLen = DmaRcvLen - num;
            if(DmaRcvLen > DmaBufLen)					//计算下次DMA接收数据量
            	Reg->UART_RCR  = DmaBufLen;
            else if(DmaRcvLen > 1)
            	Reg->UART_RCR = DmaRcvLen;
            else										//接收DMA最少为1
            {
            	Reg->UART_RCR = 1;
            	DmaRcvLen = 1;
            }

            Reg->UART_RPR = (vu32)puart_dma_recv_buf;
        }
        if((IIR & (1<<11)) && (Reg->UART_IMR &(1<<11)))//txbufe int
        {
        	while(!(Reg->UART_SR & (1<<9)));//wait for empty

            num = UART_PortRead(UCB,puart_dma_send_buf,	DmaBufLen,0);
            if(num > 0)
            {
                Reg->UART_PTCR = (1<<9);//diable dma tx
            	if((Reg->UART_TCR==0)&&(Reg->UART_TNCR==0))
            	{
//                    num = UART_PortRead(UCB,puart_dma_send_buf,
//                    		DmaBufLen,0);
            		Reg->UART_TPR  = (uint32_t)puart_dma_send_buf;
            		Reg->UART_TCR  = num;
            	}
                Reg->UART_PTCR = (1<<8);//enable dma tx
            }
            else
            {
                //是否需禁止 dma tx int
                while(!__UART_TxTranEmpty(Reg));
                __UART_SendIntDisable(Reg,s_UART_DmaUsed[Port]);
            }
        }
    }

    if(IIR &(0xE0)) //其他中断
    {
        UART_ErrHandle(UCB,CN_UART_HARD_COMM_ERR);
    }

    return 0;
}
Exemple #7
0
// =============================================================================
// 功能: 这个是直接写串口函数,不会经过事件弹出
// 参数: Reg,UART的寄存器基址.
//      send_buf,被发送的缓冲数据
//      len,发送的数据字节数
//      timeout,超时时间,微秒
// 返回: 发送的个数
// =============================================================================
u32 __UART_SendDirectly(tagUartReg* Reg,u8 *send_buf,u32 len,u32 timeout)
{
    u32  result,Port;
    switch((u32)Reg)
    {
    //UART0和UART1的FIFO深度为8,而其他的为1
    case CN_UART0_BASE:Port = CN_UART0; break;
    case CN_UART1_BASE:Port = CN_UART1;break;
    case CN_USART0_BASE:Port = CN_USART0;break;
    case CN_USART1_BASE:Port = CN_USART1; break;
    default:return 0;
    }

    __UART_SendIntDisable(Reg,s_UART_DmaUsed[Port]);
//    __UART_half_duplex_send(Port);//硬件使能发送

    if(s_UART_DmaUsed[Port] == false)
    {
        for(result=0; result < len; result ++)
        {
            while((0 == __UART_TxTranEmpty(Reg))
                && (timeout > 0))//超时或者发送缓冲为空时退出
            {
                timeout--;
                Djy_DelayUs(1);
            }
            if(timeout == 0)
                break;
            Reg->UART_THR = send_buf[result];
        }

//        //等待发送完再将485通信转为接收
//        while((0 == __UART_TxTranEmpty(Reg))
//                && (timeout > 0))//超时或者发送缓冲为空时退出
//        {
//            timeout--;
//            Djy_DelayUs(1);
//        }
//        if(timeout == 0)
//            result = 0;
    }
    else
    {
        Reg->UART_PTCR = (1<<9);//disable dma send first
    	if((Reg->UART_TCR==0)&&(Reg->UART_TNCR==0))
    	{
    		Reg->UART_TPR  = (uint32_t)send_buf;
    		Reg->UART_TCR  = len;
    		Reg->UART_PTCR = (1<<8);//dma tx enbale
    	}
    	else
            result = 0;
        //直接发送方式,采用阻塞的DMA发送
        while((!__UART_TxTranEmpty(Reg)) && (timeout > 0))
        {
            timeout--;
            Djy_DelayUs(1);
        }
        if(timeout == 0)
            result = 0;
    }
    __UART_SendIntEnable(Reg,s_UART_DmaUsed[Port]);
//    __UART_half_duplex_recv(Port);//硬件使能接收
    return result;
}