title: iic框架

tags: ARM

date: 2018-11-05 13:44:58

i2c框架

寄存器

/* 配置引脚用于I2C*/
GPECON &= ~((3<<28) | (3<<30));
GPECON |= ((2<<28) | (2<<30)); /* 设置时钟 */
/* [7] : IIC-bus acknowledge enable bit, 1-enable in rx mode
* [6] : 时钟源, 0: IICCLK = fPCLK /16; 1: IICCLK = fPCLK /512
* [5] : 1-enable interrupt
* [4] : 读出为1时表示中断发生了, 写入0来清除并恢复I2C操作
* [3:0] : Tx clock = IICCLK/(IICCON[3:0]+1).
* Tx Clock = 100khz = 50Mhz/16/(IICCON[3:0]+1)
*/
IICCON = (1<<7) | (0<<6) | (1<<5) | (30<<0);

中断配置: IIC没有次中断源.直接配置INTMSK即可INTMSK &= ~(1<<27);

主机发送

int do_master_tx(p_i2c_msg msg)
{
p_cur_msg = msg; msg->cnt_transferred = -1;
msg->err = 0; /* 设置寄存器启动传输 */
/* 1. 配置为 master tx mode */
IICCON |= (1<<7); /* TX mode, 在ACK周期释放SDA */
IICSTAT = (1<<4); /* 2. 把从设备地址写入IICDS */
IICDS = msg->addr<<1; /* 3. IICSTAT = 0xf0 , 数据即被发送出去, 将导致中断产生 */
IICSTAT = 0xf0; /* 后续的传输由中断驱动 */ /* 循环等待中断处理完毕 */
while (!msg->err && msg->cnt_transferred != msg->len); if (msg->err)
return -1;
else
return 0;
}

主机接收

int do_master_rx(p_i2c_msg msg)
{
p_cur_msg = msg; msg->cnt_transferred = -1;
msg->err = 0; /* 设置寄存器启动传输 */
/* 1. 配置为 Master Rx mode */
IICCON |= (1<<7); /* RX mode, 在ACK周期回应ACK */
IICSTAT = (1<<4); /* 2. 把从设备地址写入IICDS */
IICDS = (msg->addr<<1)|(1<<0); /* 3. IICSTAT = 0xb0 , 从设备地址即被发送出去, 将导致中断产生 */
IICSTAT = 0xb0; /* 后续的传输由中断驱动 */ /* 循环等待中断处理完毕 */
while (!msg->err && msg->cnt_transferred != msg->len); if (msg->err)
return -1;
else
return 0;
}

中断处理

注意

  1. 连续读的最后一个字节不响应ack,以用来终止读.
  2. 在读写第一个字节的时候,判断是否有ack来判断是否设备存在

if (p_cur_msg->flags == 0)	/* write */
{
/* 对于第1个中断, 它是发送出设备地址后产生的
* 需要判断是否有ACK
* 有ACK : 设备存在
* 无ACK : 无设备, 出错, 直接结束传输
*/
if (p_cur_msg->cnt_transferred == 0) /* 第1次中断 */
{
if (iicstat & (1<<0))
{ /* no ack */
/* 停止传输 */
IICSTAT = 0xd0;
IICCON &= ~(1<<4);//挂起标志
p_cur_msg->err = -1;
printf("tx err, no ack\n\r");
delay(1000);
return;
}
} if (p_cur_msg->cnt_transferred < p_cur_msg->len)
{
/* 对于其他中断, 要继续发送下一个数据
*/
IICDS = p_cur_msg->buf[p_cur_msg->cnt_transferred];
IICCON &= ~(1<<4);//挂起标志
}
else
{
/* 停止传输 */
IICSTAT = 0xd0;
IICCON &= ~(1<<4);//挂起标志
delay(1000);
}
}

/* 对于第1个中断, 它是发送出设备地址后产生的
* 需要判断是否有ACK
* 有ACK : 设备存在, 恢复I2C传输, 这样在下一个中断才可以得到第1个数据
* 无ACK : 无设备, 出错, 直接结束传输
*/
if (p_cur_msg->cnt_transferred == 0) /* 第1次中断 */
{
if (iicstat & (1<<0))
{ /* no ack */
/* 停止传输 */
IICSTAT = 0x90;
IICCON &= ~(1<<4);
p_cur_msg->err = -1;
printf("rx err, no ack\n\r");
delay(1000);
return;
}
else /* ack */
{
/* 如果是最后一个数据, 启动传输时要设置为不回应ACK */
/* 恢复I2C传输 */
if (isLastData())
{
resume_iic_without_ack();
}
else
{
resume_iic_with_ack();
}
return;
}
} /* 非第1个中断, 表示得到了一个新数据
* 从IICDS读出、保存
*/
if (p_cur_msg->cnt_transferred < p_cur_msg->len)
{
index = p_cur_msg->cnt_transferred - 1;
p_cur_msg->buf[index] = IICDS; /* 如果是最后一个数据, 启动传输时要设置为不回应ACK */
/* 恢复I2C传输 */
if (isLastData())
{
resume_iic_without_ack();
}
else
{
resume_iic_with_ack();
}
}
else
{
/* 发出停止信号 */
IICSTAT = 0x90;
IICCON &= ~(1<<4);//清标志
delay(1000);
}

程序框架

i2c框架的更多相关文章

  1. (1)I2c的简介和特性

    I2C我是想全面深入的从嵌入式软件工程师的角度做个理解,刚刚还申请了一个专栏,这个好好写.         学习技术从外文文档看起-- 要全面了解I2C,可以从<I2C-bus specific ...

  2. linux设备驱动程序-i2c(2)-adapter和设备树的解析

    linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 在本系列linux内核i2c框架的前两篇,分别讲 ...

  3. linux设备驱动程序-i2c(0)-i2c设备驱动源码实现

    (基于4.14内核版本) 为了梳理清楚linux内核中的i2c实现框架,从本文开始,博主将分几个章节分别解析i2c总线在linux内核中的形成过程.匹配过程.以及设备驱动程序源码实现. 在介绍linu ...

  4. linux设备驱动程序-i2c(1):i2c总线的添加与实现

    linux设备驱动程序-i2c(1):i2c总线的添加与实现 (基于4.14内核版本) 在上一章节linux设备驱动程序-i2c(0)-i2c设备驱动源码实现中,我们演示了i2c设备驱动程序的源码实现 ...

  5. linux设备驱动程序--串行通信驱动框架分析

    linux 串行通信接口驱动框架 在学习linux内核驱动时,不论是看linux相关的书籍,又或者是直接看linux的源码,总是能在linux中看到各种各样的框架,linux内核极其庞杂,linux各 ...

  6. 十四、i2c子系统

    由于之后的触摸屏驱动分析中使用到了GPIO子系统和i2c子系统,因此在分析触摸屏驱动之前我准备把这两个子系统进行简单分析. 在读者学习本章以及后续i2c相关章节之前,最好了解i2c通信方式,可以参考: ...

  7. MTK-TP(触屏)解读一

    MTK中的TP代码结构并不复杂,相比于其他的系统更为的简单些.它使用的是input子系统,通过该系统来上报触摸按键. 首先我们来看看TP的文件夹下的各代码文件的功能. 文件名 具体功能 关系文件 tp ...

  8. linux驱动工程面试必问知识点

    linux内核原理面试必问(由易到难) 简单型 1:linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化, ...

  9. RTC设备驱动

    问题:pcf8563 RTC设备驱动不能被正常的加载!问题分析过程. 问题在下午得到解决,虽然解决的办法比较笨,采用的是不断的使用printk来跟踪rtc-8563驱动的加载的过程,以及iic模块的工 ...

随机推荐

  1. hdu-3294(最长回文子串)

    题意:给你一个字符和一个字符串让你求出最长回文子串并且输出来,答案需要根据给出的字符转换一下,就是将给出的字符认定为a,然后依次向后推: 解题思路:manacher模板+一些处理 代码: #inclu ...

  2. python 模块之-time

    python 模块time import time # 1 time() :返回当前时间的时间戳 time.time() #1473525444.037215 #------------------- ...

  3. Codeforces518 D. Ilya and Escalator

    传送门:>Here< 题意:有n个人排队做电梯,每个人必须等前面的人全部上了以后才能上.对于每秒钟,有p的概率选择上电梯,(1-p)的概率选择不上电梯.现在问t秒期望多少人上电梯 解题思路 ...

  4. Codeforces Round #517 Div. 2/Div. 1

    \(n\)天没更博了,因为被膜你赛的毒瘤题虐哭了... 既然打了这次CF还是纪念一下. 看看NOIP之前,接下来几场的时间都不好.这应该是最后一场CF了,差\(4\)分上紫也是一个遗憾吧. A 给一个 ...

  5. 集群概念Cluster

    系统扩展方式: scale up,向上扩展:提高主机性能等,质变: scale out,向外扩展:水平扩展,质不变量变: 集群类型: LB:Load Balancing 负载均衡集群: HA:High ...

  6. [CF52C]Circular RMQ【线段树】

    题目大意 给你一个环形数列,完成环形数列上区间加法和区间求最小值. 分析 算是一道比较水的线段树模板题. 如果l>r的话,那么修改l,n和1,r区间. 不然的话那么就修改l,r区间. 其他的基础 ...

  7. python 去重

    List: listA = ['python','python','言','是','一','门','动','态','语','言'] print sorted(set(listA), key = lis ...

  8. django rest framework mixins

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXQAAAEZCAIAAAAIa0mAAAAU/0lEQVR4nO2d247cxoGG5y3yKH6AAf

  9. pandas isin

    在已知id索引的情况下,如何获取所需要的行呢?已经不止一次遇到这样的情况,经历过重重筛选,所得到的最终结果是一串满足所有条件的id列表. pandas 的isin 能很好的解决这个问题, import ...

  10. 关于servlet连接数据库会出现空指针异常情况

    一.servlet在连接数据库时,如果没有事先配置,当用Tomcat运行时会出现NullPointer的情况,是因为Tomcat在运行你的应用程序时没有连接mysql的jar包, 正确做法是将你的my ...