Exemple #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;
}
Exemple #2
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 #3
0
// =============================================================================
// 功能: UART的中断服务函数,包括发送空、接收、错误三种中断。
//      1.接收中断,从接收FIFO中读数据,并调用UART_PortWrite写入接收缓冲区中;
//      2.发送中断,调用UART_PortRead读发送缓冲区中数据,并写入发送FIFO;
//      3.错误中断,弹出错误事件
// 参数: 中断线号.
// 返回: 0.
// =============================================================================
static u32 UART_ISR(ptu32_t IntLine)
{
    struct UartCB *UCB;
    volatile tagUartReg *Reg;
    u32 i,fifodep=1,num=0;
    u8 ch[16];

    switch(IntLine)
    {
    case CN_INT_LINE_UART0_RX_TX:
    case CN_INT_LINE_UART0_ERR:
        UCB = pUartCB[CN_UART0];
        Reg = tg_UART_Reg[CN_UART0];
        fifodep = 8;
        break;
    case CN_INT_LINE_UART1_RX_TX:
    case CN_INT_LINE_UART1_ERR:
        UCB = pUartCB[CN_UART1];
        Reg = tg_UART_Reg[CN_UART1];
        fifodep = 8;
        break;
    case CN_INT_LINE_UART2_RX_TX:
    case CN_INT_LINE_UART2_ERR:
        UCB = pUartCB[CN_UART2];
        Reg = tg_UART_Reg[CN_UART2];
        break;
    case CN_INT_LINE_UART3_RX_TX:
    case CN_INT_LINE_UART3_ERR:
        UCB = pUartCB[CN_UART3];
        Reg = tg_UART_Reg[CN_UART3];
        break;
    case CN_INT_LINE_UART4_RX_TX:
    case CN_INT_LINE_UART4_ERR:
        UCB = pUartCB[CN_UART4];
        Reg = tg_UART_Reg[CN_UART4];
        break;
    case CN_INT_LINE_UART5_RX_TX:
    case CN_INT_LINE_UART5_ERR:
        UCB = pUartCB[CN_UART5];
        Reg = tg_UART_Reg[CN_UART5];
        break;
    default:return 0;
    }

    if(Reg->S1 & UART_S1_RDRF_MASK)         //接收中断标志
    {
        for(num = 0; num < fifodep; num++)
        {
            if(!(Reg->SFIFO & UART_SFIFO_RXEMPT_MASK))
                ch[num] = Reg->D;
            else
                break;
        }
        UART_PortWrite(UCB,ch,num,0);
    }

    if(Reg->S1 & UART_S1_TDRE_MASK)         //发送中断标志
    {
        num = UART_PortRead(UCB,ch,fifodep,0);
        if(num>0)
        {
            for(i = 0; i < num; i++)
                Reg->D = ch[i++];
        }
        else
        {
            __UART_TxIntDisable(Reg);
        }
    }

    if(Reg->S1 & (UART_S1_FE_MASK | UART_S1_PF_MASK))   //硬件错误
    {
        UART_ErrHandle(UCB,CN_UART_HARD_COMM_ERR);
    }

    return 0;
}