1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-16 12:55:19 +03:00
betaflight/src/drv_i2c_soft.c
timecop@gmail.com d63c1f0604 Properly set ADXL345 driver default orientation (thx enots)
Fixed compile error in i2c_soft driver which still used old GPIO init syntax.

git-svn-id: https://afrodevices.googlecode.com/svn/trunk/baseflight@451 7c89a4a9-59b9-e629-4cfe-3a2d53b20e61
2013-10-24 11:34:32 +00:00

215 lines
4.1 KiB
C

#include "board.h"
// Software I2C driver, using same pins as hardware I2C, with hw i2c module disabled.
// SCL PB10
// SDA PB11
#ifdef SOFT_I2C
#define SCL_H GPIOB->BSRR = Pin_10 /* GPIO_SetBits(GPIOB , GPIO_Pin_10) */
#define SCL_L GPIOB->BRR = Pin_10 /* GPIO_ResetBits(GPIOB , GPIO_Pin_10) */
#define SDA_H GPIOB->BSRR = Pin_11 /* GPIO_SetBits(GPIOB , GPIO_Pin_11) */
#define SDA_L GPIOB->BRR = Pin_11 /* GPIO_ResetBits(GPIOB , GPIO_Pin_11) */
#define SCL_read (GPIOB->IDR & Pin_10) /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_10) */
#define SDA_read (GPIOB->IDR & Pin_11) /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_11) */
static void I2C_delay(void)
{
volatile int i = 7;
while (i)
i--;
}
static bool I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if (!SDA_read)
return false;
SDA_L;
I2C_delay();
if (SDA_read)
return false;
SDA_L;
I2C_delay();
return true;
}
static void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
static void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
static void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
static bool I2C_WaitAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if (SDA_read) {
SCL_L;
return false;
}
SCL_L;
return true;
}
static void I2C_SendByte(uint8_t byte)
{
uint8_t i = 8;
while (i--) {
SCL_L;
I2C_delay();
if (byte & 0x80)
SDA_H;
else
SDA_L;
byte <<= 1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
static uint8_t I2C_ReceiveByte(void)
{
uint8_t i = 8;
uint8_t byte = 0;
SDA_H;
while (i--) {
byte <<= 1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if (SDA_read) {
byte |= 0x01;
}
}
SCL_L;
return byte;
}
void i2cInit(I2C_TypeDef * I2C)
{
gpio_config_t gpio;
gpio.pin = Pin_10 | Pin_11;
gpio.speed = Speed_2MHz;
gpio.mode = Mode_Out_OD;
gpioInit(GPIOB, &gpio);
}
bool i2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)
{
int i;
if (!I2C_Start())
return false;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return false;
}
I2C_SendByte(reg);
I2C_WaitAck();
for (i = 0; i < len; i++) {
I2C_SendByte(data[i]);
if (!I2C_WaitAck()) {
I2C_Stop();
return false;
}
}
I2C_Stop();
return true;
}
bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data)
{
if (!I2C_Start())
return false;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return false;
}
I2C_SendByte(reg);
I2C_WaitAck();
I2C_SendByte(data);
I2C_WaitAck();
I2C_Stop();
return true;
}
bool i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
{
if (!I2C_Start())
return false;
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
if (!I2C_WaitAck()) {
I2C_Stop();
return false;
}
I2C_SendByte(reg);
I2C_WaitAck();
I2C_Start();
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
I2C_WaitAck();
while (len) {
*buf = I2C_ReceiveByte();
if (len == 1)
I2C_NoAck();
else
I2C_Ack();
buf++;
len--;
}
I2C_Stop();
return true;
}
uint16_t i2cGetErrorCounter(void)
{
// TODO maybe fix this, but since this is test code, doesn't matter.
return 0;
}
#endif