- 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;
- }