INT08U MPU6050_Read(INT08U addr, INT08U reg, INT08U len, INT08U *buf)
{
OS_ERR err;
CPU_TS ts;
CPU_SR_ALLOC();
INT08U rlen = 0;
INT16U I2CTimeout;
I2CReadState = I2C_CHECK_BUSY;
I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
while(I2C_READ_END > I2CReadState)
{
switch(I2CReadState)
{
case I2C_CHECK_BUSY:
I2CTimeout = I2C_TIMEOUT*((INT16U)(SystemCoreClock/1000000));
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)&&(I2CTimeout--));
if(0 == I2CTimeout) delay_ms(fac_ms);
else
{
CPU_CRITICAL_ENTER();
if(I2C_CHECK_BUSY == I2CReadState) I2CReadState = I2C_SEND_START;//I2C bus is not busy
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
}
break;
case I2C_SEND_START:
I2C_GenerateSTART(I2C1, ENABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
OSSemPend(&MPU6050_SEM, I2C_TIMEOUT*fac_us, OS_OPT_PEND_BLOCKING, &ts, &err);
CPU_CRITICAL_ENTER();
if((OS_ERR_NONE == err) && (I2C_SEND_START == I2CReadState)) I2CReadState = I2C_SEND_ADDR_SEND;
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
break;
case I2C_SEND_ADDR_SEND:
I2C_Send7bitAddress(I2C1, (addr<<1), I2C_Direction_Transmitter);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
OSSemPend(&MPU6050_SEM, I2C_TIMEOUT*fac_us, OS_OPT_PEND_BLOCKING, &ts, &err);
CPU_CRITICAL_ENTER();
if((OS_ERR_NONE == err) && (I2C_SEND_ADDR_SEND == I2CReadState)) I2CReadState = I2C_SELECT_REG;
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
break;
case I2C_SELECT_REG:
I2C_SendData(I2C1, reg);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
OSSemPend(&MPU6050_SEM, I2C_TIMEOUT*fac_us, OS_OPT_PEND_BLOCKING, &ts, &err);
CPU_CRITICAL_ENTER();
if((OS_ERR_NONE == err) && (I2C_SELECT_REG == I2CReadState)) I2CReadState = I2C_CHECK_BUSY_AGAIN;
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
I2C_GenerateSTOP(I2C1, ENABLE);
break;
case I2C_CHECK_BUSY_AGAIN:
I2CTimeout = I2C_TIMEOUT*((INT16U)(SystemCoreClock/1000000));
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)&&(I2CTimeout--));
if(0 == I2CTimeout) delay_ms(fac_ms);
else
{
CPU_CRITICAL_ENTER();
if(I2C_CHECK_BUSY_AGAIN == I2CReadState) I2CReadState = I2C_SEND_START_AGAIN;//I2C bus is not busy
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
}
break;
case I2C_SEND_START_AGAIN:
I2C_GenerateSTART(I2C1, ENABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
OSSemPend(&MPU6050_SEM, I2C_TIMEOUT*fac_us, OS_OPT_PEND_BLOCKING, &ts, &err);
CPU_CRITICAL_ENTER();
if((OS_ERR_NONE == err) && (I2C_SEND_START_AGAIN == I2CReadState)) I2CReadState = I2C_SEND_ADDR_RECV;
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
break;
case I2C_SEND_ADDR_RECV:
I2C_Send7bitAddress(I2C1, (addr<<1), I2C_Direction_Receiver);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
OSSemPend(&MPU6050_SEM, I2C_TIMEOUT*fac_us, OS_OPT_PEND_BLOCKING, &ts, &err);
CPU_CRITICAL_ENTER();
if((OS_ERR_NONE == err) && (I2C_SEND_ADDR_RECV == I2CReadState)) I2CReadState = I2C_RECV_DATA;
else I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
I2C_AcknowledgeConfig(I2C1, ENABLE);
GPIO_SetBits(GPIOB,GPIO_Pin_7);
break;
case I2C_RECV_DATA:
if(len == 1+rlen)
{
I2C_AcknowledgeConfig(I2C1, DISABLE);
(void)I2C1->SR2;
I2C_GenerateSTOP(I2C1, ENABLE);
}
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
OSSemPend(&MPU6050_SEM, I2C_TIMEOUT*fac_us, OS_OPT_PEND_BLOCKING, &ts, &err);
CPU_CRITICAL_ENTER();
if((OS_ERR_NONE != err) || (I2C_RECV_DATA != I2CReadState)) I2CReadState = I2C_READ_END;
CPU_CRITICAL_EXIT();
*buf = I2C_ReceiveData(I2C1);
buf++;
rlen++;
if(len == rlen) I2CReadState = I2C_READ_END;
break;
default:
break;
}
}
I2C_ITConfig(I2C1, I2C_IT_ERR, DISABLE);
return rlen;
}
版权声明:本文为CSDN博主「lalalaxy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/lalalaxy/article/details/86755638