在线时间0 小时
UID376178
注册时间2012-7-31
NXP金币0
该用户从未签到
新手上路

- 积分
- 15
- 最后登录
- 1970-1-1
|
28平台通过I2C总线连接收音机模块,正常情况下系统运行的好好的,如果通过压力测试,就是不断的通过I2C去读写收音机模块,持续时间5~10分钟。偶尔就会产生中断异常现象。I2C使用的是PIO queue mode。I2C中中断子程序的代码如下:
#define I2C_IRQ_MASK 0x000000FF
static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
{
struct mxs_i2c_dev *mxs_i2c = dev_id;
u32 stat;
u32 done_mask =
BM_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ | BM_I2C_CTRL1_BUS_FREE_IRQ;
stat = __raw_readl(mxs_i2c->regbase + HW_I2C_CTRL1) & I2C_IRQ_MASK;
if (!stat)
return IRQ_NONE;
if (stat & BM_I2C_CTRL1_NO_SLAVE_ACK_IRQ) {
mxs_i2c->cmd_err = -EREMOTEIO;
__raw_writel(BM_I2C_CTRL1_CLR_GOT_A_NAK,
mxs_i2c->regbase + HW_I2C_CTRL1_SET);
hw_i2c_dmachan_reset(mxs_i2c);
mxs_reset_block((void __iomem *)mxs_i2c->regbase, 0);
/* Will catch all error (IRQ mask) */
__raw_writel(0x0000FF00, mxs_i2c->regbase + HW_I2C_CTRL1_SET);
if (mxs_i2c->flags & MXS_I2C_PIOQUEUE_MODE)
__raw_writel(0x04, mxs_i2c->regbase + HW_I2C_QUEUECTRL_SET);
complete(&mxs_i2c->cmd_complete);
goto done;
}
/* Don't care about BM_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ */
if (stat & (BM_I2C_CTRL1_EARLY_TERM_IRQ |
BM_I2C_CTRL1_MASTER_LOSS_IRQ |
BM_I2C_CTRL1_SLAVE_STOP_IRQ | BM_I2C_CTRL1_SLAVE_IRQ)) {
mxs_i2c->cmd_err = -EIO;
complete(&mxs_i2c->cmd_complete);
goto done;
}
if ((stat & done_mask) == done_mask)
complete(&mxs_i2c->cmd_complete);
done:
__raw_writel(stat, mxs_i2c->regbase + HW_I2C_CTRL1_CLR);
return IRQ_HANDLED;}
正常情况下完成一个读写送出的中断应该是 BM_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ | BM_I2C_CTRL1_BUS_FREE_IRQ;
偶尔只出现 BM_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ 中断,而没有后面的那个中断,不知道为什么。
这种情况在cpu繁忙的时候频率明显提高。如果继续运行,最多达到6小时后系统就会复位,这个复位是看门狗复位的。如果把看门狗关掉,系统就挂在那边,串口没有响应,系统也没有响应,通过测试发现系统时钟中断也已无法产生。各位大侠分析下是什么原因导致的。
有必要说明下I2C总线的上拉电阻本来是10K,后来改成5K,感觉出现的概率加大了。但是datasheet里面建议2K。感觉太低。
同样挂在I2C上面的RTC时钟,频繁操作12个小时不会产生问题
|
|