I2C_ReadMultiBytesOneReg 源码看不明白。
这中间的执行流程是如何控制的吗?
uint32_t I2C_ReadMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t au8Rdata[], uint32_t u32rLen)
{
uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
uint32_t u32rxLen = 0u;
I2C_START(i2c); /* Send START */
while(u8Xfering && (u8Err == 0u))
{
I2C_WAIT_READY(i2c) {}
switch(I2C_GET_STATUS(i2c))
{
case 0x08u:
I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
u8Ctrl = I2C_CTL_SI; /* Clear SI */
break;
case 0x18u: /* Slave Address ACK */
I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
break;
case 0x20u: /* Slave Address NACK */
case 0x30u: /* Master transmit data NACK */
u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
u8Err = 1u;
break;
case 0x28u:
u8Ctrl = I2C_CTL_STA_SI; /* Send repeat START */
break;
case 0x10u:
I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
u8Ctrl = I2C_CTL_SI; /* Clear SI */
break;
case 0x40u: /* Slave Address ACK */
u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
break;
case 0x48u: /* Slave Address NACK */
u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
u8Err = 1u;
break;
case 0x50u:
au8Rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
if(u32rxLen < (u32rLen - 1u))
{
u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
}
else
{
u8Ctrl = I2C_CTL_SI; /* Clear SI */
}
break;
case 0x58u:
au8Rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
u8Xfering = 0u;
break;
case 0x38u: /* Arbitration Lost */
default: /* Unknow status */
u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
u8Err = 1u;
break;
}
I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
}
return u32rxLen; /* Return bytes length that have been received */
}
|