Files
2026-08-05 19:07:52 +08:00

217 lines
7.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Includes.h"
#if 1
/* ---------------------------------------------------------------------------------------------------
- 函数名称: i2c_master_StatusCheck
- 函数功能: 状态检测
- 输入参数: 第几bit; 对应bit上的值
- 创建日期:
----------------------------------------------------------------------------------------------------*/
static void i2c_master_StatusCheck(uint8_t nbit, uint8_t bitval)
{
uint8_t val;
for(; ;) {
__read_hw_reg32(I2C_STATUS , val);
if( bitval == ((val>>nbit)&0x01) ) break;
}
}
/* ---------------------------------------------------------------------------------------------------
- 函数名称: i2c_slave_init
- 函数功能: 初始化i2c SLAVE模式
- 输入参数: i2c器件地址
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern void i2c_slave_init(uint16_t i2cAddR)
{
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x8000800);
__write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x400000);
__write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x400040);
__write_hw_reg32(CPR_I2C_CLK_CTL, 0x110011); //-> i2c_mclk = 16mhz.
i2c_master_StatusCheck(0, 0);
__write_hw_reg32(I2C_ENABLE, 0x00);
__write_hw_reg32(I2C_SAR, i2cAddR);
__write_hw_reg32(I2C_RX_TL, 0x00);
__write_hw_reg32(I2C_TX_TL, 0x00);
__write_hw_reg32(I2C_CON, 0x00);
__write_hw_reg32(I2C_INTR_EN, (I2C_SLAVE_RX_DONE | I2C_SLAVE_RD_REQ | I2C_SLAVE_RX_FULL | I2C_SLAVE_STOP ));
__write_hw_reg32(I2C_FS_SCL_HCNT, 12);
__write_hw_reg32(I2C_FS_SCL_LCNT, 19);
__write_hw_reg32(I2C_SS_SCL_HCNT, 72);
__write_hw_reg32(I2C_SS_SCL_LCNT, 79);
i2c_master_StatusCheck(0, 0);
__write_hw_reg32(I2C_ENABLE, 0x1);
NVIC_EnableIRQ(I2C_IRQn);
}
#define SELVE_ADDRESS 0xA0
/* ---------------------------------------------------------------------------------------------------
- 函数名称: I2C_Handler
- 函数功能: I2C中断处理函数
- 输入参数: 无
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern void I2C_Handler(void)
{
uint32_t stat, VAL;
__read_hw_reg32(I2C_INTR_STAT, stat);
printf("stat=%#x =>",stat); //if(stat == 0) return; //if(stat & 0x200) __read_hw_reg32(I2C_CLR_STOP_DET, VAL);//-读 此 寄 存 器 清 除 中 断STOP_DET //if(stat & 0x40) __read_hw_reg32(I2C_CLR_TX_ABRT, VAL); //- 读此寄存器清除中断 TX_ABRT
__read_hw_reg32(I2C_CLR_INTR, VAL);//- 清除中断 读此寄存器清除组合中断,各个独立中断以及I2C_TX_ABRT_SOURCE 寄存器
if(stat & 0x80)//RX_DONE-作为 slave 发送数据时,如果master 没有响应的话,在发送最后一个字节后产生此中断,表示发送结束
{
printf("RX_DONE--%#x\n",*(I2C_DATA_CMD));
}
if(stat & 0x200)//IIC 停止信号 --STOP_DET 结束条件标志 1:总线出现结束条件 0:无效
{
printf("STOP_DET--%#x\n",*(I2C_DATA_CMD));
}
if(stat & 0x4) //从站收到主站的发送的寄存器地址 (并应答主机的读或写的请求)--RX_FULL RX FIFO 满标志 1RX FIFO 数据大于或者等于 RX FIFO 阈值。此比特随 FIFO状态自动更新 0:无效
{
uint8_t val= *(I2C_DATA_CMD);
if(val==(1)) //寄存器地址
{
*(I2C_DATA_CMD)=0xCC;
}else if(val==0x02) //寄存器地址
{
printf("*****write - %#2x\n",*(I2C_DATA_CMD));
}
else
{
}
printf("RX_FULL--%#2x\n",val);
}
if(stat & 0x20) //RD_REQ //从站收到主站的再次读请求中断,
{ //作为 slave,当另外一个 master尝试从 slave 读数据时产生此中断。Slave 保持 I2C 总线为等待状态(SCL=0)直到中断服务被响应。
//这表示 slave 被远端的master 寻址,并且要求其发送数据。处理器必须响应这个中断,并 将 待 发 送 的 数 据 写 入I2C_DATA_CMD 寄存器
static uint8_t count=1;
*(I2C_DATA_CMD)=count;
printf("RD_REQ--%#x\n",count++);
}
}
void test_slave_i2c()
{
//IIC 主机命令1 是读,0是写 空闲状态下IIC 的SCL SDA都为高电平 等待时擎住SCL线到低电平
gpio_mux_ctl(4,0);gpio_fun_inter(4,0);gpio_fun_sel(4,6);//sda 6:I2C_SDA
gpio_mux_ctl(5,0);gpio_fun_inter(5,0);gpio_fun_sel(5,5);//scl 5:I2C_SCL
//i2c_slave_init(0x3D);//IIC上位机侦测的IIC从机地址为0x7A(等于0x3D<<1)
i2c_slave_init((SELVE_ADDRESS>>1));
while(1);
}
#else
i2cHandler_callback_t i2cHandler_Callback = (i2cHandler_callback_t)0;
/* ---------------------------------------------------------------------------------------------------
- 函数名称: i2c_slave_init
- 函数功能: 初始化i2c SLAVE模式
- 输入参数: i2c器件地址
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern void i2c_slave_init(uint16_t i2cAddR)
{
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x8000800);
__write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x400000);
__write_hw_reg32(CPR_RSTCTL_SUBRST_SW, 0x400040);
__write_hw_reg32(CPR_I2C_CLK_CTL, 0x110011); //-> i2c_mclk = 16mhz.
__write_hw_reg32(I2C_ENABLE, 0x00);
__write_hw_reg32(I2C_SAR, i2cAddR);
__write_hw_reg32(I2C_RX_TL, 0x00);
__write_hw_reg32(I2C_TX_TL, 0x00);
__write_hw_reg32(I2C_CON, 0x00);
__write_hw_reg32(I2C_INTR_EN, (I2C_SLAVE_RX_DONE | I2C_SLAVE_RD_REQ | I2C_SLAVE_RX_FULL | I2C_SLAVE_STOP ));
__write_hw_reg32(I2C_ENABLE, 0x1);
NVIC_EnableIRQ(I2C_IRQn);
}
/* ---------------------------------------------------------------------------------------------------
- 函数名称: i2c_slave_Register_Callback
- 函数功能: 为i2c从设备注册中断回调函数
- 输入参数: 中断状态值
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern void i2c_slave_Register_Callback(i2cHandler_callback_t callback)
{
i2cHandler_Callback = callback;
}
/* ---------------------------------------------------------------------------------------------------
- 函数名称: i2c_slave_WriteSingle
- 函数功能: 为i2c从设备发送数据
- 输入参数: 发送的数据
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern void i2c_slave_WriteSingle(uint8_t val)
{
__write_hw_reg32(I2C_DATA_CMD, val);
}
/* ---------------------------------------------------------------------------------------------------
- 函数名称: i2c_slave_ReadSingle
- 函数功能: 为i2c从设备获取数据
- 输入参数: 无
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern uint8_t i2c_slave_ReadSingle(void)
{
uint8_t val;
__read_hw_reg32(I2C_DATA_CMD, val);
return (val);
}
/* ---------------------------------------------------------------------------------------------------
- 函数名称: I2C_Handler
- 函数功能: I2C中断处理函数
- 输入参数: 无
- 创建日期:
----------------------------------------------------------------------------------------------------*/
extern void I2C_Handler(void)
{
uint32_t stat, VAL;
__read_hw_reg32(I2C_INTR_STAT, stat);
if(stat == 0) return;
if(stat & 0x200) __read_hw_reg32(I2C_CLR_STOP_DET, VAL);
if(stat & 0x40) __read_hw_reg32(I2C_CLR_TX_ABRT, VAL);
__read_hw_reg32(I2C_CLR_INTR, VAL); //- 清除中断
if(i2cHandler_Callback != (i2cHandler_callback_t)0) {
i2cHandler_Callback(stat);
}
}
#endif