#include "I2C_DMA_INTERRUPT.h"
/*
* private variables
*/
uint8_t MPU6050_RX_BUFF[MPU6050_BUFF_SIZE_RX];
uint8_t MPU6050_TX_BUFF[MPU6050_BUFF_SIZE_TX];
// We need only to write the register value for ACC -> 0x3B
uint8_t isNewData = 0;
//For initialization
uint8_t dmaStarted=0;
uint8_t dataReadyMPU=0;
uint8_t tx_finish;
uint8_t interrupt_error=0;
uint8_t i2c_hard_failure=0;
/*
* global functions
*/
uint8_t startMPU6050() {
Fill_Buffer(MPU6050_RX_BUFF,MPU6050_BUFF_SIZE_RX);
MPU6050_TX_BUFF[0]=(uint8_t)ACCEL_ADDR;
uint8_t fail_flag=0;
I2C_I2C_init();
I2C_GPIO_init();
I2C_DMA_init();
//Power ON
fail_flag|=writeI2C(MPU6050_ADDRESS_1,MPU6050_PWR,0x00);
//Power up MPU6050_1
//Gyro Mode
fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1B,MPU6050_GYRO_MODE);
//Gyro Mode: 1000°/s
//Set Sampling mode filtered
fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1A,MPU6050_DLPF);
return
fail_flag;
}
uint8_t restartMPU6050() {
uint8_t fail_flag=0;
dmaStarted=0;
isNewData =0;
i2c_hard_failure=0;
//First solve problems:
unlockI2C();
I2C_I2C_init();
I2C_GPIO_init();
I2C_DMA_init();
//Power ON
fail_flag|=writeI2C(MPU6050_ADDRESS_1,MPU6050_PWR,0x00);
//Power up MPU6050_1
//Gyro Mode
fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1B,MPU6050_GYRO_MODE);
//Gyro Mode: 1000°/s
//Set Sampling mode filtered
fail_flag|=writeI2C(MPU6050_ADDRESS_1,0x1A,MPU6050_DLPF);
/*int a1=0;
int a2=0;
readI2C1(MPU6050_ADDRESS_1,0,ACCEL_ADDR,&a1);
readI2C1(MPU6050_ADDRESS_1,0,ACCEL_ADDR,&a2);
int a = (a1<<8)|a2;*/
return
fail_flag;
}
void
unlockI2C() {
/*GPIO_InitTypeDef gpioInit;
gpioInit.GPIO_Pin = I2Cx_SCL_PIN;
gpioInit.GPIO_Mode = GPIO_Mode_OUT;
gpioInit.GPIO_Speed = GPIO_Speed_100MHz;
gpioInit.GPIO_OType = GPIO_OType_OD;
gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);*/
GPIO_InitTypeDef gpioInit;
gpioInit.GPIO_Pin = I2Cx_SCL_PIN;
gpioInit.GPIO_Mode = GPIO_Mode_OUT;
gpioInit.GPIO_Speed = GPIO_Speed_100MHz;
gpioInit.GPIO_OType = GPIO_OType_OD;
gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);
gpioInit.GPIO_Pin = I2Cx_SDA_PIN;
gpioInit.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);
uint8_t j=GPIO_ReadInputDataBit(GPIOB, I2Cx_SDA_PIN);
while
(j==0) {
GPIO_ToggleBits(GPIOB, I2Cx_SCL_PIN);
for
(
int
i=0;i<1000;i++);
//little delay
j=GPIO_ReadInputDataBit(GPIOB, I2Cx_SDA_PIN);
}
I2C_stop();
}
void
I2C_I2C_init(
void
) {
I2C_Cmd(I2C2, DISABLE);
I2C_DeInit(I2C2);
I2C_InitTypeDef i2cInit;
clearAllI2CFlags();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE);
RCC_AHB1PeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE);
RCC_AHB1PeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE);
RCC_APB1PeriphResetCmd(I2Cx_CLK, ENABLE);
RCC_APB1PeriphResetCmd(I2Cx_CLK, DISABLE);
RCC_AHB1PeriphClockCmd(DMAx_CLK, ENABLE);
// configure I2C2
i2cInit.I2C_ClockSpeed = 400000;
i2cInit.I2C_Mode = I2C_Mode_I2C;
i2cInit.I2C_DutyCycle = I2C_DutyCycle_2;
// 50% duty cycle
i2cInit.I2C_OwnAddress1 = 0x00;
// own address
i2cInit.I2C_Ack = I2C_Ack_Enable;
i2cInit.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
// set address length to 7 bit addresses
I2C_Init(I2C2, &i2cInit);
// enable I2C2
I2C_Cmd(I2C2, ENABLE);
//I2C Interrupt Routine -> For events
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//GIVE HIGHEST PRIORITY FOR ALL INTERRUPTS
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void
I2C_GPIO_init() {
GPIO_InitTypeDef gpioInit;
gpioInit.GPIO_Pin = I2Cx_SCL_PIN;
gpioInit.GPIO_Mode = GPIO_Mode_AF;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_OType = GPIO_OType_OD;
gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(I2Cx_SCL_GPIO_PORT, &gpioInit);
gpioInit.GPIO_Pin = I2Cx_SDA_PIN;
GPIO_Init(I2Cx_SDA_GPIO_PORT, &gpioInit);
GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, I2Cx_SCL_AF);
GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, I2Cx_SDA_AF);
}
void
I2C_DMA_init() {
// From the ST Standard Peripheral Library Example for I2C
NVIC_InitTypeDef nvicInit;
DMA_InitTypeDef dmaInit;
//Clear all flags and deinit before initialization
DMA_ClearFlag(MPU6050_DMA_STREAM_RX, I2Cx_RX_DMA_TCFLAG | I2Cx_RX_DMA_FEIFLAG | I2Cx_RX_DMA_DMEIFLAG | \
I2Cx_RX_DMA_TEIFLAG | I2Cx_RX_DMA_HTIFLAG);
DMA_ClearFlag(MPU6050_DMA_STREAM_TX, I2Cx_TX_DMA_TCFLAG | I2Cx_TX_DMA_FEIFLAG | I2Cx_TX_DMA_DMEIFLAG | \
I2Cx_TX_DMA_TEIFLAG | I2Cx_TX_DMA_HTIFLAG);
DMA_Cmd(MPU6050_DMA_STREAM_RX, DISABLE);
DMA_Cmd(MPU6050_DMA_STREAM_TX, DISABLE);
DMA_DeInit(MPU6050_DMA_STREAM_RX);
DMA_DeInit(MPU6050_DMA_STREAM_TX);
// Initialization DMA
dmaInit.DMA_Channel = MPU6050_DMA_CHANNEL;
dmaInit.DMA_PeripheralBaseAddr = (uint32_t)MPU6050_DR_ADDRESS;
dmaInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dmaInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
dmaInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dmaInit.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dmaInit.DMA_Mode = DMA_Mode_Normal;
dmaInit.DMA_Priority = DMA_Priority_VeryHigh;
dmaInit.DMA_FIFOMode = DMA_FIFOMode_Enable;
dmaInit.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
dmaInit.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dmaInit.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
//Init DMA Receiver
dmaInit.DMA_DIR = DMA_DIR_PeripheralToMemory;
dmaInit.DMA_Memory0BaseAddr = (uint32_t)MPU6050_RX_BUFF;
dmaInit.DMA_BufferSize = MPU6050_BUFF_SIZE_RX;
DMA_DeInit(MPU6050_DMA_STREAM_RX);
DMA_Init(MPU6050_DMA_STREAM_RX, &dmaInit);
DMA_ITConfig(MPU6050_DMA_STREAM_RX, DMA_IT_TC, ENABLE);
//Init DMA transmitter
dmaInit.DMA_DIR = DMA_DIR_MemoryToPeripheral;
dmaInit.DMA_Memory0BaseAddr = (uint32_t)MPU6050_TX_BUFF;
dmaInit.DMA_BufferSize = MPU6050_BUFF_SIZE_TX;
DMA_DeInit(MPU6050_DMA_STREAM_TX);
DMA_Init(MPU6050_DMA_STREAM_TX, &dmaInit);
DMA_ITConfig(MPU6050_DMA_STREAM_TX, DMA_IT_TC, ENABLE);
// DMA Interrupt initialization
nvicInit.NVIC_IRQChannel = DMA1_Stream2_IRQn;
//RX Interrupt
nvicInit.NVIC_IRQChannelPreemptionPriority = 1;
nvicInit.NVIC_IRQChannelSubPriority = 1;
nvicInit.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicInit);
nvicInit.NVIC_IRQChannel = DMA1_Stream7_IRQn;
//TX Interrupt
NVIC_Init(&nvicInit);
DMA_ClearFlag(DMA1_Stream2, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
DMA_Cmd(DMA1_Stream2, ENABLE);
DMA_ClearFlag(DMA1_Stream7, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
DMA_Cmd(DMA1_Stream7, ENABLE);
}
void
Fill_Buffer(uint8_t *pBuffer, uint16_t BufferLength) {
uint16_t index = 0;
for
(index = 0; index < BufferLength; index++ )
{
pBuffer[index] = 0x00;
}
}
void
recovery() {
I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
I2C_ClearFlag(I2C2, I2C_FLAG_STOPF);
I2C_Cmd(I2C2,ENABLE);
I2C_Cmd(I2C2, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);
I2C_DMACmd(I2Cx,DISABLE);
DMA_Cmd(MPU6050_DMA_STREAM_RX, DISABLE);
DMA_ClearFlag(MPU6050_DMA_STREAM_RX, I2Cx_RX_DMA_TCFLAG | I2Cx_RX_DMA_FEIFLAG | I2Cx_RX_DMA_DMEIFLAG | \
I2Cx_RX_DMA_TEIFLAG | I2Cx_RX_DMA_HTIFLAG);
DMA_Cmd(MPU6050_DMA_STREAM_TX, DISABLE);
DMA_ClearFlag(MPU6050_DMA_STREAM_TX, I2Cx_TX_DMA_TCFLAG | I2Cx_TX_DMA_FEIFLAG | I2Cx_TX_DMA_DMEIFLAG | \
I2Cx_TX_DMA_TEIFLAG | I2Cx_TX_DMA_HTIFLAG);
/*unlockI2C();
dmaStarted=0;
isNewData =0;
i2c_hard_failure=0;*/
}
void
DMA1_Stream2_IRQHandler(
void
) {
if
(DMA_GetFlagStatus(MPU6050_DMA_CHANNEL,DMA_FLAG_TCIF2)) {
DMA_ClearITPendingBit(MPU6050_DMA_CHANNEL, DMA_FLAG_TCIF2);
I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);
DMA_Cmd(MPU6050_DMA_STREAM_RX, DISABLE);
I2C_DMACmd(I2Cx,DISABLE);
DMA_ClearFlag(MPU6050_DMA_STREAM_RX, I2Cx_RX_DMA_TCFLAG | I2Cx_RX_DMA_FEIFLAG | I2Cx_RX_DMA_DMEIFLAG | \
I2Cx_RX_DMA_TEIFLAG | I2Cx_RX_DMA_HTIFLAG);
isNewData=1;
dmaStarted=0;
}
}
void
DMA1_Stream7_IRQHandler(
void
) {
if
(DMA_GetFlagStatus(MPU6050_DMA_CHANNEL,DMA_FLAG_TCIF7)) {
DMA_ClearITPendingBit(MPU6050_DMA_CHANNEL, DMA_FLAG_TCIF7);
I2C_DMACmd(I2Cx, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);
DMA_Cmd(MPU6050_DMA_STREAM_TX, DISABLE);
DMA_ClearFlag(MPU6050_DMA_STREAM_TX, I2Cx_TX_DMA_TCFLAG | I2Cx_TX_DMA_FEIFLAG | I2Cx_TX_DMA_DMEIFLAG | \
I2Cx_TX_DMA_TEIFLAG | I2Cx_TX_DMA_HTIFLAG);
DMARead();
//Activate Read after successfully transfered register read command
}
}
void
clearAllI2CFlags() {
I2C_ClearITPendingBit(I2C2,I2C_IT_SMBALERT);
I2C_ClearITPendingBit(I2C2,I2C_IT_TIMEOUT);
I2C_ClearITPendingBit(I2C2,I2C_IT_PECERR);
I2C_ClearITPendingBit(I2C2,I2C_IT_OVR);
I2C_ClearITPendingBit(I2C2,I2C_IT_AF);
I2C_ClearITPendingBit(I2C2,I2C_IT_ARLO);
I2C_ClearITPendingBit(I2C2,I2C_IT_BERR);
I2C_ClearITPendingBit(I2C2,I2C_IT_TXE);
I2C_ClearITPendingBit(I2C2,I2C_IT_RXNE);
I2C_ClearITPendingBit(I2C2,I2C_IT_STOPF);
I2C_ClearITPendingBit(I2C2,I2C_IT_ADD10);
I2C_ClearITPendingBit(I2C2,I2C_IT_BTF);
I2C_ClearITPendingBit(I2C2,I2C_IT_ADDR);
I2C_ClearITPendingBit(I2C2,I2C_IT_SB);
I2C_ClearFlag(I2C2,I2C_FLAG_SMBALERT);
I2C_ClearFlag(I2C2,I2C_FLAG_TIMEOUT);
I2C_ClearFlag(I2C2,I2C_FLAG_PECERR);
I2C_ClearFlag(I2C2,I2C_FLAG_OVR);
I2C_ClearFlag(I2C2,I2C_FLAG_AF);
I2C_ClearFlag(I2C2,I2C_FLAG_ARLO);
I2C_ClearFlag(I2C2,I2C_FLAG_BERR);
I2C_ClearFlag(I2C2,I2C_FLAG_TXE);
I2C_ClearFlag(I2C2,I2C_FLAG_RXNE);
I2C_ClearFlag(I2C2,I2C_FLAG_STOPF);
I2C_ClearFlag(I2C2,I2C_FLAG_ADD10);
I2C_ClearFlag(I2C2,I2C_FLAG_BTF);
I2C_ClearFlag(I2C2,I2C_FLAG_ADDR);
I2C_ClearFlag(I2C2,I2C_FLAG_SB);
I2C_ClearFlag(I2C2,I2C_FLAG_DUALF);
I2C_ClearFlag(I2C2,I2C_FLAG_SMBHOST);
I2C_ClearFlag(I2C2,I2C_FLAG_SMBDEFAULT);
I2C_ClearFlag(I2C2,I2C_FLAG_GENCALL);
I2C_ClearFlag(I2C2,I2C_FLAG_TRA);
I2C_ClearFlag(I2C2,I2C_FLAG_BUSY);
I2C_ClearFlag(I2C2,I2C_FLAG_MSL);
}
void
I2C2_EV_IRQHandler(
void
)
{
switch
(I2C_GetLastEvent(I2C2))
{
case
I2C_EVENT_MASTER_MODE_SELECT :
if
(!tx_finish) {
I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS_1, I2C_Direction_Transmitter);
I2C_DMACmd(I2Cx, ENABLE);
}
else
{
I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS_1, I2C_Direction_Receiver);
I2C_DMACmd(I2Cx, ENABLE);
}
interrupt_error=0;
break
;
case
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
DMA_Cmd(MPU6050_DMA_STREAM_TX, ENABLE);
break
;
case
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
DMA_Cmd(MPU6050_DMA_STREAM_RX, ENABLE);
I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
break
;
case
I2C_EVENT_SLAVE_STOP_DETECTED :
break
;
case
I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
break
;
case
I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
break
;
case
I2C_EVENT_SLAVE_ACK_FAILURE:
break
;
case
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
break
;
case
I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:
break
;
case
I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED:
break
;
case
I2C_EVENT_SLAVE_BYTE_RECEIVED:
break
;
case
I2C_EVENT_MASTER_BYTE_RECEIVED:
break
;
case
I2C_EVENT_MASTER_BYTE_TRANSMITTING:
break
;
case
I2C_EVENT_MASTER_BYTE_TRANSMITTED:
break
;
case
I2C_EVENT_MASTER_MODE_ADDRESS10:
break
;
case
I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:
break
;
default
:
interrupt_error++;
if
(interrupt_error>10) {
i2c_hard_failure=1;
recovery();
clearAllI2CFlags();
interrupt_error=0;
}
break
;
}
}
uint8_t copyNewAccData(MPU6050Data *dataStruct, MPU6050DataOffset *offset, uint8_t sensor_numb) {
if
(isNewData) {
int
accX=(MPU6050_RX_BUFF[0]<<8) | MPU6050_RX_BUFF[1];
int
accY=(MPU6050_RX_BUFF[2]<<8) | MPU6050_RX_BUFF[3];
int
accZ=(MPU6050_RX_BUFF[4]<<8) | MPU6050_RX_BUFF[5];
int
temp=(MPU6050_RX_BUFF[6]<<8) | MPU6050_RX_BUFF[7];
int
gyroX=(MPU6050_RX_BUFF[8]<<8) | MPU6050_RX_BUFF[9];
int
gyroY=(MPU6050_RX_BUFF[10]<<8) | MPU6050_RX_BUFF[11];
//int gyroZ=(MPU6050_RX_BUFF[12]<<8) | MPU6050_RX_BUFF[13];
if
(accX>32768)
accX=accX-65546;
if
(accY>32768)
accY=accY-65546;
if
(accZ>32768)
accZ=accZ-65546;
if
(gyroX>=32768)
gyroX=gyroX-65546;
if
(gyroY>=32768)
gyroY=gyroY-65546;
/*if(gyroZ>32768)
gyroZ=gyroZ-65546;*/
dataStruct->dataAccX = accX - offset->dataAccXOffset;
//- offset->dataAccXOffset;
dataStruct->dataAccY = accY - offset->dataAccYOffset;
//- offset->dataAccYOffset;
dataStruct->dataAccZ = accZ - offset->dataAccZOffset;
dataStruct->dataGyroX= gyroX - offset->dataGyroXOffset;
// - offset->dataGyroXOffset;
dataStruct->dataGyroY= gyroY - offset->dataGyroYOffset;
//- offset->dataGyroYOffset;
//dataStruct->dataGyroZ=gyroZ;
isNewData=0;
return
0;
}
else
{
return
2;
}
}
uint8_t DMAInitRead() {
if
(i2c_hard_failure)
return
1;
if
(!isNewData && !dmaStarted) {
dmaStarted=1;
tx_finish=0;
I2C_GenerateSTART(I2Cx, ENABLE);
I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE);
/*while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) {
}*/
return
0;
}
return
0;
}
uint8_t DMARead() {
//Start DMA Read process:
I2C_DMALastTransferCmd(I2Cx, ENABLE);
//Enable automatic NACK
I2C_GenerateSTART(I2Cx, ENABLE);
tx_finish=1;
return
0;
}
//FUNCTIONS WITHOUT DMA: USE ONLY FOR INITIALIZATION
uint8_t readI2C1(uint8_t addr, uint8_t dir, uint8_t reg, uint8_t *data) {
uint8_t fail_flag=0;
fail_flag|=I2C_start(addr, 0, 0);
//dir==0 is transmitter, no ack since only one write
fail_flag|=I2C_write(reg);
I2C_stop();
fail_flag|=I2C_start(addr, 1, 0);
//switch to receiver mode
I2C_read_nack1(data);
return
fail_flag;
}
uint8_t I2C_read_ack1(uint8_t *data){
uint16_t timeout = 20000;
//Wait maximum 20000 cycles
I2C_AcknowledgeConfig(I2C2, ENABLE);
while
( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) ) {
if
(--timeout == 0) {
return
1;
}
}
// read data from I2C data register and return data byte
*data = I2C_ReceiveData(I2C2);
return
0;
}
uint8_t I2C_read_nack1(uint8_t *data) {
uint16_t timeout = 20000;
//Wait maximum 20000 cycles
I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
while
( !I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) ) {
if
(--timeout == 0) {
return
1;
}
}
*data = I2C_ReceiveData(I2C2);
return
0;
}
uint8_t writeI2C(uint8_t addr, uint8_t reg, uint8_t data) {
uint8_t fail_flag=0;
fail_flag|=I2C_start(addr, 0, 0);
//dir==0 is transmitter, no ack since only one write
fail_flag|=I2C_write(reg);
fail_flag|=I2C_write(data);
I2C_stop();
return
fail_flag;
}
uint8_t I2C_start(uint8_t address, uint8_t direction, uint8_t ack) {
//direction transmitter==0
uint16_t timeout = TIMEOUT;
//Wait maximum 20000 cycles
while
(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)) {
if
(--timeout == 0) {
return
1;
}
}
I2C_GenerateSTART(I2C2, ENABLE);
while
(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) {
if
(--timeout == 0) {
return
1;
}
}
//Ack enable
if
(ack)
I2C2->CR1 |= I2C_CR1_ACK;
//Send Adress
I2C_Send7bitAddress(I2C2, address, direction);
while
(!(I2C2->SR1 & I2C_SR1_ADDR)) {
//Wait until Address is received by slave
if
(--timeout == 0) {
return
1;
}
}
if
(direction == I2C_Direction_Transmitter){
while
(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
if
(--timeout == 0) {
return
1;
}
}
}
else
if
(direction == I2C_Direction_Receiver){
while
(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
if
(--timeout == 0) {
return
1;
}
}
}
/* Read status register to clear ADDR flag */
I2C2->SR2;
return
0;
}
uint8_t I2C_write(uint8_t data) {
uint16_t timeout = TIMEOUT;
//Wait maximum 20000 cycles
I2C_SendData(I2C2, data);
while
(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
if
(--timeout == 0) {
return
1;
}
}
return
0;
}
void
I2C_stop() {
I2C_GenerateSTOP(I2C2, ENABLE);
}
void
initOffset(MPU6050DataOffset *offset) {
offset->dataAccXOffset=0;
offset->dataAccYOffset=0;
offset->dataAccZOffset=0;
offset->dataGyroXOffset=0;
offset->dataGyroYOffset=0;
offset->dataGyroZOffset=0;
}
void
setOffset(MPU6050Data *MPU1, MPU6050DataOffset *MPU1_Offset) {
MPU1_Offset->dataAccXOffset=MPU1->dataAccX;
MPU1_Offset->dataAccYOffset=MPU1->dataAccY;
MPU1_Offset->dataAccZOffset=MPU1->dataAccZ;
MPU1_Offset->dataGyroXOffset=MPU1->dataGyroX;
MPU1_Offset->dataGyroYOffset=MPU1->dataGyroY;
}