More i2c updates for io
This commit is contained in:
parent
32e0be9802
commit
33033c326b
|
@ -21,246 +21,256 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
||||||
#include "build_config.h"
|
#include "build_config.h"
|
||||||
|
#include "bus_i2c.h"
|
||||||
#include "gpio.h"
|
#include "drivers/io.h"
|
||||||
|
|
||||||
// Software I2C driver, using same pins as hardware I2C, with hw i2c module disabled.
|
// Software I2C driver, using same pins as hardware I2C, with hw i2c module disabled.
|
||||||
// Can be configured for I2C2 pinout (SCL: PB10, SDA: PB11) or I2C1 pinout (SCL: PB6, SDA: PB7)
|
// Can be configured for I2C2 pinout (SCL: PB10, SDA: PB11) or I2C1 pinout (SCL: PB6, SDA: PB7)
|
||||||
|
|
||||||
#ifdef SOFT_I2C
|
#ifdef SOFT_I2C
|
||||||
|
|
||||||
#ifdef SOFT_I2C_PB1011
|
static IO_t scl;
|
||||||
#define SCL_H GPIOB->BSRR = Pin_10
|
static IO_t sda;
|
||||||
#define SCL_L GPIOB->BRR = Pin_10
|
static volatile uint16_t i2cErrorCount = 0;
|
||||||
|
|
||||||
#define SDA_H GPIOB->BSRR = Pin_11
|
#define SCL_H IOHi(scl)
|
||||||
#define SDA_L GPIOB->BRR = Pin_11
|
#define SCL_L IOLo(scl)
|
||||||
|
|
||||||
#define SCL_read (GPIOB->IDR & Pin_10)
|
#define SDA_H IOHi(sda)
|
||||||
#define SDA_read (GPIOB->IDR & Pin_11)
|
#define SDA_L IOLo(sda)
|
||||||
#define I2C_PINS (Pin_10 | Pin_11)
|
|
||||||
#define I2C_GPIO GPIOB
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SOFT_I2C_PB67
|
#define SCL_read IORead(scl)
|
||||||
#define SCL_H GPIOB->BSRR = Pin_6
|
#define SDA_read IORead(sda)
|
||||||
#define SCL_L GPIOB->BRR = Pin_6
|
|
||||||
|
|
||||||
#define SDA_H GPIOB->BSRR = Pin_7
|
#if !defined(SOFT_I2C_SCL) || !defined(SOFT_I2C_SDA)
|
||||||
#define SDA_L GPIOB->BRR = Pin_7
|
#error "Must define the software i2c pins (SOFT_I2C_SCL and SOFT_I2C_SDA) in target.h"
|
||||||
|
|
||||||
#define SCL_read (GPIOB->IDR & Pin_6)
|
|
||||||
#define SDA_read (GPIOB->IDR & Pin_7)
|
|
||||||
#define I2C_PINS (Pin_6 | Pin_7)
|
|
||||||
#define I2C_GPIO GPIOB
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SCL_H
|
|
||||||
#error Need to define SOFT_I2C_PB1011 or SOFT_I2C_PB67 (see board.h)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void I2C_delay(void)
|
static void I2C_delay(void)
|
||||||
{
|
{
|
||||||
volatile int i = 7;
|
volatile int i = 7;
|
||||||
while (i) {
|
while (i) {
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool I2C_Start(void)
|
static bool I2C_Start(void)
|
||||||
{
|
{
|
||||||
SDA_H;
|
SDA_H;
|
||||||
SCL_H;
|
SCL_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
if (!SDA_read) {
|
if (!SDA_read) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
SDA_L;
|
|
||||||
I2C_delay();
|
|
||||||
if (SDA_read) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
SDA_L;
|
SDA_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
return true;
|
if (SDA_read) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SDA_L;
|
||||||
|
I2C_delay();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I2C_Stop(void)
|
static void I2C_Stop(void)
|
||||||
{
|
{
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SDA_L;
|
SDA_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_H;
|
SCL_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SDA_H;
|
SDA_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I2C_Ack(void)
|
static void I2C_Ack(void)
|
||||||
{
|
{
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SDA_L;
|
SDA_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_H;
|
SCL_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I2C_NoAck(void)
|
static void I2C_NoAck(void)
|
||||||
{
|
{
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SDA_H;
|
SDA_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_H;
|
SCL_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool I2C_WaitAck(void)
|
static bool I2C_WaitAck(void)
|
||||||
{
|
{
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SDA_H;
|
SDA_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_H;
|
SCL_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
if (SDA_read) {
|
if (SDA_read) {
|
||||||
SCL_L;
|
SCL_L;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SCL_L;
|
SCL_L;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I2C_SendByte(uint8_t byte)
|
static void I2C_SendByte(uint8_t byte)
|
||||||
{
|
{
|
||||||
uint8_t i = 8;
|
uint8_t i = 8;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
if (byte & 0x80) {
|
if (byte & 0x80) {
|
||||||
SDA_H;
|
SDA_H;
|
||||||
} else {
|
}
|
||||||
SDA_L;
|
else {
|
||||||
}
|
SDA_L;
|
||||||
byte <<= 1;
|
}
|
||||||
I2C_delay();
|
byte <<= 1;
|
||||||
SCL_H;
|
I2C_delay();
|
||||||
I2C_delay();
|
SCL_H;
|
||||||
}
|
I2C_delay();
|
||||||
SCL_L;
|
}
|
||||||
|
SCL_L;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t I2C_ReceiveByte(void)
|
static uint8_t I2C_ReceiveByte(void)
|
||||||
{
|
{
|
||||||
uint8_t i = 8;
|
uint8_t i = 8;
|
||||||
uint8_t byte = 0;
|
uint8_t byte = 0;
|
||||||
|
|
||||||
SDA_H;
|
SDA_H;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
byte <<= 1;
|
byte <<= 1;
|
||||||
SCL_L;
|
SCL_L;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
SCL_H;
|
SCL_H;
|
||||||
I2C_delay();
|
I2C_delay();
|
||||||
if (SDA_read) {
|
if (SDA_read) {
|
||||||
byte |= 0x01;
|
byte |= 0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCL_L;
|
SCL_L;
|
||||||
return byte;
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2cInit(I2C_TypeDef * I2C)
|
void i2cInit(I2CDevice device)
|
||||||
{
|
{
|
||||||
gpio_config_t gpio;
|
UNUSED(device);
|
||||||
|
|
||||||
gpio.pin = I2C_PINS;
|
scl = IOGetByTag(IO_TAG(SOFT_I2C_SCL));
|
||||||
gpio.speed = Speed_2MHz;
|
sda = IOGetByTag(IO_TAG(SOFT_I2C_SDA));
|
||||||
gpio.mode = Mode_Out_OD;
|
|
||||||
gpioInit(I2C_GPIO, &gpio);
|
IOConfigGPIO(scl, IOCFG_OUT_OD);
|
||||||
|
IOConfigGPIO(sda, IOCFG_OUT_OD);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)
|
bool i2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (!I2C_Start()) {
|
if (!I2C_Start()) {
|
||||||
return false;
|
i2cErrorCount++;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||||
if (!I2C_WaitAck()) {
|
if (!I2C_WaitAck()) {
|
||||||
I2C_Stop();
|
I2C_Stop();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
I2C_SendByte(reg);
|
I2C_SendByte(reg);
|
||||||
I2C_WaitAck();
|
I2C_WaitAck();
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
I2C_SendByte(data[i]);
|
I2C_SendByte(data[i]);
|
||||||
if (!I2C_WaitAck()) {
|
if (!I2C_WaitAck()) {
|
||||||
I2C_Stop();
|
I2C_Stop();
|
||||||
return false;
|
i2cErrorCount++;
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
I2C_Stop();
|
}
|
||||||
return true;
|
I2C_Stop();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data)
|
bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data)
|
||||||
{
|
{
|
||||||
if (!I2C_Start()) {
|
if (!I2C_Start()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||||
if (!I2C_WaitAck()) {
|
if (!I2C_WaitAck()) {
|
||||||
I2C_Stop();
|
I2C_Stop();
|
||||||
return false;
|
i2cErrorCount++;
|
||||||
}
|
return false;
|
||||||
I2C_SendByte(reg);
|
}
|
||||||
I2C_WaitAck();
|
I2C_SendByte(reg);
|
||||||
I2C_SendByte(data);
|
I2C_WaitAck();
|
||||||
I2C_WaitAck();
|
I2C_SendByte(data);
|
||||||
I2C_Stop();
|
I2C_WaitAck();
|
||||||
return true;
|
I2C_Stop();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
|
bool i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
|
||||||
{
|
{
|
||||||
if (!I2C_Start()) {
|
if (!I2C_Start()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||||
if (!I2C_WaitAck()) {
|
if (!I2C_WaitAck()) {
|
||||||
I2C_Stop();
|
I2C_Stop();
|
||||||
return false;
|
i2cErrorCount++;
|
||||||
}
|
return false;
|
||||||
I2C_SendByte(reg);
|
}
|
||||||
I2C_WaitAck();
|
I2C_SendByte(reg);
|
||||||
I2C_Start();
|
I2C_WaitAck();
|
||||||
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
|
I2C_Start();
|
||||||
I2C_WaitAck();
|
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
|
||||||
while (len) {
|
I2C_WaitAck();
|
||||||
*buf = I2C_ReceiveByte();
|
while (len) {
|
||||||
if (len == 1) {
|
*buf = I2C_ReceiveByte();
|
||||||
I2C_NoAck();
|
if (len == 1) {
|
||||||
} else {
|
I2C_NoAck();
|
||||||
I2C_Ack();
|
}
|
||||||
}
|
else {
|
||||||
buf++;
|
I2C_Ack();
|
||||||
len--;
|
}
|
||||||
}
|
buf++;
|
||||||
I2C_Stop();
|
len--;
|
||||||
return true;
|
}
|
||||||
|
I2C_Stop();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i2cGetErrorCounter(void)
|
uint16_t i2cGetErrorCounter(void)
|
||||||
{
|
{
|
||||||
// TODO maybe fix this, but since this is test code, doesn't matter.
|
return i2cErrorCount;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool i2cWriteBufferByDevice(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_, uint8_t *data)
|
||||||
|
{
|
||||||
|
return i2cWriteBuffer(addr_, reg_, len_, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2cWriteByDevice(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
return i2cWrite(addr_, reg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2cReadByDevice(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf)
|
||||||
|
{
|
||||||
|
return i2cRead(addr_, reg, len, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -355,6 +355,8 @@ void i2c_ev_handler(I2CDevice device) {
|
||||||
|
|
||||||
void i2cInit(I2CDevice device)
|
void i2cInit(I2CDevice device)
|
||||||
{
|
{
|
||||||
|
I2Cx_device = device;
|
||||||
|
|
||||||
if (device == I2CINVALID)
|
if (device == I2CINVALID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -25,303 +25,247 @@
|
||||||
|
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "drivers/io_impl.h"
|
||||||
|
|
||||||
#include "bus_i2c.h"
|
#include "bus_i2c.h"
|
||||||
|
|
||||||
#ifndef SOFT_I2C
|
#ifndef SOFT_I2C
|
||||||
|
|
||||||
#define I2C1_SCL_GPIO GPIOB
|
#define I2C_SHORT_TIMEOUT ((uint32_t)0x1000)
|
||||||
#define I2C1_SCL_GPIO_AF GPIO_AF_4
|
#define I2C_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT))
|
||||||
#define I2C1_SCL_PIN GPIO_Pin_6
|
#define I2C_GPIO_AF GPIO_AF_4
|
||||||
#define I2C1_SCL_PIN_SOURCE GPIO_PinSource6
|
|
||||||
#define I2C1_SCL_CLK_SOURCE RCC_AHBPeriph_GPIOB
|
|
||||||
#define I2C1_SDA_GPIO GPIOB
|
|
||||||
#define I2C1_SDA_GPIO_AF GPIO_AF_4
|
|
||||||
#define I2C1_SDA_PIN GPIO_Pin_7
|
|
||||||
#define I2C1_SDA_PIN_SOURCE GPIO_PinSource7
|
|
||||||
#define I2C1_SDA_CLK_SOURCE RCC_AHBPeriph_GPIOB
|
|
||||||
|
|
||||||
#if !defined(I2C2_SCL_GPIO)
|
|
||||||
#define I2C2_SCL_GPIO GPIOF
|
|
||||||
#define I2C2_SCL_GPIO_AF GPIO_AF_4
|
|
||||||
#define I2C2_SCL_PIN GPIO_Pin_6
|
|
||||||
#define I2C2_SCL_PIN_SOURCE GPIO_PinSource6
|
|
||||||
#define I2C2_SCL_CLK_SOURCE RCC_AHBPeriph_GPIOF
|
|
||||||
#define I2C2_SDA_GPIO GPIOA
|
|
||||||
#define I2C2_SDA_GPIO_AF GPIO_AF_4
|
|
||||||
#define I2C2_SDA_PIN GPIO_Pin_10
|
|
||||||
#define I2C2_SDA_PIN_SOURCE GPIO_PinSource10
|
|
||||||
#define I2C2_SDA_CLK_SOURCE RCC_AHBPeriph_GPIOA
|
|
||||||
|
|
||||||
|
#ifndef I2C1_SCL
|
||||||
|
#define I2C1_SCL PB6
|
||||||
|
#endif
|
||||||
|
#ifndef I2C1_SDA
|
||||||
|
#define I2C1_SDA PB7
|
||||||
|
#endif
|
||||||
|
#ifndef I2C2_SCL
|
||||||
|
#define I2C2_SCL PF4
|
||||||
|
#endif
|
||||||
|
#ifndef I2C2_SDA
|
||||||
|
#define I2C2_SDA PA10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint32_t i2cTimeout;
|
static uint32_t i2cTimeout;
|
||||||
|
|
||||||
static volatile uint16_t i2c1ErrorCount = 0;
|
static volatile uint16_t i2cErrorCount = 0;
|
||||||
static volatile uint16_t i2c2ErrorCount = 0;
|
//static volatile uint16_t i2c2ErrorCount = 0;
|
||||||
|
|
||||||
static I2C_TypeDef *I2Cx = NULL;
|
static i2cDevice_t i2cHardwareMap[] = {
|
||||||
|
{ .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = false },
|
||||||
|
{ .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = false }
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// I2C TimeoutUserCallback
|
// I2C TimeoutUserCallback
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
uint32_t i2cTimeoutUserCallback(I2C_TypeDef *I2Cx)
|
uint32_t i2cTimeoutUserCallback(void)
|
||||||
{
|
{
|
||||||
if (I2Cx == I2C1) {
|
i2cErrorCount++;
|
||||||
i2c1ErrorCount++;
|
return false;
|
||||||
} else {
|
|
||||||
i2c2ErrorCount++;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2cInitPort(I2C_TypeDef *I2Cx)
|
static I2CDevice I2Cx_device;
|
||||||
|
|
||||||
|
void i2cInit(I2CDevice device)
|
||||||
{
|
{
|
||||||
GPIO_InitTypeDef GPIO_InitStructure;
|
I2Cx_device = device;
|
||||||
I2C_InitTypeDef I2C_InitStructure;
|
|
||||||
|
i2cDevice_t *i2c;
|
||||||
|
i2c = &(i2cHardwareMap[device]);
|
||||||
|
|
||||||
if (I2Cx == I2C1) {
|
I2C_TypeDef *I2Cx;
|
||||||
RCC_AHBPeriphClockCmd(I2C1_SCL_CLK_SOURCE | I2C1_SDA_CLK_SOURCE, ENABLE);
|
I2Cx = i2c->dev;
|
||||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
|
||||||
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
|
IO_t scl = IOGetByTag(i2c->scl);
|
||||||
|
IO_t sda = IOGetByTag(i2c->sda);
|
||||||
|
|
||||||
|
RCC_ClockCmd(i2c->rcc, ENABLE);
|
||||||
|
RCC_I2CCLKConfig(I2Cx == I2C2 ? RCC_I2C2CLK_SYSCLK : RCC_I2C1CLK_SYSCLK);
|
||||||
|
|
||||||
//i2cUnstick(I2Cx); // Clock out stuff to make sure slaves arent stuck
|
IOConfigGPIOAF(scl, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4);
|
||||||
|
IOConfigGPIOAF(sda, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4);
|
||||||
|
|
||||||
GPIO_PinAFConfig(I2C1_SCL_GPIO, I2C1_SCL_PIN_SOURCE, I2C1_SCL_GPIO_AF);
|
I2C_InitTypeDef i2cInit = {
|
||||||
GPIO_PinAFConfig(I2C1_SDA_GPIO, I2C1_SDA_PIN_SOURCE, I2C1_SDA_GPIO_AF);
|
.I2C_Mode = I2C_Mode_I2C,
|
||||||
|
.I2C_AnalogFilter = I2C_AnalogFilter_Enable,
|
||||||
|
.I2C_DigitalFilter = 0x00,
|
||||||
|
.I2C_OwnAddress1 = 0x00,
|
||||||
|
.I2C_Ack = I2C_Ack_Enable,
|
||||||
|
.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
|
||||||
|
.I2C_Timing = 0x00E0257A, // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10.
|
||||||
|
//.I2C_Timing = 0x8000050B;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (i2c->overClock) {
|
||||||
|
i2cInit.I2C_Timing = 0x00500E30; // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
|
||||||
|
}
|
||||||
|
I2C_Init(I2Cx, &i2cInit);
|
||||||
|
|
||||||
GPIO_StructInit(&GPIO_InitStructure);
|
I2C_Cmd(I2Cx, ENABLE);
|
||||||
I2C_StructInit(&I2C_InitStructure);
|
|
||||||
|
|
||||||
// Init pins
|
|
||||||
|
|
||||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
|
||||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
||||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
|
||||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
|
||||||
|
|
||||||
GPIO_InitStructure.GPIO_Pin = I2C1_SCL_PIN;
|
|
||||||
GPIO_Init(I2C1_SCL_GPIO, &GPIO_InitStructure);
|
|
||||||
|
|
||||||
GPIO_InitStructure.GPIO_Pin = I2C1_SDA_PIN;
|
|
||||||
GPIO_Init(I2C1_SDA_GPIO, &GPIO_InitStructure);
|
|
||||||
|
|
||||||
I2C_StructInit(&I2C_InitStructure);
|
|
||||||
|
|
||||||
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
|
|
||||||
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
|
|
||||||
I2C_InitStructure.I2C_DigitalFilter = 0x00;
|
|
||||||
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
|
|
||||||
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
|
|
||||||
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
|
||||||
|
|
||||||
//I2C_InitStructure.I2C_Timing = 0x00E0257A; // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 100, Hold 10.
|
|
||||||
//I2C_InitStructure.I2C_Timing = 0x0070123D; // 800 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 50, Hold 5.
|
|
||||||
I2C_InitStructure.I2C_Timing = 0x00500E30; // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
|
|
||||||
|
|
||||||
|
|
||||||
I2C_Init(I2C1, &I2C_InitStructure);
|
|
||||||
|
|
||||||
I2C_Cmd(I2C1, ENABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (I2Cx == I2C2) {
|
|
||||||
RCC_AHBPeriphClockCmd(I2C2_SCL_CLK_SOURCE | I2C2_SDA_CLK_SOURCE, ENABLE);
|
|
||||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
|
|
||||||
RCC_I2CCLKConfig(RCC_I2C2CLK_SYSCLK);
|
|
||||||
|
|
||||||
//i2cUnstick(I2Cx); // Clock out stuff to make sure slaves arent stuck
|
|
||||||
|
|
||||||
GPIO_PinAFConfig(I2C2_SCL_GPIO, I2C2_SCL_PIN_SOURCE, I2C2_SCL_GPIO_AF);
|
|
||||||
GPIO_PinAFConfig(I2C2_SDA_GPIO, I2C2_SDA_PIN_SOURCE, I2C2_SDA_GPIO_AF);
|
|
||||||
|
|
||||||
GPIO_StructInit(&GPIO_InitStructure);
|
|
||||||
I2C_StructInit(&I2C_InitStructure);
|
|
||||||
|
|
||||||
// Init pins
|
|
||||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
|
||||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
||||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
|
||||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
|
||||||
|
|
||||||
GPIO_InitStructure.GPIO_Pin = I2C2_SCL_PIN;
|
|
||||||
GPIO_Init(I2C2_SCL_GPIO, &GPIO_InitStructure);
|
|
||||||
|
|
||||||
GPIO_InitStructure.GPIO_Pin = I2C2_SDA_PIN;
|
|
||||||
GPIO_Init(I2C2_SDA_GPIO, &GPIO_InitStructure);
|
|
||||||
|
|
||||||
I2C_StructInit(&I2C_InitStructure);
|
|
||||||
|
|
||||||
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
|
|
||||||
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
|
|
||||||
I2C_InitStructure.I2C_DigitalFilter = 0x00;
|
|
||||||
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
|
|
||||||
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
|
|
||||||
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
|
||||||
|
|
||||||
//I2C_InitStructure.I2C_Timing = 0x00E0257A; // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 100, Hold 10.
|
|
||||||
//I2C_InitStructure.I2C_Timing = 0x0070123D; // 800 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 50, Hold 5.
|
|
||||||
I2C_InitStructure.I2C_Timing = 0x00500E30; // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
|
|
||||||
|
|
||||||
I2C_Init(I2C2, &I2C_InitStructure);
|
|
||||||
|
|
||||||
I2C_Cmd(I2C2, ENABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void i2cInit(I2CDevice index)
|
|
||||||
{
|
|
||||||
if (index == I2CDEV_1) {
|
|
||||||
I2Cx = I2C1;
|
|
||||||
} else {
|
|
||||||
I2Cx = I2C2;
|
|
||||||
}
|
|
||||||
i2cInitPort(I2Cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i2cGetErrorCounter(void)
|
uint16_t i2cGetErrorCounter(void)
|
||||||
{
|
{
|
||||||
if (I2Cx == I2C1) {
|
return i2cErrorCount;
|
||||||
return i2c1ErrorCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return i2c2ErrorCount;
|
bool i2cWriteByDevice(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
addr_ <<= 1;
|
||||||
|
|
||||||
|
I2C_TypeDef *I2Cx;
|
||||||
|
I2Cx = i2cHardwareMap[device].dev;
|
||||||
|
|
||||||
|
/* Test on BUSY Flag */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||||
|
I2C_TransferHandling(I2Cx, addr_, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
|
||||||
|
|
||||||
|
/* Wait until TXIS flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send Register address */
|
||||||
|
I2C_SendData(I2Cx, (uint8_t) reg);
|
||||||
|
|
||||||
|
/* Wait until TCR flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET)
|
||||||
|
{
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||||
|
I2C_TransferHandling(I2Cx, addr_, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
|
||||||
|
|
||||||
|
/* Wait until TXIS flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write data to TXDR */
|
||||||
|
I2C_SendData(I2Cx, data);
|
||||||
|
|
||||||
|
/* Wait until STOPF flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear STOPF flag */
|
||||||
|
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2cReadByDevice(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf)
|
||||||
|
{
|
||||||
|
addr_ <<= 1;
|
||||||
|
|
||||||
|
I2C_TypeDef *I2Cx;
|
||||||
|
I2Cx = i2cHardwareMap[device].dev;
|
||||||
|
|
||||||
|
/* Test on BUSY Flag */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||||
|
I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
|
||||||
|
|
||||||
|
/* Wait until TXIS flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send Register address */
|
||||||
|
I2C_SendData(I2Cx, (uint8_t) reg);
|
||||||
|
|
||||||
|
/* Wait until TC flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||||
|
I2C_TransferHandling(I2Cx, addr_, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
|
||||||
|
|
||||||
|
/* Wait until all data are received */
|
||||||
|
while (len) {
|
||||||
|
/* Wait until RXNE flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read data from RXDR */
|
||||||
|
*buf = I2C_ReceiveData(I2Cx);
|
||||||
|
/* Point to the next location where the byte read will be saved */
|
||||||
|
buf++;
|
||||||
|
|
||||||
|
/* Decrement the read bytes counter */
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait until STOPF flag is set */
|
||||||
|
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||||
|
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
||||||
|
if ((i2cTimeout--) == 0) {
|
||||||
|
return i2cTimeoutUserCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear STOPF flag */
|
||||||
|
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
|
||||||
|
|
||||||
|
/* If all operations OK */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2cWriteBuffer(uint8_t addr_, uint8_t reg_, uint8_t len_, uint8_t *data)
|
||||||
|
{
|
||||||
|
return i2cWriteBufferByDevice(I2Cx_device, addr_, reg_, len_, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2cWrite(uint8_t addr_, uint8_t reg, uint8_t data)
|
bool i2cWrite(uint8_t addr_, uint8_t reg, uint8_t data)
|
||||||
{
|
{
|
||||||
addr_ <<= 1;
|
return i2cWriteByDevice(I2Cx_device, addr_, reg, data);
|
||||||
|
|
||||||
/* Test on BUSY Flag */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
|
||||||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
|
|
||||||
|
|
||||||
/* Wait until TXIS flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send Register address */
|
|
||||||
I2C_SendData(I2Cx, (uint8_t) reg);
|
|
||||||
|
|
||||||
/* Wait until TCR flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET)
|
|
||||||
{
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
|
||||||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
|
|
||||||
|
|
||||||
/* Wait until TXIS flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write data to TXDR */
|
|
||||||
I2C_SendData(I2Cx, data);
|
|
||||||
|
|
||||||
/* Wait until STOPF flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear STOPF flag */
|
|
||||||
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2cRead(uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf)
|
bool i2cRead(uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf)
|
||||||
{
|
{
|
||||||
addr_ <<= 1;
|
return i2cReadByDevice(I2Cx_device, addr_, reg, len, buf);
|
||||||
|
|
||||||
/* Test on BUSY Flag */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
|
||||||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
|
|
||||||
|
|
||||||
/* Wait until TXIS flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send Register address */
|
|
||||||
I2C_SendData(I2Cx, (uint8_t) reg);
|
|
||||||
|
|
||||||
/* Wait until TC flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
|
||||||
I2C_TransferHandling(I2Cx, addr_, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
|
|
||||||
|
|
||||||
/* Wait until all data are received */
|
|
||||||
while (len) {
|
|
||||||
/* Wait until RXNE flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read data from RXDR */
|
|
||||||
*buf = I2C_ReceiveData(I2Cx);
|
|
||||||
/* Point to the next location where the byte read will be saved */
|
|
||||||
buf++;
|
|
||||||
|
|
||||||
/* Decrement the read bytes counter */
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait until STOPF flag is set */
|
|
||||||
i2cTimeout = I2C_DEFAULT_TIMEOUT;
|
|
||||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
|
||||||
if ((i2cTimeout--) == 0) {
|
|
||||||
return i2cTimeoutUserCallback(I2Cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear STOPF flag */
|
|
||||||
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
|
|
||||||
|
|
||||||
/* If all operations OK */
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue