| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- /******************************************************************************
- 版权所有:
- 文件名称: i2c.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-01
- 功能说明: i2c驱动程序。目前总线频率391KHZ.
- 其它说明:
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "bspconfig.h"
- #include "ustimer.h"
- #include "i2c.h"
- /*------------------------------- 宏定义 --------------------------------------
- */
- #define I2C_PM_REG MCF_PMM_PPMCR1
- #define I2C_PM_INDEX 4
- /*------------------------------ 全局变量 -------------------------------------
- */
- //总线占用状态
- int gh_i2c = 0;
- /*------------------------------ 外部函数 -------------------------------------
- */
- /******************************************************************************
- 函数名称: i2c_init
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-06-26
- 函数说明: i2c初始化。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- int i2c_init(void)
- {
- #if 0
- unsigned char temp;
- //允许I2C模块时钟
- I2C_PM_REG = I2C_PM_INDEX;
-
- //管脚配置,假设从默认值开始设置
- MCF_PAD_PAR_SSI0H |= 0
- | MCF_PAD_PAR_SSI0H_PAR_TXD_SCL2
- | MCF_PAD_PAR_SSI0H_PAR_RXD_SDA2;
-
- //I2C模块输入时钟125M,将频率设为接近400KHZ(391khz)(分频比320,值0x34).
- MCF_I2FDR = MCF_I2C_I2FDR_IC(0x34);
-
- //允许模块,mcf54418必须打开中断。
- MCF_I2CR = 0 | MCF_I2C_I2CR_IEN | MCF_I2C_I2CR_IIEN;
-
- //如果总线忙bit设置,发送一个stop信号到slave模块。
- if( MCF_I2SR & MCF_I2C_I2SR_IBB)
- {
- MCF_I2CR = 0; /* clear control register */
- MCF_I2CR = MCF_I2C_I2CR_IEN /* enable module */
- | MCF_I2C_I2CR_MSTA; /* send a START condition */
- temp = MCF_I2DR; /* dummy read */
- MCF_I2SR = 0; /* clear status register */
- MCF_I2CR = 0; /* clear control register */
- MCF_I2CR = MCF_I2C_I2CR_IEN; /* enable the module again */
- }
- #endif
- return 0;
- }
- /******************************************************************************
- 函数名称: i2c_open
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-19
- 函数说明: 打开一个I2C设备,所有的I2C设备互斥,一次只能打开一个.
-
- 注意:此函数在资源竞争问题上,有一定的系统要求,如果要求不满足,用户应
- 自己处理资源竞争问题.这个要求为:系统中每个任务(一个中断服务程序也算
- 一个任务)都具有唯一优先级.目前UT800S的系统满足这个条件.
- 参数说明:
- i2c_id: 指定需要打开I2C设备的标识符(以I2C_ID_开头)。
- 返回值:
- >=0 : 打开设备的句柄
- <0 : 打开失败。
- 修改记录:
- */
- int i2c_open(int i2c_id)
- {
- if(i2c_id != I2C_ID_RTC && i2c_id != I2C_ID_E2PROM)
- {
-
- return -1;
- }
-
- //如果QSPI总线空闲,占有它。
- if(gh_i2c == 0)
- {
-
- gh_i2c = i2c_id;
- }
- else
- {
-
- return -1;
- }
-
- //解决资源竞争问题,如果两个值不相等,说明在竞争中失败,退出。
- if(gh_i2c != i2c_id)
- {
-
- return -2;
- }
-
- return i2c_id;
- }
- /******************************************************************************
- 函数名称: i2c_close
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-21
- 函数说明: 关闭一个I2C设备。
- 参数说明:
- h_i2c:关闭设备的句柄。
- 返回值: 成功返回0.
- 修改记录:
- */
- int i2c_close(int h_i2c)
- {
- if(h_i2c != gh_i2c)
- {
-
- return -1;
- }
-
- gh_i2c = 0;
-
- return 0;
- }
- /******************************************************************************
- 函数名称: i2c_wait_completion
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-07
- 函数说明: 等待i2c传输一个字节完成,带0.1秒超时。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- int i2c_wait_completion(void)
- {
- uint32_t us0,us;
-
- //等待中断发生
- us0 = ustimer_get_origin();
- while(1)
- {
- // 得到超时值
- us = ustimer_get_duration(us0);
- // 检查条件
- //if((MCF_I2SR & MCF_I2C_I2SR_IIF))
- {
- break;
- }
-
- //超时设定为1秒
- if(us > 1*USTIMER_SEC)
- {
- //重新初始化I2C模块,否则模块可能再也不能正常工作。
- MCF_I2CR = 0;
- i2c_init();
- return -1;
- }
- }
- //MCF_I2SR &= ~MCF_I2C_I2SR_IIF;
-
- return 0;
- }
- /******************************************************************************
- 函数名称: i2c_wait_bus_idle
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-07
- 函数说明: 等待i2c总线空闲,带0.1秒超时。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- int i2c_wait_bus_idle(void)
- {
- uint32_t us0,us;
-
- //清除arbitration位(IAL),增强程序健壮性。
- // MCF_I2SR &= ~MCF_I2C_I2SR_IAL;
-
- //等待总线空闲
- us0 = ustimer_get_origin();
- while(1)
- {
-
- // 得到超时值
- us = ustimer_get_duration(us0);
-
- // 检查条件
- // if((MCF_I2SR & MCF_I2C_I2SR_IBB) == 0)
- {
- break;
- }
- //超时设定为1秒
- if(us > 1*USTIMER_SEC)
- {
- //重新初始化I2C模块,否则模块可能再也不能正常工作。
- MCF_I2CR = 0;
- i2c_init();
- return -1;
- }
- }
-
- return 0;
- }
- /*------------------------------ 内部函数 -------------------------------------
- */
- /*------------------------------ 测试函数 -------------------------------------
- */
|