/**
  * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
  *
  * @note   The number of bytes (combined to write start address) must not 
  *         cross the EEPROM page boundary. This function can only write into
  *         the boundaries of an EEPROM page.
  *         This function doesn't check on boundaries condition (in this driver 
  *         the function sEE_WriteBuffer() which calls sEE_WritePage() is 
  *         responsible of checking on Page boundaries).
  * 
  * @param  pBuffer : pointer to the buffer containing the data to be written to 
  *         the EEPROM.
  * @param  WriteAddr : EEPROM's internal address to write to.
  * @param  NumByteToWrite : pointer to the variable holding number of bytes to 
  *         be written into the EEPROM. 
  * 
  *        @note The variable pointed by NumByteToWrite is reset to 0 when all the 
  *              data are written to the EEPROM. Application should monitor this 
  *              variable in order know when the transfer is complete.
  * 
  * @note This function just configure the communication and enable the DMA 
  *       channel to transfer data. Meanwhile, the user application may perform 
  *       other tasks in parallel.
  * 
  * @retval sEE_OK (0) if operation is correctly performed, else return value 
  *         different from sEE_OK (0) or the timeout user callback.
  */
uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
{ 
  /* Set the pointer to the Number of data to be written. This pointer will be used 
      by the DMA Transfer Completer interrupt Handler in order to reset the 
      variable to 0. User should check on this variable in order to know if the 
      DMA transfer has been complete or not. */
  sEEDataWritePointer = NumByteToWrite;  
  
  /*!< While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send START condition */
  I2C_GenerateSTART(sEE_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it */
  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 write */
  sEETimeout = sEE_FLAG_TIMEOUT;
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);

  /*!< Test on EV6 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send the EEPROM's internal address to write to : MSB of the address first */
  I2C_SendData(sEE_I2C, (uint8_t)((WriteAddr & 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 write to : LSB of the address */
  I2C_SendData(sEE_I2C, (uint8_t)(WriteAddr & 0x00FF));
  
  /*!< 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();
  }  
  
  /* Configure the DMA Tx Channel with the buffer address and the buffer size */
  sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint8_t)(*NumByteToWrite), sEE_DIRECTION_TX);
  
  /* Enable the DMA Tx Stream */
  DMA_Cmd(sEE_I2C_DMA_STREAM_TX, ENABLE);
  
  /* If all operations OK, return sEE_OK (0) */
  return sEE_OK;
}
/**
  * @brief  Reads a block of data from the EEPROM.
  * @param  pBuffer : pointer to the buffer that receives the data read from 
  *         the EEPROM.
  * @param  ReadAddr : EEPROM's internal address to start reading from.
  * @param  NumByteToRead : pointer to the variable holding number of bytes to 
  *         be read from the EEPROM.
  * 
  *        @note The variable pointed by NumByteToRead is reset to 0 when all the 
  *              data are read from the EEPROM. Application should monitor this 
  *              variable in order know when the transfer is complete.
  * 
  * @note When number of data to be read is higher than 1, this function just 
  *       configures the communication and enable the DMA channel to transfer data.
  *       Meanwhile, the user application may perform other tasks.
  *       When number of data to be read is 1, then the DMA is not used. The byte
  *       is read in polling mode.
  * 
  * @retval sEE_OK (0) if operation is correctly performed, else return value 
  *         different from sEE_OK (0) or the timeout user callback.
  */
uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{  
  /* Set the pointer to the Number of data to be read. This pointer will be used 
      by the DMA Transfer Completer interrupt Handler in order to reset the 
      variable to 0. User should check on this variable in order to know if the 
      DMA transfer has been complete or not. */
  sEEDataReadPointer = NumByteToRead;
  
  /*!< While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send START condition */
  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 write */
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);

  /*!< Test on EV6 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  } 

  /*!< 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;
}
/**
  * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
  * @note   The number of byte can't exceed the EEPROM page size.
  * @param  pBuffer : pointer to the buffer containing the data to be written to 
  *         the EEPROM.
  * @param  WriteAddr : EEPROM's internal address to write to.
  * @param  NumByteToWrite : pointer to the variable holding number of bytes to 
  *         written to the EEPROM. 
  * 
  *        @note The variable pointed by NumByteToWrite is reset to 0 when all the 
  *              data are read from the EEPROM. Application should monitor this 
  *              variable in order know when the transfer is complete.
  * 
  * @note When number of data to be written is higher than 1, this function just 
  *       configure the communication and enable the DMA channel to transfer data.
  *       Meanwhile, the user application may perform other tasks.
  *       When number of data to be written is 1, then the DMA is not used.
  * 
  * @retval None
  */
void sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
{ 
  /* Set the pointer to the Number of data to be written. This pointer will be used 
      by the DMA Transfer Completer interrupt Handler in order to reset the 
      variable to 0. User should check on this variable in order to know if the 
      DMA transfer has been complete or not. */
  sEEDataWritePointer = NumByteToWrite;  
  
  /*!< 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 write to : only one byte Address */
  I2C_SendData(sEE_I2C, WriteAddr);
  
#elif defined(sEE_M24C64_32)
  
  /*!< Send the EEPROM's internal address to write to : MSB of the address first */
  I2C_SendData(sEE_I2C, (uint8_t)((WriteAddr & 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 write to : LSB of the address */
  I2C_SendData(sEE_I2C, (uint8_t)(WriteAddr & 0x00FF));
  
#endif /*!< sEE_M24C08 */  

  /*!< Test on EV8 and clear it */
  while(! I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
  }

  /* If number of data to be written is 1, then DMA couldn't be used */
  if ((uint16_t)(*NumByteToWrite) < 2)
  {
    /*!< Send the byte to be written */
    I2C_SendData(sEE_I2C, *pBuffer); 
    
    /*!< Test on EV8 and clear it */
    while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
    {
    }
    
    /*!< Send STOP condition */
    I2C_GenerateSTOP(sEE_I2C, ENABLE);
    
    (uint8_t)(*NumByteToWrite)--;
  }
  /* DMA could be used for number of data higher than 1 */
  else
  {  
    /* Configure the DMA Tx Channel with the buffer address and the buffer size */
    sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint8_t)(*NumByteToWrite), sEE_DIRECTION_TX);
    
    /* Enable the DMA Tx Channel */
    DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, ENABLE);
  }
}
/**
  * @brief  Reads a block of data from the EEPROM.
  * @param  pBuffer : pointer to the buffer that receives the data read from 
  *         the EEPROM.
  * @param  ReadAddr : EEPROM's internal address to read from.
  * @param  NumByteToRead : pointer to the variable holding number of bytes to 
  *         read from the EEPROM. 
  * 
  *        @note The variable pointed by NumByteToRead is reset to 0 when all the 
  *              data are read from the EEPROM. Application should monitor this 
  *              variable in order know when the transfer is complete.
  * 
  * @note When number of data to be read is higher than 1, this function just 
  *       configure the communication and enable the DMA channel to transfer data.
  *       Meanwhile, the user application may perform other tasks.
  *       When number of data to be read is 1, then the DMA is not used.
  * 
  * @retval None
  */
void sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{  
  /* Set the pointer to the Number of data to be read. This pointer will be used 
      by the DMA Transfer Completer interrupt Handler in order to reset the 
      variable to 0. User should check on this variable in order to know if the 
      DMA transfer has been complete or not. */
  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);     
  }
}
Exemple #5
0
uint32_t i2c_read(i2c_dev *dev, uint8_t addr, uint8_t *tx_buff, uint8_t txlen, uint8_t *rx_buff, uint8_t *rxlen)
{

    /* Set the pointer to the Number of data to be read. This pointer will be used
     by the DMA Transfer Completer interrupt Handler in order to reset the
     variable to 0. User should check on this variable in order to know if the
     DMA transfer has been complete or not. */
    if(dev->I2Cx == I2C1)
	I2C1DataReadPointer = (uint16_t*) rxlen;
    else
	I2C2DataReadPointer = (uint16_t*) rxlen;

    //uint16_t received;
    //int flags;
    //uint16_t ptr;
    uint8_t *buffer8 = rx_buff;

    //errno_r = 0;
    //received = 0;

    // While the bus is busy
    dev->timeout = sEE_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_BUSY ))
	{
	if ((dev->timeout--) == 0)
	    return I2C_ERROR;
	}

    // Send START condition
    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 write
    I2C_Send7bitAddress(dev->I2Cx, addr, I2C_Direction_Transmitter );
    dev->timeout = sEE_FLAG_TIMEOUT;
    // Test on EV6 and clear it
    while (!I2C_CheckEvent(dev->I2Cx,
	    I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ))
	{
	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;
    }
Exemple #6
0
/* Send a buffer to the i2c port */
uint32_t i2c_write(i2c_dev *dev, uint8_t addr, uint8_t *tx_buff, uint8_t *len)
{

    /* Set the pointer to the Number of data to be written. This pointer will be used
     by the DMA Transfer Completer interrupt Handler in order to reset the
     variable to 0. User should check on this variable in order to know if the
     DMA transfer has been complete or not. */
    if(dev->I2Cx == I2C1)
	I2C1DataWritePointer = len;
    else
	I2C2DataWritePointer = len;

    uint16_t sent = 0;
    uint8_t *buffer = tx_buff;

    sent = 0;

    // While the bus is busy
    /*!< While the bus is busy */
    dev->timeout = sEE_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_BUSY ))
	{
	if ((dev->timeout--) == 0)
	    return I2C_ERROR;
	}

    // Send START condition
    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 write
    I2C_Send7bitAddress(dev->I2Cx, addr, I2C_Direction_Transmitter );

    dev->timeout = sEE_FLAG_TIMEOUT;
    // Test on EV6 and clear it
    while (!I2C_CheckEvent(dev->I2Cx,
	    I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ))
	{
	if ((dev->timeout--) == 0)
	    return I2C_ERROR;
	}

    I2C_SendData(dev->I2Cx, *buffer++);

    // Test on EV8 and clear it
    dev->timeout = sEE_FLAG_TIMEOUT;
    while (!I2C_CheckEvent(dev->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED ))
	{
	if ((dev->timeout--) == 0)
	    return I2C_ERROR;
	}
    if ((uint16_t)(*len) < 2)
	{
	/* Send the current byte */
	I2C_SendData(dev->I2Cx, *buffer);
	/* Point to the next byte to be written */
	sent++;
	/* Test on EV8 and clear it */
	dev->timeout = sEE_FLAG_TIMEOUT;
	while (!I2C_CheckEvent(dev->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED ))
	    {
	    if ((dev->timeout--) == 0)
		return I2C_ERROR;
	    }

	/*!< STOP condition */
	I2C_GenerateSTOP(dev->I2Cx, DISABLE);
	I2C_ClearFlag(dev->I2Cx, I2C_FLAG_STOPF );
	/* Send STOP condition */
	I2C_GenerateSTOP(dev->I2Cx, ENABLE);
	}
    else
	{
    /* Configure the DMA Tx Channel with the buffer address and the buffer size */
    sEE_LowLevel_DMAConfig(dev,(uint32_t) buffer, (uint8_t)(*len),
		sEE_DIRECTION_TX);

    /* Enable the DMA Tx Stream */
    if (dev->I2Cx == I2C1){
	DMA_Cmd(sEE_I2C1_DMA_STREAM_TX, ENABLE);
    } else if(dev->I2Cx == I2C2){
	DMA_Cmd(sEE_I2C2_DMA_STREAM_TX, ENABLE);
    }
    /* Enable the sEE_I2C peripheral DMA requests */
    I2C_DMACmd(dev->I2Cx, ENABLE);
	}

    return I2C_OK;
}