Ejemplo n.º 1
0
// =============================================================================
// 功能: 启动串口发送,其目的是触发中断,用中断方式发送数据。
// 参数: PrivateTag,被操作的串口设备指针数值.
// 返回: 发送的个数
// =============================================================================
static u32 __UART_SendStart (tagUartReg *Reg,u32 timeout)
{
    u8 fifodep=1,num,ch[8],port;

    switch((u32)Reg)
    {
    //UART0和UART1的FIFO深度为8,而其他的为1
    case CN_UART0_BASE:   port = CN_UART0;   fifodep = 8;  break;
    case CN_UART1_BASE:   port = CN_UART1;   fifodep = 8;  break;
    case CN_UART2_BASE:   port = CN_UART2;   break;
    case CN_UART3_BASE:   port = CN_UART3;   break;
    case CN_UART4_BASE:   port = CN_UART4;   break;
    case CN_UART5_BASE:   port = CN_UART5;   break;
    default:return 0;
    }

    __UART_TxIntDisable(Reg);
    if(__UART_TxTranEmpty(Reg))
    {
        fifodep = UART_PortRead(pUartCB[port],ch,fifodep,0);// UART的FIFO大小为8字节
        for(num = 0; num < fifodep; num++)
        {
            Reg->D = ch[num];
        }
    }
    __UART_TxIntEnable(Reg);
    return num;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 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 = GetCharDirectReg->C2;                          //Save INT
    __UART_TxIntDisable(GetCharDirectReg);                  //disable send INT
    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->D = str[result];
    }
    PutStrDirectReg->C2 = CR_Bak;                         //restore send INT
    return result;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}