Exemplo n.º 1
0
// =============================================================================
// 功能:IIC接收与发送中断服务函数。该函数实现的功能如下:
//       1.每发送与接收一个或若干字节发生一次中断;
//       2.若有多个中断使用同一个中断号,则需根据具体情况区分使用的是哪个中断;
//       3.清中断标志,并判断ACK信号,每读写字节,计数器都需相应修改;
//       4.接收达到倒数第一个字节时,需配置不发送ACK信号;
//       5.接收或发送完成时,需post信号量IntParam->pDrvPostSemp;
//       6.接收或发送完成时,需产生停止时序。
// 参数:i2c_int_line,中断号,本函数没用到
// 返回:无意义
// =============================================================================
static u32 __IIC_ISR(ufast_t i2c_int_line)
{

    static struct tagIIC_IntParamSet *IntParam;
    static struct tagIIC_CB *ICB;
    tagI2CReg *reg;
    u8 ch;
    u32 IicErrorNo;
    u32 irptl_temp=*rTWIIRPTL;//read IRPTL

    reg = (tagI2CReg*)CN_IIC_REGISTER_BADDR0;
    ICB=&s_IIC0_CB;
    IntParam=&IntParamset0;

        //MASTER TX\RX COMPLETE
        if( (irptl_temp & TWITXINT) != 0 )      //发送中断
        {
            if(!(CHKBIT(reg->rTWIMSTAT, TWIANAK)|CHKBIT(reg->rTWIMSTAT, TWIDNAK)))
            {
                //从泛设备读一个字节的数据,并发送
                if(IIC_PortRead(ICB,&ch,1) > 0)
                {
                    *rTXTWI8 = ch;
                    IntParam->TransCount++;
                }
                else if(IntParam->TransCount == IntParam->TransTotalLen)
                {
                    //in Master TX Mode , we need to STOP TWI by ourself
                    Lock_SempPost(IntParam->pDrvPostSemp);
                     __IIC_GenerateStop(reg);
                }
                else
                {
                 IicErrorNo = CN_IIC_NO_ACK_ERR;//调用错处处理API函数
                 IIC_ErrPop(ICB,IicErrorNo);
                }
            }
            else    //TX no ACK
            {
                IicErrorNo = CN_IIC_NO_ACK_ERR;//调用错处处理API函数
                IIC_ErrPop(ICB,IicErrorNo);
                return 1;
            }
            //clear IIC interrupt
            irptl_temp = TWITXINT;
            *rTWIIRPTL = irptl_temp;
        }
        else if( (irptl_temp & TWIRXINT) != 0 )      //接收中断
        {
            if(!(CHKBIT(reg->rTWIMSTAT, TWIANAK)|CHKBIT(reg->rTWIMSTAT, TWIDNAK)))
            {
                ch = *rRXTWI8;
                IIC_PortWrite(ICB,&ch,1);
                IntParam->TransCount ++;
                if(IntParam->TransCount == IntParam->TransTotalLen)
                {
                    __IIC_GenerateStop(reg);
                    Lock_SempPost(IntParam->pDrvPostSemp);//释放总线信号量
                }
            }

            else    //RX no ACK
            {

            }
            //clear IIC interrupt
            irptl_temp = TWIRXINT;
            *rTWIIRPTL = irptl_temp;
        }
        else    //TWIMERR
        {
        }

    irptl_temp==*rTWIIRPTL; //update TWI_IRPTL

        //MASTER TRANS COMPLETE
        if( (irptl_temp & TWIMCOM) != 0 )
        {
            _IIC_GenerateDisable(reg);

            Lock_SempPost(ICB->iic_bus_semp);//释放总线信号量

            //clear STOP
            CLRBIT(reg->rTWIMCTL, TWISTOP);
            //clear IIC interrupt
            irptl_temp |= TWIMCOM;
            *rTWIIRPTL = irptl_temp;
        }

    return 0;
}
Exemplo n.º 2
0
// =============================================================================
// 功能:        IIC接收与发送中断服务函数。该函数实现的功能如下:
//       1.每发送与接收一个或若干字节发生一次中断;
//       2.若有多个中断使用同一个中断号,则需根据具体情况区分使用的是哪个中断;
//       3.清中断标志,并判断ACK信号,每读写字节,计数器都需相应修改;
//       4.接收达到倒数第一个字节时,需配置不发送ACK信号;
//       5.接收或发送完成时,需post信号量IntParam->pDrvPostSemp;
//       6.接收或发送完成时,需产生停止时序。
// 参数:i2c_int_line,中断号,本函数没用到
// 返回:true falst
// =============================================================================
static u32 __IIC_ISR(ufast_t i2c_int_line)
{
    static struct IIC_CB *ICB;
    static struct IIC_IntParamSet *IntParam;
    tagI2CReg *reg;
    u8 ch;
    u32 IicErrorNo;
    switch (i2c_int_line)
    {
        case CN_INT_LINE_I2C1_EV:
                reg = (tagI2CReg*)CN_IIC1_BASE;
                ICB = &s_IIC1_CB;
                IntParam = &IntParamset0;
                break;
        case CN_INT_LINE_I2C2_EV:
                reg = (tagI2CReg*)CN_IIC2_BASE;
                ICB = &s_IIC2_CB;
                IntParam = &IntParamset1;
                break;
        default:
                return false;
    }

    if(reg->SR1 & I2C_SR1_BTF_MASK)        //已经启动传输
    {
        if(reg->SR1 & I2C_SR1_TxE_MASK)      //发送中断
        {
            if(!(reg->SR1 & I2C_SR1_RxNE_MASK))
            {
                //从发送缓冲区读一个字节的数据,并发送
                if(IIC_PortRead(ICB,&ch,1) > 0)
                {
                    reg->DR = ch;
                    IntParam->TransCount ++;;
                }
                else if(IntParam->TransCount == IntParam->TransTotalLen)
                {
                  Lock_SempPost(IntParam->pDrvPostSemp);
                  __IIC_IntDisable(reg);//关中断
                  __IIC_GenerateStop(reg);
                }
            }
            else                        //未收到ACK信号
            {
                IicErrorNo = CN_IIC_POP_NO_ACK_ERR;//调用错处处理API函数
                IIC_ErrPop(ICB,IicErrorNo);
                return 1;
            }
        }
        else                            //接收中断
        {
            while((IntParam->TransCount < IntParam->TransTotalLen))
            {
                // 最后一个字节master不发ACK,表示读操作终止
                if(IntParam->TransCount == IntParam->TransTotalLen - 1)
                {
                    reg->CR1 &=~ I2C_CR1_ACK_MASK;
                }
                while (!(reg->SR1 & I2C_SR1_RxNE_MASK));//等待接收完成
                    ch = reg->DR;
                //写数据
                IIC_PortWrite(ICB,&ch,1);
                IntParam->TransCount ++;
            }
            if((IntParam->TransCount == IntParam->TransTotalLen)  &&
                                        (reg->SR1 & I2C_SR1_BTF_MASK))
            {
                __IIC_GenerateStop(reg);
                __IIC_IntDisable(reg);//关中断
                Lock_SempPost(IntParam->pDrvPostSemp);//释放总线信号量
            }
        }
    }
    else//未启动通信
    {
        if(reg->SR1 & I2C_SR1_ARLO_MASK)//仲裁丢失中断
        {
            reg->SR1 &= ~I2C_SR1_ARLO_MASK;//清除仲裁丢失中断标志位
            IicErrorNo = CN_IIC_POP_MAL_LOST_ERR;
            IIC_ErrPop(ICB,IicErrorNo);
        }
    }

    return true;
}