201 lines
4.6 KiB
C++
201 lines
4.6 KiB
C++
#include "I2C_Port.h"
|
|
|
|
//static I2C_TypeDef* const g_I2Cs[] = I2CS;
|
|
//static const Pin g_I2C_Pins_Map[][2] = I2C_PINS_FULLREMAP;
|
|
|
|
I2C_Port::I2C_Port(I2C_TypeDef* iic, uint speedHz )
|
|
{
|
|
assert_param(iic);
|
|
|
|
I2C_TypeDef* g_I2Cs[] = I2CS;
|
|
_index = 0xFF;
|
|
for(int i=0; i<ArrayLength(g_I2Cs); i++)
|
|
{
|
|
if(g_I2Cs[i] == iic)
|
|
{
|
|
_index = i;
|
|
break;
|
|
}
|
|
}
|
|
assert_param(_index < ArrayLength(g_I2Cs));
|
|
|
|
_IIC = g_I2Cs[_index];
|
|
|
|
Pin pins[][2] = I2C_PINS;
|
|
Pins[0] = pins[_index][0];
|
|
Pins[1] = pins[_index][1];
|
|
|
|
debug_printf("I2C%d %dHz \r\n", _index + 1, speedHz);
|
|
|
|
Speed = speedHz;
|
|
Retry = 200;
|
|
Error = 0;
|
|
Address = 0x00;
|
|
}
|
|
|
|
I2C_Port::~I2C_Port()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
void I2C_Port::SetPin(Pin acl , Pin sda )
|
|
{
|
|
Pins[0] = acl;
|
|
Pins[1] = sda;
|
|
}
|
|
|
|
void I2C_Port::GetPin(Pin* acl , Pin* sda )
|
|
{
|
|
*acl = Pins[0];
|
|
*sda = Pins[1];
|
|
}
|
|
|
|
void I2C_Port::Open()
|
|
{
|
|
// gpio 复用开漏输出
|
|
SCL = new AlternatePort(Pins[0], true);
|
|
SDA = new AlternatePort(Pins[1], true);
|
|
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 << _index, ENABLE);
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
|
|
|
//RCC_APB1PeriphResetCmd(sEE_I2C_CLK, ENABLE);
|
|
//RCC_APB1PeriphResetCmd(sEE_I2C_CLK, DISABLE);
|
|
|
|
#if defined(STM32F0)
|
|
// SPI都在GPIO_AF_0分组内
|
|
GPIO_PinAFConfig(_GROUP(Pins[0]), _PIN(Pins[0]), GPIO_AF_0);
|
|
GPIO_PinAFConfig(_GROUP(Pins[1]), _PIN(Pins[1]), GPIO_AF_0);
|
|
#elif defined(STM32F4)
|
|
byte afs[] = { GPIO_AF_I2C1, GPIO_AF_I2C2, GPIO_AF_I2C3 };
|
|
GPIO_PinAFConfig(_GROUP(Pins[0]), _PIN(Pins[0]), afs[_index]);
|
|
GPIO_PinAFConfig(_GROUP(Pins[1]), _PIN(Pins[1]), afs[_index]);
|
|
#endif
|
|
|
|
I2C_InitTypeDef i2c;
|
|
I2C_StructInit(&i2c);
|
|
I2C_DeInit(_IIC); // 复位
|
|
|
|
// I2C_Timing
|
|
// I2C_AnalogFilter
|
|
// I2C_DigitalFilter
|
|
// I2C_Mode
|
|
// I2C_OwnAddress1
|
|
// I2C_Ack
|
|
// I2C_AcknowledgedAddress
|
|
|
|
/*i2c.I2C_AnalogFilter = I2C_AnalogFilter_Disable; // 关闭滤波器
|
|
// i2c.I2C_DigitalFilter // 数字滤波器 不知道怎么设置 跟 cr1 的8-11位有关
|
|
i2c.I2C_Mode =I2C_Mode_I2C; // IIC 模式
|
|
// i2c.I2C_OwnAddress1
|
|
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
|
if(addressLen == ADDR_LEN_10)
|
|
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_10bit;*/
|
|
i2c.I2C_Mode = I2C_Mode_I2C;
|
|
i2c.I2C_DutyCycle = I2C_DutyCycle_2;
|
|
i2c.I2C_OwnAddress1 = Address;
|
|
i2c.I2C_Ack = I2C_Ack_Enable;
|
|
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
|
i2c.I2C_ClockSpeed = Speed;
|
|
|
|
I2C_Cmd(_IIC, ENABLE);
|
|
I2C_Init(_IIC, &i2c);
|
|
}
|
|
|
|
void I2C_Port::Close()
|
|
{
|
|
// sEE_I2C Peripheral Disable
|
|
I2C_Cmd(_IIC, DISABLE);
|
|
|
|
// sEE_I2C DeInit
|
|
I2C_DeInit(_IIC);
|
|
|
|
// sEE_I2C Periph clock disable
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 << _index, DISABLE);
|
|
|
|
if(SCL) delete SCL;
|
|
SCL = NULL;
|
|
|
|
if(SDA) delete SDA;
|
|
SDA = NULL;
|
|
}
|
|
|
|
bool I2C_Port::WaitForEvent(uint event)
|
|
{
|
|
int retry = Retry;
|
|
while(!I2C_CheckEvent(_IIC, event));
|
|
{
|
|
if(--retry <= 0) return ++Error; // 超时处理
|
|
}
|
|
return retry > 0;
|
|
}
|
|
|
|
bool I2C_Port::SetID(byte id, bool tx)
|
|
{
|
|
// 产生起始条件
|
|
I2C_GenerateSTART(_IIC, ENABLE);
|
|
// 等待ACK
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_MODE_SELECT)) return false;
|
|
if(tx)
|
|
{
|
|
// 向设备发送设备地址
|
|
I2C_Send7bitAddress(_IIC, id, I2C_Direction_Transmitter);
|
|
// 等待ACK
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) return false;
|
|
}
|
|
else
|
|
{
|
|
// 发送读地址
|
|
I2C_Send7bitAddress(_IIC, id, I2C_Direction_Receiver);
|
|
// EV6
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) return 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void I2C_Port::Write(byte id, byte addr, byte dat)
|
|
{
|
|
if(!SetID(id)) return;
|
|
|
|
// 寄存器地址
|
|
I2C_SendData(_IIC, addr);
|
|
// 等待ACK
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) return;
|
|
// 发送数据
|
|
I2C_SendData(_IIC, dat);
|
|
// 发送完成
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) return;
|
|
// 产生结束信号
|
|
I2C_GenerateSTOP(_IIC, ENABLE);
|
|
}
|
|
|
|
byte I2C_Port::Read(byte id, byte addr)
|
|
{
|
|
// 等待I2C
|
|
while(I2C_GetFlagStatus(_IIC, I2C_FLAG_BUSY));
|
|
|
|
if(!SetID(id)) return 0;
|
|
|
|
// 重新设置可以清楚EV6
|
|
I2C_Cmd(_IIC, ENABLE);
|
|
// 发送读得地址
|
|
I2C_SendData(_IIC, addr);
|
|
// EV8
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) return 0;
|
|
|
|
if(!SetID(id, false)) return 0;
|
|
|
|
// 关闭应答
|
|
I2C_AcknowledgeConfig(_IIC, DISABLE);
|
|
// 停止条件产生
|
|
I2C_GenerateSTOP(_IIC, ENABLE);
|
|
if(!WaitForEvent(I2C_EVENT_MASTER_BYTE_RECEIVED)) return 0;
|
|
|
|
byte dat = I2C_ReceiveData(_IIC);
|
|
|
|
I2C_AcknowledgeConfig(_IIC, ENABLE);
|
|
|
|
return dat;
|
|
}
|