i2c框架
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;
}
中断处理
注意
- 连续读的最后一个字节不响应ack,以用来终止读.
- 在读写第一个字节的时候,判断是否有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)I2c的简介和特性
I2C我是想全面深入的从嵌入式软件工程师的角度做个理解,刚刚还申请了一个专栏,这个好好写. 学习技术从外文文档看起-- 要全面了解I2C,可以从<I2C-bus specific ...
- linux设备驱动程序-i2c(2)-adapter和设备树的解析
linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 在本系列linux内核i2c框架的前两篇,分别讲 ...
- linux设备驱动程序-i2c(0)-i2c设备驱动源码实现
(基于4.14内核版本) 为了梳理清楚linux内核中的i2c实现框架,从本文开始,博主将分几个章节分别解析i2c总线在linux内核中的形成过程.匹配过程.以及设备驱动程序源码实现. 在介绍linu ...
- linux设备驱动程序-i2c(1):i2c总线的添加与实现
linux设备驱动程序-i2c(1):i2c总线的添加与实现 (基于4.14内核版本) 在上一章节linux设备驱动程序-i2c(0)-i2c设备驱动源码实现中,我们演示了i2c设备驱动程序的源码实现 ...
- linux设备驱动程序--串行通信驱动框架分析
linux 串行通信接口驱动框架 在学习linux内核驱动时,不论是看linux相关的书籍,又或者是直接看linux的源码,总是能在linux中看到各种各样的框架,linux内核极其庞杂,linux各 ...
- 十四、i2c子系统
由于之后的触摸屏驱动分析中使用到了GPIO子系统和i2c子系统,因此在分析触摸屏驱动之前我准备把这两个子系统进行简单分析. 在读者学习本章以及后续i2c相关章节之前,最好了解i2c通信方式,可以参考: ...
- MTK-TP(触屏)解读一
MTK中的TP代码结构并不复杂,相比于其他的系统更为的简单些.它使用的是input子系统,通过该系统来上报触摸按键. 首先我们来看看TP的文件夹下的各代码文件的功能. 文件名 具体功能 关系文件 tp ...
- linux驱动工程面试必问知识点
linux内核原理面试必问(由易到难) 简单型 1:linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化, ...
- RTC设备驱动
问题:pcf8563 RTC设备驱动不能被正常的加载!问题分析过程. 问题在下午得到解决,虽然解决的办法比较笨,采用的是不断的使用printk来跟踪rtc-8563驱动的加载的过程,以及iic模块的工 ...
随机推荐
- raise missingsectionheadererror:file containe no section headers问题解决
本人亲测,遇到这个问题,就换到管理员方式运行命令 因为太小白,所以这次重新装包的时候切换到D盘了,想着省一点儿C盘内存,结果,每次pip install安装的时候都是这个问题,中间还有什么反序列失败, ...
- fiddler软件测试——Fiddler抓取https设置详解(图文)
强烈推荐(原创亲测)!!!Fiddler抓取https设置详解(图文)转 本文主要说明了自己在设置fiddler抓取https过程中所遇到的问题及解决步骤,特别是fiddler在设置证书的环节遇到的各 ...
- CSS查漏补缺【未完】
1.层叠次序 当同一个 HTML 元素被不止一个样式定义时,会使用哪个样式呢? 一般而言,所有的样式会根据下面的规则层叠于一个新的虚拟样式表中,其中数字 4 拥有最高的优先权. 浏览器缺省设置 外部样 ...
- java JUC
https://www.cnblogs.com/q151860/p/8589683.html
- [luogu1452]Beauty Contest【凸包+旋转卡壳】
题目大意 求出平面最远点对距离的平方. 分析 此题我wa了好久,第一是凸包写错了,后面又是旋转卡壳写错了..自闭3s. 题解应该是旋转卡壳,但是有人用随机化乱搞过掉了Orz. 讲讲正解. 我们先求出所 ...
- HR_Two Strings
https://www.hackerrank.com/challenges/two-strings/problem?h_l=interview&playlist_slugs%5B%5D=int ...
- shell中,2>&1详解
我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令.首先我们把这条命令大概分解下,首先就是一个nohup表示当前用户和系 ...
- [SDOI2010]大陆争霸
幻想历8012年5月12日深夜,斯普林·布拉泽降下神谕:“Trust me, earn eternal life.”克里斯军团士气大增.作为克里斯军团的主帅,你决定利用这一机会发动奇袭,一举击败杰森国 ...
- maven插件运行过程中自动执行sql文件
配置pom.propertis即可 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId> ...
- 项目部署之nginx实现PC端和移动端自动跳转
假设PC端域名为 www.abc.com 移动端域名为m.abc.com PC端nginx配置文件server中加入如下代码: if ($http_host !~ "^www.abc ...