mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-17 05:15:25 +03:00
added softi2c source file (oops)
changed gpio speeds to 2mhz from 50, nothing is toggling at 50mhz here. reduce ringing/noise. git-svn-id: https://afrodevices.googlecode.com/svn/trunk/baseflight@181 7c89a4a9-59b9-e629-4cfe-3a2d53b20e61
This commit is contained in:
parent
23d11299b8
commit
e70d7b5d16
11 changed files with 781 additions and 549 deletions
216
src/drv_i2c_soft.c
Normal file
216
src/drv_i2c_soft.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
#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 = GPIO_Pin_10 /* GPIO_SetBits(GPIOB , GPIO_Pin_10) */
|
||||
#define SCL_L GPIOB->BRR = GPIO_Pin_10 /* GPIO_ResetBits(GPIOB , GPIO_Pin_10) */
|
||||
|
||||
#define SDA_H GPIOB->BSRR = GPIO_Pin_11 /* GPIO_SetBits(GPIOB , GPIO_Pin_11) */
|
||||
#define SDA_L GPIOB->BRR = GPIO_Pin_11 /* GPIO_ResetBits(GPIOB , GPIO_Pin_11) */
|
||||
|
||||
#define SCL_read GPIOB->IDR & GPIO_Pin_10 /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_10) */
|
||||
#define SDA_read GPIOB->IDR & GPIO_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_InitTypeDef gpio;
|
||||
|
||||
gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
|
||||
gpio.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
gpio.GPIO_Mode = GPIO_Mode_Out_OD;
|
||||
GPIO_Init(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
|
Loading…
Add table
Add a link
Reference in a new issue