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

📄 i2c.c

📁 飞利浦lpc2200实验箱关于i2c接口的驱动代码。代码非常详细有注释。
💻 C
📖 第 1 页 / 共 2 页
字号:
        outl(0xffff, I2SCLH);                /* 设置高电平时间 */
        outl(0xffff, I2SCLL);                /* 设置低电平时间 */

        sema_init(&sem, 1);
        sema_init(&irq_sem, 0);
        filp->private_data = (void *)num;
        local_irq_restore(flag);
    }    usage++;
    MOD_INC_USE_COUNT;    return 0;          /* success */} /*********************************************************************************************************
** Function name: i2c_release
** Descriptions:  release device
** Input:inode:   information of device
**       filp:    pointer of file
** Output 0:      OK
**        other:  not OK
** Created by:    Chenmingji
** Created Date:  2005-5-17
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static int i2c_release(struct inode *inode, struct file *filp) {    unsigned long flag;    u32 temp;
    
    MOD_DEC_USE_COUNT;    usage--;
    if (usage == 0)
    {
        local_irq_save(flag);
        temp = inl(PINSEL0);
        temp &= ~(0x0f << 4);
        temp |= PinSel0Save;
        outl(temp, PINSEL0);
        local_irq_restore(flag);
        free_irq(IRQ_I2C, NULL);
    }
    return(0); } /*********************************************************************************************************
** Function name: i2c_ioctl
** Descriptions:  IO control function
** Input:inode:   information of device
**       filp:    pointer of file
**       cmd:     command
**       arg:     additive parameter
** Output 0:      OK
**        other:  not OK
** Created by:    Chenmingji
** Created Date:  2005-5-17
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static int i2c_ioctl(struct inode *inode, struct file *filp,                        unsigned int cmd, unsigned long arg){
    if (_IOC_TYPE(cmd) != I2C_IOC_MAGIC)    {        return -ENOTTY;    }    if (_IOC_NR(cmd) >= I2C_MAXNR)    {        return -ENOTTY;    }    
    switch(cmd)    {        case I2C_SET_CLH:
            if (arg < 4)
            {
                arg = 4;
            }
            outl(arg, I2SCLH);                   /* 设置高电平时间 */
            break;        case I2C_SET_CLL:
            if (arg < 4)
            {
                arg = 4;
            }
            outl(arg, I2SCLL);                   /* 设置低电平时间 */
            break;        default:            return -ENOTTY;            break;    }    return 0;}
/*********************************************************************************************************
** Function name: i2c_irq_handle
** Descriptions:  The top-half interrupt handler
** Input:
** Output none
** Created by:    Chenmingji
** Created Date:  2005-5-17
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static void i2c_irq_handle(int irq, void *dev_id, struct pt_regs *regs){
    unsigned int temp;
        temp = inl(I2STAT);
    switch(temp & 0xf8)
    {
        case  0x08:                             /* 已发送起始条件,与0x10相同处理 */
        case  0x10:                             /* 已发送重复起始条件 */
            outl(I2cAddr, I2DAT);              /* 发送地址 */
            outl(0x28, I2CONCLR);              /* 清除标志 */
            break;
        case  0x18:                             /* 已发送SLA+W,并已接收应答 */
            get_user(temp, (u8 *)I2cBuf);
            outl(temp, I2DAT);
            I2cBuf++;
            I2cNbyte--;
            outl(0x28, I2CONCLR);              /* 清除标志 */
            break;
        case  0x28:                             /* 已发送I2C数据,并接收到应答 */
            if (I2cNbyte > 0)
            {
                get_user(temp, (u8 *)I2cBuf);
                outl(temp, I2DAT);
                outl(0x28, I2CONCLR);           /* 清除标志 */
                I2cBuf++;
                I2cNbyte--;
            }
            else
            {
                outl(0x28, I2CONCLR);           /* 清除标志 */
                outl(1 << 4, I2CONSET);         /* 结束总线 */
                up(&irq_sem);
            }
            break;
        case  0x20:                             /* 已发送SLA+W;已接收非ACK, 与0x48处理相同 */
        case  0x30:                             /* 已发送I2DAT中的数据字节;已接收非ACK, 与0x48处理相同 */
        case  0x48:                             /* 已发送SLA+R;已接收非ACK */
            outl(1 << 4, I2CONSET);             /* 发送停止信号 */
            outl(0x28, I2CONCLR);               /* 清除标志 */
            up(&irq_sem);
            break;
        case  0x38:                             /* 在SLA+R/W或数据字节中丢失仲裁 */
            outl(0x28, I2CONCLR);              /* 清除标志 */
            up(&irq_sem);
            break;
        case  0x40:                             /* 已发送SLA+R;已接收ACK */
            if (I2cNbyte <= 1)
            {
                outl(1 << 2, I2CONCLR);         /* 下次发送非应答信号 */
            }
            else
            {
                outl(1 << 2, I2CONSET);         /* 下次发送应答信号 */
            }
            outl(0x28, I2CONCLR);              /* 清除标志 */
            break;
        case  0x50:                             /* 已接收数据字节;已发送ACK */
            temp = inl(I2DAT);
            put_user(temp, (u8 *)I2cBuf);
                                                /* 接收数据 */
            I2cBuf++;
            I2cNbyte--;
            if (I2cNbyte <= 1)
            {
                outl(1 << 2, I2CONCLR);         /* 下次发送非应答信号 */
            }
            outl(0x28, I2CONCLR);              /* 清除标志 */
            break;
        case  0x58:                             /* 已接收数据字节;已返发送非ACK */
            temp = inl(I2DAT);
            put_user(temp, (u8 *)I2cBuf);
                                                /* 接收数据 */
            I2cNbyte--;
            outl(1 << 4, I2CONSET);             /* 结束总线 */
            outl(0x28, I2CONCLR);               /* 清除标志 */
            up(&irq_sem);
            break;
        default:
            outl(0x28, I2CONCLR);              /* 清除标志 */
            break;
    }
}

/*********************************************************************************************************
** Function name: i2c_init
** Descriptions:  init driver
** Input:none
** Output 0:      OK
**        other:  not OK
** Created by:    Chenmingji
** Created Date:  2005-5-17
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        int i2c_init(void){    int  result;
    
    result = register_chrdev(MAJOR_NR,  DEVICE_NAME,  &i2c_fops);     if (result < 0)    {        printk(KERN_ERR DEVICE_NAME ": Unable to get major %d\n", MAJOR_NR );        return(result);     } 
    if (MAJOR_NR == 0)    {        MAJOR_NR = result; /* dynamic */    }

    printk(KERN_INFO DEVICE_NAME ": init OK\n");    return(0); }/*********************************************************************************************************
** Function name: i2c_cleanup
** Descriptions:  exit driver
** Input:none
** Output none
** Created by:    Chenmingji
** Created Date:  2005-5-17
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        void i2c_cleanup(void){
    unregister_chrdev(MAJOR_NR, DEVICE_NAME);}/***********************************************************************************************************                            End Of File********************************************************************************************************/

⌨️ 快捷键说明

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