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

📄 i2c-algo-ip3203.c

📁 PNX8550 I2C总线驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        busptr->mode = MasterTransmitter;#ifdef USE_DMA                        {                                int dmalen;                                if( busptr->mst_txbuflen <= div_DmaBufSize )                                {                                        dmalen = busptr->mst_txbuflen;                                }                                else                                {                                        dmalen = div_DmaBufSize;                                }                                dma_start( busptr->mst_txbuf, i2c_adap, dmalen,  MasterTransmitter);                                busptr->mst_txbufindex = dmalen;                        }#endif                }                else                {                        int myaddr = ((busptr->mst_address & 0xFE) | 0x01);dev_dbg(&i2c_adap->dev, "START TRANSMITTED, Read bit set(%x)\n", myaddr);                        write_IP3203_I2CDAT(busptr, myaddr); /* Read bit set */                        busptr->mode = MasterReceiver;                }                STAOUT( busptr, 0 );/* Clear STA flag */                CLEAR_I2C_INTERRUPT( busptr ); /* Reset interrupt */				break;        case 0x18: /* Master Transmitter: SLA+W has been transmitted; ACK has been received */            /* fall through; */        case 0x28: /* Master Transmitter: Data byte in I2DAT has been transmitted; ACK has been received */                if( busptr->mst_txbufindex < busptr->mst_txbuflen )  /* transmit buffer not empty ? */                {                        write_IP3203_I2CDAT(busptr, *( busptr->mst_txbuf + busptr->mst_txbufindex ));                        busptr->mst_txbufindex++;                        STAOUT( busptr, 0 ); /* Don't generate (repeated) START condition */#ifdef USE_DMA                        {                                int dmalen;                                if( ( busptr->mst_txbuflen - busptr->mst_txbufindex ) <= div_DmaBufSize )                                {                                        dmalen = busptr->mst_txbuflen - busptr->mst_txbufindex;                                }                                else                                {                                        dmalen = div_DmaBufSize;                                }                                dma_start( busptr->mst_txbuf + busptr->mst_txbufindex, i2c_adap, dmalen, MasterTransmitter);                                busptr->mst_txbufindex += dmalen;                        }#endif                }                else                {                        if( busptr->mst_rxbufindex < busptr->mst_rxbuflen ) /* if bytes to receive  ? */                        {                                STAOUT( busptr, 1 ); /* Generate repeated START condition */                        }                        else                        {                                STAOUT( busptr, 0 ); /* Don't generate (repeated) START condition */                                STOOUT( busptr, 1 ); /* Generate STOP condition */                                busptr->mode = Idle;                                busptr->isr_event |= evMasterReady;                                wake_up_interruptible(&(busptr->iic_wait_master));                        }                }                CLEAR_I2C_INTERRUPT( busptr ); /* reset interrupt */                break;        case 0x20: /* Master Transmitter: SLA+W has been transmitted; NOT ACK has been received */                dev_dbg(&i2c_adap->dev, "Master Transmitter : SLA+W, NOT ACK has been received\n");                /* fall through; */        case 0x30: /* Master Transmitter: Data byte in I2DAT has been transmitted; NOT ACK has been received */                STAOUT( busptr, 0 ); /* Don't generate (repeated) START condition */                STOOUT( busptr, 1 ); /* Generate STOP condition */                busptr->mode = Idle;                busptr->mst_status = ( i2c_state == 0x20 ) ? errids_IsI2cDeviceError : errids_IsI2cWriteError;                busptr->isr_event |= evMasterReady;                CLEAR_I2C_INTERRUPT( busptr ); /* Reset interrupt */                wake_up_interruptible(&(busptr->iic_wait_master));                break;        case 0x38: /* Arbitration lost in SLA+R/~W or Data bytes */                busptr->mode = Idle;                STAOUT( busptr, 1 ); /* Retry the master operation */                busptr->mst_txbufindex = 0;                busptr->mst_rxbufindex = 0;                AAOUT( busptr, busptr->slv_enabled ); /* ACK bit will be returned, or not, after slave address reception */                CLEAR_I2C_INTERRUPT( busptr ); /* Reset interrupt */                break;        case 0x68: /* Arbitration lost in SLA+R/~W as master; Own SLA+W has been received, ACK has been returned */                STAOUT( busptr, 1 ); /* Retry the master operation */                busptr->mst_txbufindex = 0;                busptr->mst_rxbufindex = 0;                busptr->slv_bufindex = 1; /* reset buffer pointer !!! */                AAOUT( busptr, busptr->slv_enabled ); /* ACK bit will be returned, or not, after next byte reception */                busptr->mode = SlaveReceiver;//                Todo : Start timeout timer in tasklet//                slave_device = i2c_adap;//                tasklet_schedule(&IP3203_slave_tasklet);                CLEAR_I2C_INTERRUPT(busptr); /* Don't reset i2c interrupt */                break;        case 0xB0: /* Arbitration lost in SLA+R/~W as master; Own SLA+R has been received, ACK has been returned */                STAOUT( busptr, 1 ); /* Retry the master operation */                busptr->mst_txbufindex = 0;                busptr->mst_rxbufindex = 0;                busptr->mode = SlaveTransmitter;                busptr->isr_event |= evSlaveReadRequest;                slave_device = i2c_adap;                tasklet_schedule(&IP3203_slave_tasklet);                /* Don't reset i2c interrupt */                break;        case 0x70: /* General call address (0x00) has been received; ACK has been returned */                /* fall through; */        case 0x78: /* Arbitration lost in SLA+R/~W as master; General call address (0x00) has been received; ACK has been returned */                /* fall through; */        default:                recover_from_hardware_error( i2c_adap );                break;		}}static __inline void iic_interrupt_master_receiver(struct i2c_adapter * i2c_adap, struct I2cBusObject * busptr, int i2c_state){        switch(i2c_state)		{		/* 0x10 : A repeated START should not occur when in MasterReceiver mode in this implementation */        case 0x38: /* Arbitration lost in NOT ACK bit */                busptr->mode = Idle;                STAOUT( busptr, 1 ); /* Retry the master operation */                busptr->mst_txbufindex = 0;                busptr->mst_rxbufindex = 0;                AAOUT( busptr, busptr->slv_enabled); /* ACK bit will be returned, or not, after slave address reception */                CLEAR_I2C_INTERRUPT( busptr ); /* Reset interrupt */                break;        case 0x50: /* Data byte has been received; ACK has been returned */                if ( busptr->mst_rxbufindex < busptr->mst_rxbuflen ) /* bytes to receive ? */                {                        *( busptr->mst_rxbuf + busptr->mst_rxbufindex++ ) = read_IP3203_I2CDAT(busptr);                }                else                {                        (void)read_IP3203_I2CDAT(busptr); /* Ignore received byte, no storage space available */                }                /* fall through; */        case 0x40: /* SLA+R has been transmitted; ACK has been received */#ifdef USE_DMA                {                    int dmalen;                    if( ( busptr->mst_rxbuflen - 1 - busptr->mst_rxbufindex ) <= div_DmaBufSize )                    {                            dmalen = busptr->mst_rxbuflen -1 - busptr->mst_rxbufindex;                    }                    else                    {                            dmalen = div_DmaBufSize;                    }                    if( ( dmalen > 1 ) && /* Bug in N1 can not ask DMA to receive 1 byte */                        ( busptr->mst_rxbufindex + dmalen <= div_DmaBufSize ) ) /* Bug in N1, second DMA transfer response is different */                    {                            dma_start( busptr->mst_rxbuf + busptr->mst_rxbufindex, i2c_adap, dmalen, MasterReceiver );                            busptr->mst_rxbufindex += (dmalen - 1); /* Last byte should be read by the ISR */                    }                }#endif                if ( busptr->mst_rxbufindex < ( busptr->mst_rxbuflen - 1 ) )                {                        AAOUT( busptr, 1 ); /* ACK bit will be returned after byte reception */                }                else                {                        AAOUT( busptr, 0 ); /* NOT ACK bit will be returned after (last) byte reception */                }                STAOUT( busptr, 0 ); /* Don't generate (repeated) START condition */                CLEAR_I2C_INTERRUPT( busptr ); /* reset interrupt */                break;        case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */                STAOUT( busptr, 0 ); /* Don't generate (repeated) START condition */                STOOUT( busptr, 1 ); /* Generate STOP condition */                busptr->mode = Idle;                busptr->mst_status = errids_IsI2cDeviceError;                busptr->isr_event |= evMasterReady;                wake_up_interruptible(&(busptr->iic_wait_master));                CLEAR_I2C_INTERRUPT( busptr ); /* reset interrupt */                break;            case 0x58: /* Data byte has been received; NOT ACK has been returned */                if ( busptr->mst_rxbufindex < busptr->mst_rxbuflen ) /* bytes to receive ? */                {               	    *( busptr->mst_rxbuf + busptr->mst_rxbufindex++ ) = read_IP3203_I2CDAT(busptr);                     dev_dbg(&i2c_adap->dev, "received byte %x\n", *(busptr->mst_rxbuf + busptr->mst_rxbufindex -1));                }                else                {                    (void)read_IP3203_I2CDAT(busptr);  /* Ignore received byte, no storage space available */                    dev_dbg(&i2c_adap->dev, "ignore received byte\n");                }                AAOUT( busptr, busptr->slv_enabled ); /* ACK bit will be returned, or not, after slave address reception */                STAOUT( busptr, 0 ); /* Don't generate (repeated) START condition */                STOOUT( busptr, 1 ); /* Generate STOP condition */                busptr->mode = Idle;                busptr->isr_event |= evMasterReady;                CLEAR_I2C_INTERRUPT( busptr ); /* reset interrupt */                wake_up_interruptible(&(busptr->iic_wait_master));                break;        case 0x68: /* Arbitration lost in SLA+R/~W as master; Own SLA+W has been received, ACK has been returned */                STAOUT( busptr, 1 ); /* Retry the master operation */                busptr->mst_txbufindex = 0;                busptr->mst_rxbufindex = 0;                busptr->slv_bufindex = 1; /* reset buffer pointer !!! */                AAOUT( busptr, busptr->slv_enabled ); /* ACK bit will be returned, or not, after next byte reception */                busptr->mode = SlaveReceiver;//                Todo : Start timeout timer in tasklet//                tasklet_schedule(&IP3203_slave_tasklet);                CLEAR_I2C_INTERRUPT(busptr); /* Don't reset i2c interrupt */                break;        case 0xB0: /* Arbitration lost in SLA+R/~W as master; Own SLA+R has been received, ACK has been returned */                STAOUT( busptr, 1 ); /* Retry the master operation */                busptr->mst_txbufindex = 0;                busptr->mst_rxbufindex = 0;                busptr->mode = SlaveReceiver;                busptr->isr_event |= evSlaveReadRequest;                slave_device = i2c_adap;                tasklet_schedule(&IP3203_slave_tasklet);                /* Don't reset i2c interrupt */                break;        case 0x70: /* General call address (0x00) has been received; ACK has been returned */                /* fall through; */        case 0x78: /* Arbitration lost in SLA+R/~W as master; General call address (0x00) has been received; ACK has been returned */                /* fall through; */        default:				recover_from_hardware_error( i2c_adap );				break;		}}static __inline void iic_interrupt_slave_receiver(struct i2c_adapter * i2c_adap, struct I2cBusObject * busptr, int i2c_state){        switch (i2c_state)		{        case 0x80: /* Previously addressed with own SLA; DATA byte has been received; ACK has been returned */                if( busptr->slv_bufindex < busptr->slv_bufsize )                {                        *( busptr->slv_buf + busptr->slv_bufindex++ ) = read_IP3203_I2CDAT(busptr);                }                else                {                        (void)read_IP3203_I2CDAT(busptr); /* Ignore received byte, no storage space available */                }                AAOUT( busptr, busptr->slv_enabled ); /* ACK bit will be returned, or not, after next byte reception */                if( busptr->slv_bufindex < busptr->slv_bufsize )                {#if 0 // USE_DMA                        int dmalen;                        {                                if( ( busptr->slv_bufsize - busptr->slv_bufindex ) >  div_DmaBufSize )                                {                                        dmalen = div_DmaBufSize;                                }                                else                                {                                        dmalen = busptr->slv_bufsize - busptr->slv_bufindex;                                }                                dma_start( busptr->slv_buf + busptr->slv_bufindex, i2c_adap, dmalen, SlaveReceiver );                                busptr->slv_bufindex += dmalen;/* Any number of bytes might be received */                        }#endif                }                CLEAR_I2C_INTERRUPT( busptr );  /* Reset i2c interrupt */				break;        case 0x88: /* Previously addressed with own SLA; DATA byte has been received; NOT ACK has been returned */                if ( busptr->slv_bufindex < busptr->slv_bufsize )                {                        *( busptr->slv_buf + busptr->slv_bufindex++ ) = read_IP3203_I2CDAT(busptr);// I2CDATIN( busptr );                }                else                {                        (void)read_IP3203_I2CDAT(busptr); // I2CDATIN( busptr ); /* Ignore received byte, no storage space available */                }                AAOUT( busptr, busptr->slv_enabled ); /* ACK bit will be returned, or not, after slave address reception */                CLEAR_I2C_INTERRUPT( busptr );    /* reset i2c interrupt */				break;        case 0xA0: /* A STOP condition or repeated START has been received while still address as SLV/REC or SLV/TRX */				// Slave will be enabled again when data is out of the buffer                AAOUT( busptr, 0 ); /* NOT ACK bit will be returned after slave address reception */                busptr->isr_event |= evSlaveStopCondition;                slave_device = i2c_adap;                tasklet_schedule(&IP3203_slave_tasklet);                CLEAR_I2C_INTERRUPT( busptr );   /* Reset i2c interrupt */				break;        case 0x70: /* General call address (0x00) has been received; ACK has been returned */                /* fall through; */        case 0x78: /* Arbitration lost in SLA+R/~W as master; General call address (0x00) has been received; ACK has been returned */

⌨️ 快捷键说明

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