void i2cMgr_t::ReadMany() {
// Enable Acknowledgement
I2C_AcknowledgeConfig(I2C1, ENABLE);
// Prepare DMA
DMA_DeInit(I2C_DMA_CHNL_RX);
DMA_InitTypeDef DMA_InitStructure;
//DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &I2C1->DR;
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40005410;
// Decide where to read data to
if(CmdToRead->DataToRead.Buf == 0) { // no need in this data
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CmdToRead->DataToRead.InnerBuf[0]; // dummy place
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // Do not move pointer
}
else {
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CmdToRead->DataToRead.Buf[0];
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
}
DMA_InitStructure.DMA_BufferSize = CmdToRead->DataToRead.Length;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // From I2C to memory
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(I2C_DMA_CHNL_RX, &DMA_InitStructure);
//Inform the DMA that the next End Of Transfer Signal will be the last one, need to send NACK after last byte
I2C_DMALastTransferCmd(I2C1, ENABLE);
// Start transmission
I2C_DMACmd(I2C1, ENABLE); // Enable DMA
DMA_Cmd(I2C_DMA_CHNL_RX, ENABLE); // Enable DMA channel
Delay.Reset(&Timer);
}
void I2C_DMA_Read(u8 slaveAddr, u8 readAddr)
{
/* Disable DMA channel*/
DMA_Cmd(DMA1_Channel7, DISABLE);
/* Set current data number again to 14 for MPu6050, only possible after disabling the DMA channel */
DMA_SetCurrDataCounter(DMA1_Channel7, 14);
/* While the bus is busy */
while(I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_BUSY));
/* Enable DMA NACK automatic generation */
I2C_DMALastTransferCmd(MPU6050_I2C, ENABLE); //Note this one, very important
/* Send START condition */
I2C_GenerateSTART(MPU6050_I2C, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_MODE_SELECT));
/* Send MPU6050 address for write */
I2C_Send7bitAddress(MPU6050_I2C, slaveAddr, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(MPU6050_I2C, ENABLE);
/* Send the MPU6050's internal address to write to */
I2C_SendData(MPU6050_I2C, readAddr);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send STRAT condition a second time */
I2C_GenerateSTART(MPU6050_I2C, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_MODE_SELECT));
/* Send MPU6050 address for read */
I2C_Send7bitAddress(MPU6050_I2C, slaveAddr, I2C_Direction_Receiver);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* Start DMA to receive data from I2C */
DMA_Cmd(DMA1_Channel7, ENABLE);
I2C_DMACmd(MPU6050_I2C, ENABLE);
// When the data transmission is complete, it will automatically jump to DMA interrupt routine to finish the rest.
//now go back to the main routine
}
void i2c_dma_read( u8 read_addr)
{
// read_addr +=1;
//disable dma channel
DMA_Cmd( MPU6050_DMA_CHANNEL, DISABLE);
//? set current data number again to 14
DMA_SetCurrDataCounter(MPU6050_DMA_CHANNEL, 14);
//while the bus is busy
while( I2C_GetFlagStatus( MPU6050_I2C,I2C_FLAG_BUSY));
//enable dma nack automatic generation.....
I2C_DMALastTransferCmd( MPU6050_I2C, ENABLE);
//send start condition
I2C_GenerateSTART( MPU6050_I2C, ENABLE);
//test on ev5 and clear it
while( !I2C_CheckEvent( MPU6050_I2C, I2C_EVENT_MASTER_MODE_SELECT));
//send mpu6050 address for write
I2C_Send7bitAddress( MPU6050_I2C, I2C1_MPU6050, I2C_Direction_Transmitter );
//test on ev6 and clear it
while( !I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//clear ev6 by setting again the PE bit
I2C_Cmd( MPU6050_I2C,ENABLE);
//send the mpu6050 internal address to write to
I2C_SendData( MPU6050_I2C, read_addr);
//test on ev8 and clear it
while(!I2C_CheckEvent( MPU6050_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
//send start condition a second time
I2C_GenerateSTART(MPU6050_I2C, ENABLE);
//test on ev5 and clear it
while( !I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_MODE_SELECT));
//send mpu6050 address for read
I2C_Send7bitAddress(MPU6050_I2C,I2C1_MPU6050, I2C_Direction_Receiver);
//test on ev6 and clear it
while( !I2C_CheckEvent( MPU6050_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
//start dma to receive data from i2c
DMA_Cmd(MPU6050_DMA_CHANNEL, ENABLE);
I2C_DMACmd(MPU6050_I2C, ENABLE);
//when the data transmission is complete, it will automatically jump to dma interrupt routine
//to finish the rest.
}
//.........这里部分代码省略.........
I2C_DMACmd(I2Cx, DISABLE);
/* Wait until BTF Flag is set before generating STOP or time out */
TimeOut = USER_TIMEOUT;
while ((!I2C_GetFlagStatus(I2Cx,I2C_FLAG_BTF))&&(TimeOut != 0x00))
{}
if(TimeOut == 0)
{
TimeOut_UserCallback();
}
/* Send I2Cx STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
/* Disable DMA TX Channel */
DMA_Cmd(I2Cx_DMA_STREAM_TX, DISABLE);
/* Wait until I2Cx_DMA_STREAM_TX disabled or time out */
TimeOut = USER_TIMEOUT;
while ((DMA_GetCmdStatus(I2Cx_DMA_STREAM_TX)!= DISABLE)&&(TimeOut != 0x00))
{}
if(TimeOut == 0)
{
TimeOut_UserCallback();
}
/* Clear any pending flag on Tx Stream */
DMA_ClearFlag(I2Cx_DMA_STREAM_TX, I2Cx_TX_DMA_TCFLAG | I2Cx_TX_DMA_FEIFLAG | I2Cx_TX_DMA_DMEIFLAG | \
I2Cx_TX_DMA_TEIFLAG | I2Cx_TX_DMA_HTIFLAG);
/* Master Receiver -----------------------------------------------------------*/
/* Enable DMA NACK automatic generation */
I2C_DMALastTransferCmd(I2Cx, ENABLE);
/* Send I2Cx START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
#ifdef I2C_10BITS_ADDRESS
/* Test on EV5 and clear it or time out */
TimeOut = USER_TIMEOUT;
while ((!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))&&(TimeOut != 0x00))
{}
if(TimeOut == 0)
{
TimeOut_UserCallback();
}
/* Send Header to Slave for write */
I2C_SendData(I2Cx, HEADER_ADDRESS_Write);
/* Test on EV9 and clear it or time out */
TimeOut = USER_TIMEOUT;
while ((!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_ADDRESS10))&&(TimeOut != 0x00))
{}
if(TimeOut == 0)
{
TimeOut_UserCallback();
}
/* Send slave Address */
I2C_Send7bitAddress(I2Cx, (uint8_t)SLAVE_ADDRESS, I2C_Direction_Transmitter);
/* Test on I2Cx EV6 and clear it or time out*/
TimeOut = USER_TIMEOUT;
while ((!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&&(TimeOut != 0x00))
{}
if(TimeOut == 0)
//.........这里部分代码省略.........
sEEDataReadPointer = NumByteToRead;
/*!< While the bus is busy */
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
{
}
/*!< Send START condition */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/*!< Test on EV5 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
}
/*!< Send EEPROM address for write */
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
/*!< Test on EV6 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
}
#ifdef sEE_M24C08
/*!< Send the EEPROM's internal address to read from: Only one byte address */
I2C_SendData(sEE_I2C, ReadAddr);
#elif defined (sEE_M24C64_32)
/*!< Send the EEPROM's internal address to read from: MSB of the address first */
I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
/*!< Test on EV8 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
}
/*!< Send the EEPROM's internal address to read from: LSB of the address */
I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));
#endif /*!< sEE_M24C08 */
/*!< Test on EV8 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
}
/*!< Send STRAT condition a second time */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/*!< Test on EV5 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
}
/*!< Send EEPROM address for read */
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver);
/*!< Test on EV6 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
}
/* If number of data to be read is 1, then DMA couldn't be used */
if ((uint16_t)(*NumByteToRead) < 2)
{
/*!< Disable Acknowledgement */
I2C_AcknowledgeConfig(sEE_I2C, DISABLE);
/*!< Send STOP Condition */
I2C_GenerateSTOP(sEE_I2C, ENABLE);
/*!< Test on EV7 and clear it */
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
{
}
/*!< Read a byte from the EEPROM */
*pBuffer = I2C_ReceiveData(sEE_I2C);
/*!< Decrement the read bytes counter */
(uint16_t)(*NumByteToRead)--;
/*!< Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(sEE_I2C, ENABLE);
}
/* DMA could be used for number of data higher than 1 */
else
{
/* Configure the DMA Rx Channel with the buffer address and the buffer size */
sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX);
/* Inform the DMA that the next End Of Transfer Signal will be the last one */
I2C_DMALastTransferCmd(sEE_I2C, ENABLE);
/* Enable the DMA Rx Channel */
DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, ENABLE);
}
}
//.........这里部分代码省略.........
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
I2C_SendData(dev->I2Cx, *tx_buff++);
// Test on EV8 and clear it
dev->timeout = sEE_FLAG_TIMEOUT;
while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_BTF ) == RESET)
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
// Send STRAT condition a second time
I2C_GenerateSTART(dev->I2Cx, ENABLE);
// Test on EV5 and clear it (cleared by reading SR1 then writing to DR)
dev->timeout = sEE_FLAG_TIMEOUT;
while (!I2C_CheckEvent(dev->I2Cx, I2C_EVENT_MASTER_MODE_SELECT ))
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
// Send address for read
I2C_Send7bitAddress(dev->I2Cx, addr, I2C_Direction_Receiver );
if ((uint16_t)(*rxlen) < 2)
{
dev->timeout = sEE_FLAG_TIMEOUT;
while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_ADDR ) == RESET)
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
// Disable Acknowledgement
I2C_AcknowledgeConfig(dev->I2Cx, DISABLE);
/* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
(void) dev->I2Cx->SR2;
/*!< STOP condition */
I2C_GenerateSTOP(dev->I2Cx, DISABLE);
I2C_ClearFlag(dev->I2Cx, I2C_FLAG_STOPF );
/* Send STOP condition */
I2C_GenerateSTOP(dev->I2Cx, ENABLE);
/* Wait for the byte to be received */
dev->timeout = sEE_FLAG_TIMEOUT;
while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_RXNE ) == RESET)
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
/*!< Read the byte received from the EEPROM */
*buffer8 = I2C_ReceiveData(dev->I2Cx);
(uint16_t)(*rxlen)--;
/* Wait to make sure that STOP control bit has been cleared */
dev->timeout = sEE_FLAG_TIMEOUT;
while (dev->I2Cx->CR1 & I2C_CR1_STOP )
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
// Re-Enable Acknowledgement to be ready for another reception
I2C_AcknowledgeConfig(dev->I2Cx, ENABLE);
}
else/* More than one Byte Master Reception procedure (DMA) -----------------*/
{
/*!< Test on EV6 and clear it */
dev->timeout = sEE_FLAG_TIMEOUT;
while (!I2C_CheckEvent(dev->I2Cx,
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ))
{
if ((dev->timeout--) == 0)
return I2C_ERROR;
}
/* Configure the DMA Rx Channel with the buffer address and the buffer size */
sEE_LowLevel_DMAConfig(dev, (uint32_t) buffer8, (uint16_t)(*rxlen),
sEE_DIRECTION_RX);
/* Inform the DMA that the next End Of Transfer Signal will be the last one */
I2C_DMALastTransferCmd(dev->I2Cx, ENABLE);
/* Enable the DMA Rx Stream */
if (dev->I2Cx == I2C1){
DMA_Cmd(sEE_I2C1_DMA_STREAM_RX, ENABLE);
} else if(dev->I2Cx == I2C2){
DMA_Cmd(sEE_I2C2_DMA_STREAM_RX, ENABLE);
}
/* Enable the sEE_I2C peripheral DMA requests */
I2C_DMACmd(dev->I2Cx, ENABLE);
}
return I2C_OK;
}
开发者ID:136048599,项目名称:vrbrain,代码行数:101,代码来源:i2c.c
示例15: LM75_ShutDown
/**
* @brief Enables or disables the LM75.
* @param NewState: specifies the LM75 new status. This parameter can be ENABLE
* or DISABLE.
* @retval None
*/
uint8_t LM75_ShutDown(FunctionalState NewState)
{
uint8_t LM75_BufferRX[2] ={0,0};
uint8_t LM75_BufferTX = 0;
__IO uint8_t RegValue = 0;
/* Test on BUSY Flag */
LM75_Timeout = LM75_LONG_TIMEOUT;
while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Configure DMA Peripheral */
LM75_DMA_Config(LM75_DMA_RX, (uint8_t*)LM75_BufferRX, 2);
/* Enable DMA NACK automatic generation */
I2C_DMALastTransferCmd(LM75_I2C, ENABLE);
/* Enable the I2C peripheral */
I2C_GenerateSTART(LM75_I2C, ENABLE);
/* Test on SB Flag */
LM75_Timeout = LM75_FLAG_TIMEOUT;
while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Send device address for write */
I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);
/* Test on ADDR Flag */
LM75_Timeout = LM75_FLAG_TIMEOUT;
while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Send the device's internal address to write to */
I2C_SendData(LM75_I2C, LM75_REG_CONF);
/* Test on TXE FLag (data sent) */
LM75_Timeout = LM75_FLAG_TIMEOUT;
while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF)))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Send START condition a second time */
I2C_GenerateSTART(LM75_I2C, ENABLE);
/* Test on SB Flag */
LM75_Timeout = LM75_FLAG_TIMEOUT;
while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Send LM75 address for read */
I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);
/* Test on ADDR Flag */
LM75_Timeout = LM75_FLAG_TIMEOUT;
while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Enable I2C DMA request */
I2C_DMACmd(LM75_I2C,ENABLE);
/* Enable DMA RX Channel */
DMA_Cmd(LM75_DMA_RX_CHANNEL, ENABLE);
/* Wait until DMA Transfer Complete */
LM75_Timeout = LM75_LONG_TIMEOUT;
while (!DMA_GetFlagStatus(LM75_DMA_RX_TCFLAG))
{
if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback();
}
/* Send STOP Condition */
I2C_GenerateSTOP(LM75_I2C, ENABLE);
/* Disable DMA RX Channel */
DMA_Cmd(LM75_DMA_RX_CHANNEL, DISABLE);
/* Disable I2C DMA request */
I2C_DMACmd(LM75_I2C,DISABLE);
/* Clear DMA RX Transfer Complete Flag */
DMA_ClearFlag(LM75_DMA_RX_TCFLAG);
//.........这里部分代码省略.........
/**
* @brief Reads buffer of bytes from the slave.
* @param pBuffer: Buffer of bytes to read from the slave.
* @param NumByteToRead: Number of bytes to be read by the Master.
* @retval : None.
*/
void I2C_Master_BufferRead(uint8_t* pBuffer, uint16_t NumByteToRead)
{
#ifdef DMA_Master_Receive
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer;
DMA_InitStructure.DMA_BufferSize = NumByteToRead;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
/* Set Last bit to have a NACK on the last received byte */
I2C_DMALastTransferCmd(I2C1, ENABLE);
I2C_DMACmd(I2C1, ENABLE);
/* Enable the DMA Channel7 Transfer Complete IT */
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
/* Generate the START */
I2C_GenerateSTART(I2C1, ENABLE);
#endif
#ifdef Polling_Master_Receive
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send slave address for read */
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* While there is data to be read; here the safe procedure is implemented */
while (NumByteToRead)
{
if (NumByteToRead != 3) /* Receive bytes from first byte until byte N-3 */
{
while ((I2C_GetLastEvent(I2C1) & 0x00004) != 0x000004); /* Poll on BTF */
/* Read data */
*pBuffer = I2C_ReceiveData(I2C1);
pBuffer++;
/* Decrement the read bytes counter */
NumByteToRead--;
}
if (NumByteToRead == 3) /* it remains to read three data: data N-2, data N-1, Data N */
{
/* Data N-2 in DR and data N -1 in shift register */
while ((I2C_GetLastEvent(I2C1) & 0x000004) != 0x0000004); /* Poll on BTF */
/* Clear ACK */
I2C_AcknowledgeConfig(I2C1, DISABLE);
__disable_irq();
/* Read Data N-2 */
*pBuffer = I2C_ReceiveData(I2C1);
pBuffer++;
/* Program the STOP */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Read DataN-1 */
*pBuffer = I2C_ReceiveData(I2C1);
__enable_irq();
pBuffer++;
while ((I2C_GetLastEvent(I2C1) & 0x00000040) != 0x0000040); /* Poll on RxNE */
/* Read DataN */
*pBuffer = I2C1->DR;
/* Reset the number of bytes to be read by master */
NumByteToRead = 0;
}
}
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((I2C1->CR1&0x200) == 0x200);
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
#endif
}
开发者ID:emmamuelo,项目名称:IPM,代码行数:83,代码来源:driver.c
示例17: sEE_ReadBuffer
//.........这里部分代码省略.........
}
/*!< Send the EEPROM's internal address to read from: MSB of the address first */
I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
/*!< Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send the EEPROM's internal address to read from: LSB of the address */
I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));
/*!< Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send STRAT condition a second time */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send EEPROM address for read */
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver);
/* If number of data to be read is 1, then DMA couldn't be used */
/* One Byte Master Reception procedure (POLLING) ---------------------------*/
if ((uint16_t)(*NumByteToRead) < 2)
{
/* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
sEETimeout = sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Disable Acknowledgement */
I2C_AcknowledgeConfig(sEE_I2C, DISABLE);
/* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
(void)sEE_I2C->SR2;
/*!< Send STOP Condition */
I2C_GenerateSTOP(sEE_I2C, ENABLE);
/* Wait for the byte to be received */
sEETimeout = sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Read the byte received from the EEPROM */
*pBuffer = I2C_ReceiveData(sEE_I2C);
/*!< Decrement the read bytes counter */
(uint16_t)(*NumByteToRead)--;
/* Wait to make sure that STOP control bit has been cleared */
sEETimeout = sEE_FLAG_TIMEOUT;
while(sEE_I2C->CR1 & I2C_CR1_STOP)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Re-Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(sEE_I2C, ENABLE);
}
else/* More than one Byte Master Reception procedure (DMA) -----------------*/
{
/*!< Test on EV6 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Configure the DMA Rx Channel with the buffer address and the buffer size */
sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX);
/* Inform the DMA that the next End Of Transfer Signal will be the last one */
I2C_DMALastTransferCmd(sEE_I2C, ENABLE);
/* Enable the DMA Rx Stream */
DMA_Cmd(sEE_I2C_DMA_STREAM_RX, ENABLE);
}
/* If all operations OK, return sEE_OK (0) */
return sEE_OK;
}
请发表评论