optical/NxBase/i2crw.c
2025-09-04 09:45:08 +08:00

343 lines
6.8 KiB
C

#include "i2crw.h"
#ifndef MAX_MSG_NUM
#define MAX_MSG_NUM 0
#endif
#if (MAX_MSG_NUM > 0)
#ifndef MAX_MSG_DAT_LEN
#define MAX_MSG_DAT_LEN 128
#endif
typedef struct
{
int transDir; // 传输方向
int transSteps; // 传输步骤
u8 slaveAddr; // 从节点地址
u8 regAddr; // 寄存器地址
u8 datbuff[MAX_MSG_DAT_LEN]; // 数据缓冲器
int dataNums; // 数据长度
int datIndex; // 数据传输指针
}TransI2cMsg;
// 传输方向
#define TRANS_DIR_RD 0
#define TRANS_DIR_WR 1
// 传输步骤
#define TRANS_STEP_FREE 0 // 空闲
#define TRANS_STEP_START 1 // 启动
#define TRANS_STEP_R_START 2 // 重复启动
#define TRANS_STEP_ADDR 3 // 传输地址
#define TRANS_STEP_RDDAT 4 // 读取数据
#define TRANS_STEP_FINISH 5 // 完成
#define TRANS_STEP_ERROR 6 // 错误
TransI2cMsg g_msgList[10];
#endif
/*
typedef enum
{
i2cWrite,
i2cRead
} I2cDirection;
typedef enum
{
I2C_STATUS_FREE = 0,
I2C_STATUS_START,
I2C_STATUS_ADDRESS,
I2C_STATUS_START_R,//读数据时第二次发送起始信号
I2C_STATUS_REDATA,
I2C_STATUS_FINSIH,//操作完成
I2C_STATUS_ERR,//错误
}I2C_STATUS;
typedef struct _I2cMessage
{
uint32_t Length;
uint32_t Index;
uint8_t slaveAddress;
I2cDirection direction;
I2C_STATUS status;
uint16_t regAddress;
uint8_t *buffer;
} I2cMessage;
static I2cMessage Message;
void i2cdrvInitBus()
{
I2C_InitTypeDef I2C_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // SCL
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // SDA
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_Pin_9Source, GPIO_AF_I2C1);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x30;;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
NVIC_Init(&NVIC_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_8);
GPIO_SetBits(GPIOB, GPIO_Pin_9);
}
//读取数据
bool i2cdevRead(uint8_t devAddr, uint8_t ReadAddr, uint8_t DatasLen, uint8_t *DataRead)
{
int waitTime;
Message.status = I2C_STATUS_START;
Message.slaveAddress = devAddr;
Message.Index = 0;
Message.buffer = DataRead;
Message.Length = DatasLen;
Message.regAddress = ReadAddr;//寄存器地址
Message.direction = i2cRead;
I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
I2C1->CR1 = (I2C_CR1_START | I2C_CR1_PE);//1 触发起始中断
waitTime = clock();
while (1)//等待接收完成
{
if (Message.status == I2C_STATUS_FINSIH)
{
return true;
}
if (Message.status == I2C_STATUS_ERR)
{
return false;
}
if (clock() - waitTime > 10)
{
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
return false;
}
}
}
//发送一个字节
bool i2cdevWriteByte(uint8_t devAddr, uint8_t WriteAddr, uint8_t DataToWrite)
{
int waitTime;
Message.status = I2C_STATUS_START;
Message.slaveAddress = devAddr;
Message.Index = 0;
Message.buffer = &DataToWrite;
Message.Length = 1;
Message.regAddress = WriteAddr;//寄存器地址
Message.direction = i2cWrite;
I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
I2C1->CR1 = (I2C_CR1_START | I2C_CR1_PE);//1 触发了起始中断
waitTime = clock();
while (1)//等待发送完成
{
if (Message.status == I2C_STATUS_FINSIH)
{
return true;
}
if (Message.status == I2C_STATUS_ERR)
{
return false;
}
if (clock() - waitTime > 10)
{
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
return false;
}
}
}
void I2C1_ER_IRQHandler(void)
{
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF))
{
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
Message.status = I2C_STATUS_ERR;
}
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_BERR))
{
I2C_ClearFlag(I2C1, I2C_FLAG_BERR);
}
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_OVR))
{
I2C_ClearFlag(I2C1, I2C_FLAG_OVR);
}
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_ARLO))
{
I2C_ClearFlag(I2C1, I2C_FLAG_ARLO);
}
}
void I2C1_EV_IRQHandler()
{
uint16_t SR1;
uint16_t SR2;
SR1 = I2C1->SR1;
// Start bit event
if (SR1 & I2C_SR1_SB)
{
if (Message.status == I2C_STATUS_START)
{
I2C_Send7bitAddress(I2C1, Message.slaveAddress << 1, I2C_Direction_Transmitter);//2
Message.status = I2C_STATUS_ADDRESS;
}
else if (Message.status == I2C_STATUS_START_R)
{
I2C_AcknowledgeConfig(I2C1, ENABLE);//5 转为读数据
I2C_Send7bitAddress(I2C1, Message.slaveAddress << 1, I2C_Direction_Receiver);
Message.status = I2C_STATUS_REDATA;
}
}
else if (SR1 & I2C_SR1_ADDR)//地址传输完成
{
SR2 = I2C1->SR2;
if (Message.status == I2C_STATUS_ADDRESS)//发送寄存器地址
{
I2C_SendData(I2C1, Message.regAddress);//4 发送地址
}
if (Message.Length == 1)//只接受一个字节
{
if (Message.status == I2C_STATUS_REDATA)
{
I2C_AcknowledgeConfig(I2C1, DISABLE);
}
}
I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
}
else if (SR1 & I2C_SR1_BTF)
{
//4 上次传输完成
if (SR1&I2C_SR1_TXE)//发送完成
{
if (Message.direction == i2cRead)//读数据
{
if (Message.status == I2C_STATUS_ADDRESS)//寄存器发送完
{
I2C1->CR1 = (I2C_CR1_START | I2C_CR1_PE);//
Message.status = I2C_STATUS_START_R;//启动读数据
}
}
else//写数据
{
I2C_SendData(I2C1, Message.buffer[Message.Index++]);
if (Message.Index == Message.Length)
{
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);//关闭中断
I2C1->CR1 = (I2C_CR1_STOP | I2C_CR1_PE);//后续测试是否添加
Message.status = I2C_STATUS_FINSIH;
}
}
}
}
if (SR1 & I2C_SR1_RXNE)
{
Message.buffer[Message.Index++] = I2C_ReceiveData(I2C1);
if (Message.Index == Message.Length - 1)
{
I2C_AcknowledgeConfig(I2C1, DISABLE);//末尾数据禁止应答
}
if (Message.Index == Message.Length)
{
I2C1->CR1 = (I2C_CR1_STOP | I2C_CR1_PE);//后续测试是否添加
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);//接受结束
Message.status = I2C_STATUS_FINSIH;
}
}
else if (SR1 & I2C_SR1_TXE)
{
}
}
*/