case STATE_READ:
{
PRINTK("STATE_READ\n");
/* 读出数据 */
s3c2440_i2c_xfer_data.msgs->buf[s3c2440_i2c_xfer_data.cur_ptr] = s3c2440_i2c_regs->iicds;
s3c2440_i2c_xfer_data.cur_ptr++;
next_read:
if (!isEndData()) /* 如果数据没读写, 继续发起读操作 */
{
if (isLastData()) /* 如果即将读的数据是最后一个, 不发ack */
{
s3c2440_i2c_regs->iiccon = 0x2f; // 恢复I2C传输,接收到下一数据时无ACK
}
else
{
s3c2440_i2c_regs->iiccon = 0xaf; // 恢复I2C传输,接收到下一数据时发出ACK
}
break;
}
else if (!isLastMsg())
{
/* 开始处理下一个消息 */
s3c2440_i2c_xfer_data.msgs++;
s3c2440_i2c_xfer_data.cur_msg++;
s3c2440_i2c_xfer_data.cur_ptr = 0;
s3c2440_i2c_xfer_data.state = STATE_START;
/* 发出START信号和发出设备地址 */
s3c2440_i2c_start();
break;
}
else
{
/* 是最后一个消息的最后一个数据 */
s3c2440_i2c_stop(0);
break;
}
break;
}
default: break;
}
/* 清中断 */
s3c2440_i2c_regs->iiccon &= ~(S3C2410_IICCON_IRQPEND);
return IRQ_HANDLED;
}
/*
* I2C初始化
*/
static void s3c2440_i2c_init(void)
{
struct clk *clk;
clk = clk_get(NULL, "i2c");
clk_enable(clk);
// 选择引脚功能:GPE15:IICSDA, GPE14:IICSCL
s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
/* bit[7] = 1, 使能ACK
* bit[6] = 0, IICCLK = PCLK/16
* bit[5] = 1, 使能中断
* bit[3:0] = 0xf, Tx clock = IICCLK/16
* PCLK = 50MHz, IICCLK = 3.125MHz, Tx Clock = 0.195MHz
*/
s3c2440_i2c_regs->iiccon = (1<<7) | (0<<6) | (1<<5) | (0xf); // 0xaf