Example #1
0
/**
 * @brief  Reads a block of data from the MPU6050.
 * @param  slaveAddr  : slave address MPU6050_DEFAULT_ADDRESS
 * @param  pBuffer : pointer to the buffer that receives the data read from the MPU6050.
 * @param  readAddr : MPU6050's internal address to read from.
 * @param  NumByteToRead : number of bytes to read from the MPU6050 ( NumByteToRead >1  only for the Mgnetometer readinf).
 * @return None
 */
void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)
{
    // ENTR_CRT_SECTION();

    /* While the bus is busy */
    while (I2C_GetFlagStatus(MPU6050_I2C, I2C_FLAG_BUSY));

    /* 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));

    /* While there is data to be read */
    while (NumByteToRead)
    {
        if (NumByteToRead == 1)
        {
            /* Disable Acknowledgement */
            I2C_AcknowledgeConfig(MPU6050_I2C, DISABLE);

            /* Send STOP Condition */
            I2C_GenerateSTOP(MPU6050_I2C, ENABLE);
        }

        /* Test on EV7 and clear it */
        if (I2C_CheckEvent(MPU6050_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            /* Read a byte from the MPU6050 */
            *pBuffer = I2C_ReceiveData(MPU6050_I2C);

            /* Point to the next location where the byte read will be saved */
            pBuffer++;

            /* Decrement the read bytes counter */
            NumByteToRead--;
        }
    }

    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(MPU6050_I2C, ENABLE);
    // EXT_CRT_SECTION();
}
Example #2
0
/**
  * @brief  Reads and returns the value of an audio codec register through the
  *         control interface (I2C).
  * @param  RegisterAddr: Address of the register to be read.
  * @retval Value of the register to be read or dummy value if the communication
  *         fails.
  */
static uint32_t Codec_ReadRegister(uint8_t RegisterAddr)
{
  uint32_t result = 0;

  /*!< While the bus is busy */
  CODECTimeout = CODEC_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /* Start the config sequence */
  I2C_GenerateSTART(CODEC_I2C, ENABLE);

  /* Test on EV5 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }

  /* Transmit the register address to be read */
  I2C_SendData(CODEC_I2C, RegisterAddr);

  /* Test on EV8 and clear it */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while (I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF) == RESET)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /*!< Send START condition a second time */  
  I2C_GenerateSTART(CODEC_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  } 
  
  /*!< Send Codec address for read */
  I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Receiver);  
  
  /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_ADDR) == RESET)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }     
  
  /*!< Disable Acknowledgment */
  I2C_AcknowledgeConfig(CODEC_I2C, DISABLE);   
  
  /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
  (void)CODEC_I2C->SR2;
  
  /*!< Send STOP Condition */
  I2C_GenerateSTOP(CODEC_I2C, ENABLE);
  
  /* Wait for the byte to be received */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_RXNE) == RESET)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }
  
  /*!< Read the byte received from the Codec */
  result = I2C_ReceiveData(CODEC_I2C);
  
  /* Wait to make sure that STOP flag has been cleared */
  CODECTimeout = CODEC_FLAG_TIMEOUT;
  while(CODEC_I2C->CR1 & I2C_CR1_STOP)
  {
    if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
  }  
  
  /*!< Re-Enable Acknowledgment to be ready for another reception */
  I2C_AcknowledgeConfig(CODEC_I2C, ENABLE);  
  
  /* Clear AF flag for next communication */
  I2C_ClearFlag(CODEC_I2C, I2C_FLAG_AF); 
  
  /* Return the byte read from Codec */
  return result;
}
Example #3
0
void I2C_IRQ_ev(i2c_bus *bus) {
  if (bus->state == I2C_S_IDLE) {
//    u32_t ev = I2C_GetLastEvent(I2C_HW(bus));
//    I2C_LOG_UNKNOWN_EV(bus, ev);
//    (void)ev;
//    i2c_error(bus, I2C_ERR_UNKNOWN_STATE, TRUE);
    return;
  }


  u32_t sr1 = I2C_HW(bus)->SR1;
  DBG(D_I2C, D_DEBUG, "I2C irq ev %02x\n", sr1);

  if (bus->op == I2C_OP_RX) {

    // ==== RX ====

    if ((sr1 & I2C_IT_SB) && bus->state == I2C_S_GEN_START) {
      // send address | 0x01 for rx
      I2C_HW_DBG("rx it sb\n");
      I2C_LOG_EV(bus, sr1);
      I2C_HW(bus)->DR = bus->addr | 0x01;
    } // if IT_SB
    else if ((sr1 & I2C_IT_ADDR) && bus->state == I2C_S_GEN_START) {
      // address sent and acknowledged
      // IT_ADDR bit cleared by reading SR1 & SR2
      (void)I2C_HW(bus)->SR2;
      I2C_LOG_EV(bus, sr1);
      bus->state = I2C_S_RX;
      if (bus->len == 2) {
        I2C_HW_DBG("rx it addr, len = 2\n");
        // RM0008 26.3.3 case len = 2
        I2C_ITConfig(I2C_HW(bus), I2C_IT_BUF, DISABLE); // kill RXNE interrupt, rely on BTF interrupt
        // POS=1 indicates that the ACK bit indicates ack or nack of next byte coming in the shift reg
        I2C_HW(bus)->CR1 |= I2C_CR1_POS;
        I2C_AcknowledgeConfig(I2C_HW(bus), DISABLE);
      }
      else if (bus->len <= 1) {
        // RM0008 26.3.3 case len = 1
        I2C_HW_DBG("rx it addr, len < 2\n");
        I2C_AcknowledgeConfig(I2C_HW(bus), DISABLE);
        if (bus->gen_stop) {
          I2C_LOG_STOP(bus);
          I2C_GenerateSTOP(I2C_HW(bus), ENABLE);
        } else {
          // the restart condition must be set before receiving last byte
          I2C_LOG_START(bus);
          I2C_GenerateSTART(I2C_HW(bus), ENABLE);
          bus->restart_generated = TRUE;
        }
      }
      else { // bus->len > 2
        // do naught, rely on RXNE interrupt
        I2C_HW_DBG("rx it addr, len > 2\n");
      }
    } // if IT_ADDR
    else if ((sr1 & I2C_IT_BTF) && bus->state == I2C_S_RX) {
      // data register full, shift register full, clock is now stretched
      I2C_LOG_EV(bus, sr1);
      if (bus->len == 2) {
        I2C_HW_DBG("rx it btf, len = 2\n");
        // these are the two last bytes to receive
        if (bus->gen_stop) {
          I2C_LOG_STOP(bus);
          I2C_GenerateSTOP(I2C_HW(bus), ENABLE);
        } else {
          // the restart condition must be set before receiving last byte
          I2C_LOG_START(bus);
          I2C_GenerateSTART(I2C_HW(bus), ENABLE);
          bus->restart_generated = TRUE;
        }
        *bus->buf++ = I2C_HW(bus)->DR;
        *bus->buf++ = I2C_HW(bus)->DR;
        bus->len -= 2;

        // clear POS
        I2C_HW(bus)->CR1 &= ~I2C_CR1_POS;

        i2c_finalize(bus);
        if (bus->i2c_bus_callback) {
          I2C_LOG_CB(bus);
          bus->i2c_bus_callback(bus, I2C_RX_OK);
        }
      }
      else if (bus->len == 3) {
        I2C_HW_DBG("rx it btf, len = 3\n");
        I2C_ITConfig(I2C_HW(bus), I2C_IT_BUF, DISABLE); // kill RXNE interrupts now, rely on BTF
        I2C_AcknowledgeConfig(I2C_HW(bus), DISABLE);
        // read N-2, await IT_BTF for the final 2 bytes
        *bus->buf++ = I2C_HW(bus)->DR;
        bus->len--;
      }
      else { // bus->len > 3
        I2C_HW_DBG("rx it btf, len > 3\n");
        *bus->buf++ = I2C_HW(bus)->DR;
        bus->len--;
      }
    } // if IT_BTF
    else if (sr1 & I2C_IT_RXNE) {
      I2C_LOG_EV(bus, sr1);
      ASSERT(bus->len != 2); // this should never happen as RXNE interrupts for 2 bytes are disabled
      if (bus->len == 3) {
        I2C_HW_DBG("rx it rxne, len = 3\n");
        I2C_ITConfig(I2C_HW(bus), I2C_IT_BUF, DISABLE); // kill RXNE interrupts now, rely on BTF
      }
      else {
        // bus->len > 3 || bus->len == 1
        I2C_HW_DBG("rx it rxne, len > 3\n");
        *bus->buf++ = I2C_HW(bus)->DR;
        bus->len--;
        if (bus->len == 0) {
          if (bus->gen_stop) {
            I2C_LOG_STOP(bus);
            I2C_GenerateSTOP(I2C_HW(bus), ENABLE);
          } else {
            // the restart condition must be set before receiving last byte
            I2C_LOG_START(bus);
            I2C_GenerateSTART(I2C_HW(bus), ENABLE);
            bus->restart_generated = TRUE;
          }
          bool gen_cb = bus->state == I2C_S_RX;
          i2c_finalize(bus);
          if (bus->i2c_bus_callback && gen_cb) {
            I2C_LOG_CB(bus);
            bus->i2c_bus_callback(bus, I2C_RX_OK);
          }
        }
      }
    } // if IT_RXNE
    else {
      // do not read SR2 here, this might clear IT_ADDR or IT_SB
      I2C_HW_DBG("rx it bad\n");
      I2C_LOG_UNKNOWN_EV(bus, sr1);
      bus->bad_ev_counter++;
    } // if any other interrupt

  } // if RX
  else {

    // ==== TX or QUERY ====

    I2C_LOG_EV(bus, sr1);
    if (sr1 & I2C_IT_SB) {
      // from send start condition
      I2C_HW_DBG("tx it sb\n");
      I2C_HW(bus)->DR = bus->addr & ~0x01;
    }
    else if (sr1 & I2C_IT_ADDR) {
      // from send 7 bit address tx
      // IT_ADDR bit cleared by reading SR1 & SR2
      (void)I2C_HW(bus)->SR2;
      if (bus->len > 0 && bus->op == I2C_OP_TX) {
        I2C_HW_DBG("tx it addr\n");
        bus->state = I2C_S_TX;
        I2C_HW(bus)->DR = *bus->buf++;
        bus->len--;
        if (bus->len == 0) {
          I2C_ITConfig(I2C_HW(bus), I2C_IT_BUF, DISABLE); // kill TXE interrupts now, rely on BTF
        }
      } else {
        // for address query
        I2C_HW_DBG("tx query it addr\n");
        I2C_LOG_STOP(bus);
        I2C_GenerateSTOP(I2C_HW(bus), ENABLE);
        i2c_finalize(bus);
        if (bus->i2c_bus_callback) {
          I2C_LOG_CB(bus);
          bus->i2c_bus_callback(bus, I2C_OK);
        }
      }
    }
    else if ((sr1 & I2C_IT_TXE) || (sr1 & I2C_IT_BTF)) {
      // transmitted or transmitting
      I2C_HW_DBG("tx it txed txing TXE:%i BTF:%i len:%i\n", (sr1 & I2C_IT_TXE) != 0, (sr1 & I2C_IT_BTF) != 0, bus->len);
      if (bus->len > 0) {
        I2C_HW(bus)->DR = *bus->buf++;
        bus->len--;
        if (bus->len == 0) {
          I2C_ITConfig(I2C_HW(bus), I2C_IT_BUF, DISABLE); // kill TXE interrupts now, rely on BTF
        }
      }
      else if (bus->state == I2C_S_TX && (sr1 & I2C_IT_BTF)) {
        // must check for tx here, at low speeds there might come spurios tx events
        if (bus->len == 0) {
          if (bus->gen_stop) {
            I2C_LOG_STOP(bus);
            I2C_GenerateSTOP(I2C_HW(bus), ENABLE);
          } else {
            I2C_LOG_START(bus);
            I2C_GenerateSTART(I2C_HW(bus), ENABLE);
            bus->restart_generated = TRUE;
          }
          bool gen_cb = bus->state == I2C_S_TX;
          i2c_finalize(bus);
          if (bus->i2c_bus_callback && gen_cb) {
            I2C_LOG_CB(bus);
            bus->i2c_bus_callback(bus, I2C_TX_OK);
          }
        }
      }
    }
    else {
      // bad event
      DBG(D_I2C, D_WARN, "i2c_err: bad event %02x\n", sr1);
      bus->bad_ev_counter ++;
      I2C_LOG_UNKNOWN_EV(bus, sr1);
    } // switch ev
  }
  if (bus->bad_ev_counter > 16) {
    i2c_error(bus, I2C_ERR_UNKNOWN_STATE, TRUE);
  }
}
Example #4
0
/**
*************************************************
 *@Function     : IIC_ReadPage(u8 *pBuffer,u8 PartAddr,u8 WriteAddr,u8 NumByteToWrite)
 *@Return_Value :Null
 *@Peremater    :
 *@Brief        :
***************************************************/
u8* IIC_ReadPage(u8 *pBuffer,u8 PartAddr,u8 WriteAddr,u8 NumByteToWrite)
{
//  I2C_ClearFlag(I2C1, I2C_FLAG_AF);
  I2C_AcknowledgeConfig(I2C1,ENABLE);
  /*send Start condition,test on EV5 and clear it*/
  TimeOut=EE_TimeOut;
  I2C_GenerateSTART(I2C1,ENABLE);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))
    {
      if((TimeOut--)==0){EE_State=EE_ErrorRTimeOut;}    
    }

  /*send Part Address for write,test on EV6 and clear it*/
  TimeOut=EE_TimeOut;
  I2C_Send7bitAddress(I2C1,PartAddr,I2C_Direction_Transmitter);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
    {
      if((TimeOut--)==0){EE_State=EE_ErrorRTimeOut;}
    }

  /*send the EEPROM's internal address,test on EV8 and clear it
  I2C_SendData(I2C1,WriteAddr);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));  */
   /******writeAddress for 8bit or 16 bit**********/
  TimeOut=EE_TimeOut;

 /**send the EEPROM's internal address,test on EV8 and clear it**/
  I2C_SendData(I2C1,(u8)WriteAddr);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))
    {
      if((TimeOut--)==0){EE_State=EE_ErrorRTimeOut;}
    }


  /* DMA control */
  /*send Start condition,test on EV5 and clear it*/
  TimeOut=EE_TimeOut;
  I2C_GenerateSTART(I2C1,ENABLE);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))
    {
      if((TimeOut--)==0){EE_State=EE_ErrorRTimeOut;}    
    }

  /*send Part Address for write,test on EV6 and clear it*/
  TimeOut=EE_TimeOut;
  I2C_Send7bitAddress(I2C1,PartAddr,I2C_Direction_Receiver);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {
      if((TimeOut--)==0){EE_State=EE_ErrorRTimeOut;}
    }

  while(NumByteToWrite)
    {
      if(NumByteToWrite==1)
    	{
    	  I2C_AcknowledgeConfig(I2C1,DISABLE);
    	  I2C_GenerateSTOP(I2C1,ENABLE);
    	}
      if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED))
    	{
    	  *pBuffer=I2C_ReceiveData(I2C1);
    	  pBuffer++;
    	  NumByteToWrite--;
	     TimeOut=EE_TimeOut;
    	}
      else
    	{
    	    if((TimeOut--)==0){EE_State=EE_ErrorRTimeOut;}  
    	}
    
     }
 I2C_GenerateSTOP(I2C1,ENABLE);
 return pBuffer;
}
Example #5
0
/**
 * @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(i2c_dev *dev, 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. */
    I2C2DataReadPointer = NumByteToRead;

    /*!< While the bus is busy */
    sEETimeout = sEE_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_BUSY ))
	{
	if ((sEETimeout--) == 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) */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while (!I2C_CheckEvent(dev->I2Cx, I2C_EVENT_MASTER_MODE_SELECT ))
	{
	if ((sEETimeout--) == 0)
	    return I2C_ERROR;
	}

    /*!< Send EEPROM address for write */
    I2C_Send7bitAddress(dev->I2Cx, sEEAddress, I2C_Direction_Transmitter );

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

    /*!< Send the EEPROM's internal address to read from: MSB of the address first */
    I2C_SendData(dev->I2Cx, (uint8_t)((ReadAddr & 0xFF00) >> 8));

    /*!< Test on EV8 and clear it */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while (!I2C_CheckEvent(dev->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING ))
	{
	if ((sEETimeout--) == 0)
	    return I2C_ERROR;
	}

    /*!< Send the EEPROM's internal address to read from: LSB of the address */
    I2C_SendData(dev->I2Cx, (uint8_t)(ReadAddr & 0x00FF));

    /*!< Test on EV8 and clear it */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_BTF ) == RESET)
	{
	if ((sEETimeout--) == 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) */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while (!I2C_CheckEvent(dev->I2Cx, I2C_EVENT_MASTER_MODE_SELECT ))
	{
	if ((sEETimeout--) == 0)
	    return I2C_ERROR;
	}

    /*!< Send EEPROM address for read */
    I2C_Send7bitAddress(dev->I2Cx, 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(dev->I2Cx, I2C_FLAG_ADDR ) == RESET)
	    {
	    if ((sEETimeout--) == 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(sEE_I2C, DISABLE);
	//I2C_ClearFlag(sEE_I2C, I2C_FLAG_STOPF );
	/* Send STOP condition */
	I2C_GenerateSTOP(dev->I2Cx, ENABLE);

	/* Wait for the byte to be received */
	sEETimeout = sEE_FLAG_TIMEOUT;
	while (I2C_GetFlagStatus(dev->I2Cx, I2C_FLAG_RXNE ) == RESET)
	    {
	    if ((sEETimeout--) == 0)
		return I2C_ERROR;
	    }

	/*!< Read the byte received from the EEPROM */
	*pBuffer = I2C_ReceiveData(dev->I2Cx );

	/*!< Decrement the read bytes counter */
	(uint16_t)(*NumByteToRead)--;

	/* Wait to make sure that STOP control bit has been cleared */
	sEETimeout = sEE_FLAG_TIMEOUT;
	while (dev->I2Cx ->CR1 & I2C_CR1_STOP )
	    {
	    if ((sEETimeout--) == 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 */
	sEETimeout = sEE_FLAG_TIMEOUT;
	while (!I2C_CheckEvent(dev->I2Cx,
		I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ))
	    {
	    if ((sEETimeout--) == 0)
		return I2C_ERROR;
	    }

	/* Configure the DMA Rx Channel with the buffer address and the buffer size */
	sEE_LowLevel_DMAConfig(_I2C2, (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(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);
	}

    /* If all operations OK, return sEE_OK (0) */
    return I2C_OK;
    }
/**
  * @brief  Reads a byte from a specific Camera register
  * @param  Addr: OV9655 register address.
  * @retval data read from the specific register or 0xFF if timeout condition
  *         occured.
  */
uint8_t OV9655_ReadReg(uint16_t Addr)
{
  uint32_t timeout = DCMI_TIMEOUT_MAX;
  uint8_t Data = 0;

  /* Generate the Start Condition */
  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on I2C1 EV5 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }
  
  /* Send DCMI selcted device slave Address for write */
  I2C_Send7bitAddress(I2C1, OV9655_DEVICE_READ_ADDRESS, I2C_Direction_Transmitter);
 
  /* Test on I2C1 EV6 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }

  /* Send I2C1 location address LSB */
  I2C_SendData(I2C1, (uint8_t)(Addr));

  /* Test on I2C1 EV8 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  
  /* Clear AF flag if arised */
  I2C1->SR1 |= (uint16_t)0x0400;

  /* Generate the Start Condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on I2C1 EV6 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  
  /* Send DCMI selcted device slave Address for write */
  I2C_Send7bitAddress(I2C1, OV9655_DEVICE_READ_ADDRESS, I2C_Direction_Receiver);

  /* Test on I2C1 EV6 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }
 
  /* Prepare an NACK for the next data received */
  I2C_AcknowledgeConfig(I2C1, DISABLE);

  /* Test on I2C1 EV7 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }

  /* Prepare Stop after receiving data */
  I2C_GenerateSTOP(I2C1, ENABLE);

  /* Receive the Data */
  Data = I2C_ReceiveData(I2C1);

  /* return the read data */
  return Data;
}
Example #7
0
/**
  * @brief  Reads a byte from a specific Camera register 
  * @param  Device: OV7670 write address.
  * @param  Addr: OV7670 register address. 
  * @retval data read from the specific register or 0xFF if timeout condition 
  *         occured. 
  */
uint8_t DCMI_SingleRandomRead(uint8_t Reg, uint8_t *Data)
{
  uint32_t timeout = DCMI_TIMEOUT_MAX;

    /* Clear AF flag if arised */
  I2C2->SR1 |= (uint16_t)0x0400;

  /* Generate the Start Condition */
  I2C_GenerateSTART(Open207Z_SCCB, ENABLE);

  /* Test on I2C2 EV5 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(Open207Z_SCCB, I2C_EVENT_MASTER_MODE_SELECT))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  /*-----------------------------------------------------------------------------------*/
  /* Send DCMI selcted device slave Address for write */
  I2C_Send7bitAddress(Open207Z_SCCB, OV7670_DEVICE_READ_ADDRESS, I2C_Direction_Transmitter);
 
  /* Test on I2C2 EV6 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(Open207Z_SCCB, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  /*-----------------------------------------------------------------------------------*/
  /* Send I2C2 location address LSB */
  I2C_SendData(Open207Z_SCCB, (uint8_t)(Reg));

  /* Test on I2C2 EV8 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(Open207Z_SCCB, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  
  /* Clear AF flag if arised */
  I2C2->SR1 |= (uint16_t)0x0400;
  /*-----------------------------------------------------------------------------------*/    
  /* Prepare Stop after receiving data */
  I2C_GenerateSTOP(Open207Z_SCCB, ENABLE);

  /*-----------------------------------------------------------------------------------*/
  /* Generate the Start Condition */
  I2C_GenerateSTART(Open207Z_SCCB, ENABLE);
  
  /* Test on I2C2 EV6 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(Open207Z_SCCB, I2C_EVENT_MASTER_MODE_SELECT))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  /*-----------------------------------------------------------------------------------*/
  /* Send DCMI selcted device slave Address for write */
  I2C_Send7bitAddress(Open207Z_SCCB, OV7670_DEVICE_READ_ADDRESS, I2C_Direction_Receiver);
   
  /* Test on I2C2 EV6 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(Open207Z_SCCB, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }
      
  /*-----------------------------------------------------------------------------------*/
  /* Prepare an NACK for the next data received */
  I2C_AcknowledgeConfig(Open207Z_SCCB, DISABLE);

  /* Test on Open207Z_SCCB EV7 and clear it */
  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
  while(!I2C_CheckEvent(Open207Z_SCCB, I2C_EVENT_MASTER_BYTE_RECEIVED))
  {
    /* If the timeout delay is exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  } 
  /*-----------------------------------------------------------------------------------*/    
  /* Prepare Stop after receiving data */
  I2C_GenerateSTOP(Open207Z_SCCB, ENABLE); 

  /*-----------------------------------------------------------------------------------*/
  /* Receive the Data */
  *Data = I2C_ReceiveData(Open207Z_SCCB);
  /* Clear AF flag if arised */
  I2C2->SR1 |= (uint16_t)0x0400;

  /* return the read data */
  return 0;
}
/**
  * @brief  Enables or disables the LM75.
  * @param  NewState: specifies the LM75 new status. This parameter can be ENABLE
  *         or DISABLE.
  * @retval None
  */
void LM75_ShutDown(FunctionalState NewState)
{
  __IO uint8_t RegValue = 0;

  /*---------------------------- Transmission Phase ---------------------------*/
  /* Send LM75_I2C START condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on LM75_I2C EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);

  /* Test on LM75_I2C EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);

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

  /*-------------------------------- Reception Phase --------------------------*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }

  /* Disable LM75_I2C acknowledgement */
  I2C_AcknowledgeConfig(LM75_I2C, DISABLE);

  /* Send LM75_I2C STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);

  /* Test on RXNE flag */
  while (I2C_GetFlagStatus(LM75_I2C, I2C_FLAG_RXNE) == RESET);

  /* Store LM75_I2C received data */
  RegValue = I2C_ReceiveData(LM75_I2C);

  /*------------------------------------ Transmission Phase -------------------*/
  /* Send LM75_I2C START condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on LM75_I2C EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);

  /* Test on LM75_I2C EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);

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

  /* Enable or disable SD bit */
  if (NewState != DISABLE)
  {
    /* Enable LM75 */
    I2C_SendData(LM75_I2C, (uint8_t)(RegValue & LM75_SD_RESET));
  }
  else
  {
    /* Disable LM75 */
    I2C_SendData(LM75_I2C, (uint8_t)(RegValue | LM75_SD_SET));
  }

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

  /* Send LM75_I2C STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);

}
Example #9
0
/**
  * @brief  Reads a word from a specific Camera register
  * @param  Addr: MT9D111 register address.
  * @retval data word from the specific register or
  *         0xFFFF if timeout condition occured (device not connected or bus error).
  */
ushort MT9D111_ReadReg(uchar regAddr)
{
    unsigned int timeout = I2C_TIMEOUT_MAX;
    unsigned short regVal = 0;

    /* Generate the START Condition */
    I2C_GenerateSTART(MT9D111_I2C, ENABLE);

    /* Test on I2C EV5 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_MODE_SELECT))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    /* Send slave device address with write mode selected */
    I2C_Send7bitAddress(MT9D111_I2C, MT9D111_DEVICE_WRITE_ADDRESS, I2C_Direction_Transmitter);

    /* Test on I2C EV6 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    /* Send register address byte */
    I2C_SendData(MT9D111_I2C, regAddr);

    /* Test on I2C EV8 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    /* Clear AF flag if arised */
    MT9D111_I2C->SR1 |= (uint16_t)0x0400;

    /* Generate the START Condition */
    I2C_GenerateSTART(MT9D111_I2C, ENABLE);

    /* Test on I2C EV6 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_MODE_SELECT))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    /* Send slave device address with read mode selected */
    I2C_Send7bitAddress(MT9D111_I2C, MT9D111_DEVICE_READ_ADDRESS, I2C_Direction_Receiver);

    /* Test on I2C EV6 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    /* Prepare an ACK for the next data received */
    I2C_AcknowledgeConfig(MT9D111_I2C, ENABLE);

    /* Test on I2C EV7 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    regVal = ((unsigned short) I2C_ReceiveData(MT9D111_I2C)) << 8;

    /* Prepare an NACK for the next data received */
    I2C_AcknowledgeConfig(MT9D111_I2C, DISABLE);

    /* Test on I2C EV7 and clear it */
    timeout = I2C_TIMEOUT_MAX;  // Initialize timeout value
    while (!I2C_CheckEvent(MT9D111_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
        // If the timeout delay is exceeded, exit with error code
        if ((timeout--) == 0)
            return 0xFF;
    }

    /* Prepare STOP after receiving data */
    I2C_GenerateSTOP(MT9D111_I2C, ENABLE);

    /* Receive the Data */
    regVal += I2C_ReceiveData(MT9D111_I2C);

    while (((MT9D111_I2C->CR1) & 0x0200) != 0);

    /* Return the read data */
    return regVal;
}
Example #10
0
/*******************************************************************************
* Function Name  : CODEC_ReadRegister
* Description    : Reads a register of the audio Codec through I2C.
* Input          :  - RegisterAddr: The target register address (between 00x and 0x24)
* Output         : None
* Return         : The value of the read register
*******************************************************************************/
uint32_t CODEC_ReadRegister(uint32_t RegisterAddr)
{
  uint32_t tmp = 0;

  /* Disable the I2C1 peripheral  */
  I2C_Cmd(I2C1, DISABLE);

  /* Reset all I2C2 registers */
  I2C_SoftwareResetCmd(I2C1, ENABLE);
  I2C_SoftwareResetCmd(I2C1, DISABLE);

  /* Configure the I2C peripheral */
  I2C_Config();

  /* Enable the I2C peripheral */
  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
  {}
  /* Disable Acknowledgement */
  I2C_AcknowledgeConfig(I2C1, DISABLE);

  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(I2C1, CODEC_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {}
  /* Transmit the first address for r/w operations */
  I2C_SendData(I2C1, RegisterAddr);

  /* Test on EV8 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {}
  /* Regenerate a start condition */
  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
  {}
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(I2C1, CODEC_ADDRESS, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  {}
  /* Test on EV7 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
  {}
  /* End the configuration sequence */
  I2C_GenerateSTOP(I2C1, ENABLE);

  /* Load the register value */
  tmp = I2C_ReceiveData(I2C1);

  /* Disable Acknowledgement */
  I2C_AcknowledgeConfig(I2C1, ENABLE);

  /* Return the read value */
  return tmp;
}
Example #11
0
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
void main()
{

#ifdef FAST_I2C_MODE
  /* system_clock / 1 */
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
#else
  /* system_clock / 2 */
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);
#endif

  /* Initialize LEDs mounted on STM8/128-EVAL board */
  STM_EVAL_LEDInit(LED1);
  STM_EVAL_LEDInit(LED2);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);
	
	STM_EVAL_LEDOff(LED1);
  STM_EVAL_LEDOff(LED2);
  STM_EVAL_LEDOff(LED3);
  STM_EVAL_LEDOff(LED4);


  /* I2C Initialize */
  I2C_Init(I2C_SPEED, 0xA0, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);


  /* Enable Buffer and Event Interrupt*/
  I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);

  enableInterrupts();

  /* TXBuffer initialization */
  for (i = 0; i < BUFFERSIZE; i++)
    TxBuffer[i] = i;

  /* Send START condition */
  I2C_GenerateSTART(ENABLE);
  while (NumOfBytes);
  while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));

  /* Add a delay to be sure that communication is finished */
  Delay(0xFFFF);

  /*****  reception phase ***/
  /*  Wait while the bus is busy */
  while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));

  /* Send START condition */
  I2C_GenerateSTART(ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

#ifdef TEN_BITS_ADDRESS
  /* Send Header to Slave for write */
  I2C_SendData(HEADER_ADDRESS_Write);

  /* Test on EV9 and clear it*/
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_ADDRESS10));

  /* Send slave Address */
  I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  /* Repeated Start */
  I2C_GenerateSTART(ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

  /* Send Header to Slave for Read */
  I2C_SendData(HEADER_ADDRESS_Read);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

#else
  /* Send slave Address for write */
  I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
#endif /* TEN_BITS_ADDRESS */

  /* While there is data to be read */
  while (NumByteToRead)
  {
#ifdef SAFE_PROCEDURE
    if (NumByteToRead != 3) /* Receive bytes from first byte until byte N-3 */
    {
      while ((I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET)); /* Poll on BTF */

      /* Read a byte from the Slave */
      RxBuffer[Rx_Idx] = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      Rx_Idx++;

      /* 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_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET)); /* Poll on BTF */

      /* Clear ACK */
      I2C_AcknowledgeConfig(I2C_ACK_NONE);

      /* Disable general interrupts */
      disableInterrupts();

      /* Read Data N-2 */
      RxBuffer[Rx_Idx] = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      Rx_Idx++;

      /* Program the STOP */
      I2C_GenerateSTOP(ENABLE);

      /* Read DataN-1 */
      RxBuffer[Rx_Idx] = I2C_ReceiveData();

      /* Enable General interrupts */
      enableInterrupts();

      /* Point to the next location where the byte read will be saved */
      Rx_Idx++;

      while ((I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET)); /* Poll on RxNE */

      /* Read DataN */
      RxBuffer[Rx_Idx] = I2C_ReceiveData();

      /* Reset the number of bytes to be read by master */
      NumByteToRead = 0;

    }
#else
    if (NumByteToRead == 1)
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C_ACK_NONE);

      /* Send STOP Condition */
      I2C_GenerateSTOP(ENABLE);

      /* Poll on RxNE Flag */
      while ((I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET));
      /* Read a byte from the Slave */
      RxBuffer[Rx_Idx] = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      Rx_Idx++;

      /* Decrement the read bytes counter */
      NumByteToRead--;
    }

    /* Test on EV7 and clear it */
    if (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED) )
    {
      /* Read a byte from the EEPROM */
      RxBuffer[Rx_Idx] = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      Rx_Idx++;

      /* Decrement the read bytes counter */
      NumByteToRead--;
	}
#endif /* SAFE_PROCEDURE */
  }

  /* check if sent and received data are not corrupted */
  TransferStatus1 = Buffercmp((uint8_t*)TxBuffer, (uint8_t*) RxBuffer, BUFFERSIZE);

  if (TransferStatus1 != FAILED)
  {
    while (1)
    {
      /* Toggle LED1*/
      STM_EVAL_LEDToggle(LED1);
      /* Insert delay */
      Delay(0x7FFF);
    }
  }
  else
  {
    while (1)
    {
      /* Toggle LED4*/
      STM_EVAL_LEDToggle(LED4);
      /* Insert delay */
      Delay(0x7FFF);
    }
  }
}
Example #12
0
/**
  * @brief   Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
  this is done through SystemInit() function which is called from startup
  file (startup_stm32l1xx_xx.s) before to branch to application main.
  To reconfigure the default setting of SystemInit() function, refer to
  system_stm32l1xx.c file
  */
  
/* I2C configuration ---------------------------------------------------------*/
  I2C_Config();
  
  /* Initialize LEDs mounted on STM32L152-EVAL board */
  STM_EVAL_LEDInit(LED1);
  STM_EVAL_LEDInit(LED2);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);
  
/* SysTick configuration -----------------------------------------------------*/
  SysTickConfig();
  
/*************************************Master Code******************************/
#if defined (I2C_MASTER)
  /* I2C De-initialize */
  I2C_DeInit(I2Cx);
  
  /*!< I2C Struct Initialize */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
  I2C_InitStructure.I2C_OwnAddress1 = 0xA0;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
  
#ifndef I2C_10BITS_ADDRESS
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
#else
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_10bit;
#endif /* I2C_10BITS_ADDRESS */
  
  /*!< I2C Initialize */
  I2C_Init(I2Cx, &I2C_InitStructure);
  
  /* Enable Error Interrupt */
  I2C_ITConfig(I2Cx, I2C_IT_ERR , ENABLE);
  
  /* I2C ENABLE */
  I2C_Cmd(I2Cx, ENABLE);
  
/* Master Transmitter---------------------------------------------------------*/   
  NumberOfByteToTransmit = TXBUFFERSIZE;
  MasterMode = MASTER_MODE_TRANSMITTER;
  Tx_Idx = 0x00;
  /* Enable Error and Buffer Interrupts */
  I2C_ITConfig(I2Cx, (I2C_IT_EVT | I2C_IT_BUF), ENABLE);
  /* Generate the Start condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Data transfer is performed in the I2C interrupt routine */
  /* Wait until end of data transfer or time out */
  TimeOut = USER_TIMEOUT;
  while ((Tx_Idx < TXBUFFERSIZE)&&(TimeOut != 0x00))
  {}
  if(TimeOut == 0)
  {
    TimeOut_UserCallback();
  }
  
  TimeOut = USER_TIMEOUT;
  while ((I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))&&(TimeOut != 0x00))
  {}
  if(TimeOut == 0)
  {
    TimeOut_UserCallback();
  }
/* Master Receiver------------------------------------------------------------*/ 
  NumberOfByteToReceive = RXBUFFERSIZE;
  MasterMode = MASTER_MODE_RECEIVER;
  Rx_Idx = 0x00;
  /* Clear the RxBuffer */
  Fill_Buffer(RxBuffer, RXBUFFERSIZE);
  
  /* Enable Event Interrupts */
  I2C_ITConfig(I2Cx, I2C_IT_EVT , ENABLE);
  /* Enable Acknowledge */
  I2C_AcknowledgeConfig(I2Cx, ENABLE);
  
  /* Generate the Start condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Data transfer is performed in the I2C interrupt routine */
  /* Wait until end of data transfer */
  while (Rx_Idx < RXBUFFERSIZE)
  {}
  if (Buffercmp(TxBuffer, RxBuffer, RXBUFFERSIZE) == PASSED)
  {
    /* LED2, LED3 and LED4 Toggle */
    STM_EVAL_LEDOn(LED2);
    STM_EVAL_LEDOn(LED3);
    STM_EVAL_LEDOn(LED4);
  }
  else 
  {   /* ED2, LED3 and LED4 On */
    STM_EVAL_LEDOff(LED2);
    STM_EVAL_LEDOff(LED3);
    STM_EVAL_LEDOff(LED4);
  }
  
#endif /* I2C_MASTER */
  
/**********************************Slave Code**********************************/
#if defined (I2C_SLAVE)
  
   I2C_DeInit(I2Cx);
  
  /* Initialize I2C peripheral */
  /*!< I2C Init */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
  I2C_InitStructure.I2C_OwnAddress1 = SLAVE_ADDRESS;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
  
#ifndef I2C_10BITS_ADDRESS
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
#else
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_10bit;
#endif /* I2C_10BITS_ADDRESS */
  
  I2C_Init(I2Cx, &I2C_InitStructure);
  
  /* Enable Error Interrupt */
  I2C_ITConfig(I2Cx, (I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
  
  /* I2C ENABLE */
  I2C_Cmd(I2Cx, ENABLE);
  
/* Slave Receiver-------------------------------------------------------------*/
  Rx_Idx = 0x00; 
  Tx_Idx = 0x00;
  
  /* Clear the RxBuffer */
  Fill_Buffer(RxBuffer, RXBUFFERSIZE);
  
  /* Wait until end of data transfer */
  while (Rx_Idx < RXBUFFERSIZE)
  {} 
  
  TimeOut = USER_TIMEOUT;
  while ((I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))&&(TimeOut != 0x00))
  {}
  if(TimeOut == 0)
  {
    TimeOut_UserCallback();
  }
  
/* Slave Transmitter----------------------------------------------------------*/   
  
  /* Wait until end of data transfer */
  while (Tx_Idx < TXBUFFERSIZE)
  {} 
  
  if (Buffercmp(TxBuffer, RxBuffer, RXBUFFERSIZE) == PASSED)
  {
    /* LED2, LED3 and LED4 Toggle */
    STM_EVAL_LEDOn(LED2);
    STM_EVAL_LEDOn(LED3);
    STM_EVAL_LEDOn(LED4);
  }
  else 
  {   /* ED2, LED3 and LED4 On */
    STM_EVAL_LEDOff(LED2);
    STM_EVAL_LEDOff(LED3);
    STM_EVAL_LEDOff(LED4);
  } 
  
#endif /* I2C_SLAVE */
  while(1)
  {}
}
Example #13
0
int8_t I2C::send_no_ack()
{
	int8_t err = 0;
	I2C_AcknowledgeConfig(_I2Cx,DISABLE);
	return err;
}
//--------------------------------------------------------------
// Auslesen mehrerer Adresse per I2C von einem Slave
// slave_adr => I2C-Basis-Adresse vom Slave
// adr       => Start Register Adresse ab der gelesen wird
// cnt       => Anzahl der Bytewert die gelesen werden sollen
// Daten die gelesen worden sind, stehen danach in "I2C3_DATA"
//
// Return_wert :
//    0   , Ok
//  < 0   , Error
//--------------------------------------------------------------
int16_t UB_I2C3_ReadMultiByte(uint8_t slave_adr, uint8_t adr, uint8_t cnt)
{
  int16_t ret_wert=0;
  uint32_t timeout=I2C3_TIMEOUT;
  uint8_t wert,n;

  if(cnt==0) return(-8);
  if(cnt>I2C3_MULTIBYTE_ANZ) return(-9);

  // Start-Sequenz
  I2C_GenerateSTART(I2C3, ENABLE);

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-1));
  }

  if(cnt==1) {
    // ACK disable
    I2C_AcknowledgeConfig(I2C3, DISABLE);
  }
  else {
	// ACK enable
	I2C_AcknowledgeConfig(I2C3, ENABLE);
  }

  // Slave-Adresse senden (write)
  I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Transmitter);

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-2));
  }

  // ADDR-Flag löschen
  I2C3->SR2;

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-3));
  }

  // Adresse senden
  I2C_SendData(I2C3, adr);

  timeout=I2C3_TIMEOUT;
  while ((!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2C3, I2C_FLAG_BTF))) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-4));
  }

  // Start-Sequenz
  I2C_GenerateSTART(I2C3, ENABLE);

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-5));
  }

  // Slave-Adresse senden (read)
  I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Receiver);

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-6));
  }

  // ADDR-Flag löschen
  I2C3->SR2;

  // alle Daten auslesen
  for(n=0;n<cnt;n++) {

    if((n+1)>=cnt) {
      // ACK disable
      I2C_AcknowledgeConfig(I2C3, DISABLE);
      // Stop-Sequenz
      I2C_GenerateSTOP(I2C3, ENABLE);
    }

    timeout=I2C3_TIMEOUT;
    while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_RXNE)) {
      if(timeout!=0) timeout--; else return(P_I2C3_timeout(-7));
    }

    // Daten auslesen
    wert=I2C_ReceiveData(I2C3);

    // Daten in Array speichern
    I2C3_DATA[n]=wert;
  }

  // ACK enable
  I2C_AcknowledgeConfig(I2C3, ENABLE);

  ret_wert=0; // alles ok

  return(ret_wert);
}
Example #15
0
static rt_size_t stm32_i2c_xfer(struct rt_i2c_bus_device *bus,
                                struct rt_i2c_msg msgs[], rt_uint32_t num)
{
    struct rt_i2c_msg *msg;
    rt_int32_t i, ret;
    rt_uint16_t ignore_nack;

    I2C_GenerateSTART(I2C1, ENABLE);
    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    for (i = 0; i < num; i++)
    {
        msg = &msgs[i];
        ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
        if (!(msg->flags & RT_I2C_NO_START))
        {
            if (i)
            {
                I2C_GenerateSTART(I2C1, ENABLE);
            }
            I2C_SendAddress(I2C1, msg);
            if (msg->flags & RT_I2C_RD)
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
            else
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        }
        if (msg->flags & RT_I2C_RD)
        {
            if (!(msg->flags & RT_I2C_NO_READ_ACK))
                I2C_AcknowledgeConfig(I2C1,ENABLE);
            else
                I2C_AcknowledgeConfig(I2C1,DISABLE);
            ret = stm32_i2c_recv_bytes(I2C1, msg);
            if (ret >= 1)
                i2c_dbg("read %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_EIO;
                goto out;
            }
        }
        else
        {
            ret = stm32_i2c_send_bytes(I2C1, msg);
            if (ret >= 1)
                i2c_dbg("write %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_ERROR;
                goto out;
            }
        }
    }
    ret = i;

out:
    i2c_dbg("send stop condition\n");
    I2C_GenerateSTOP(I2C1, ENABLE);

    return ret;
}
/**
  * @brief  Read the configuration register from the LM75.
  * @param  None
  * @retval LM75 configuration register value.
  */
uint8_t LM75_ReadConfReg(void)
{
  __IO uint8_t RegValue = 0;

  /* Enable LM75_I2C acknowledgement if it is already disabled by other function */
  I2C_AcknowledgeConfig(LM75_I2C, ENABLE);
  /*----------------------------- Transmission Phase --------------------------*/
  /* Send LM75_I2C START condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on LM75_I2C EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter);

  /* Test on LM75_I2C EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(LM75_I2C, LM75_REG_CONF);

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

  /*----------------------------- Reception Phase -----------------------------*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(LM75_I2C, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }

  /* Disable LM75_I2C acknowledgement */
  I2C_AcknowledgeConfig(LM75_I2C, DISABLE);

  /* Send LM75_I2C STOP Condition */
  I2C_GenerateSTOP(LM75_I2C, ENABLE);

  /* Test on RXNE flag */
  while (I2C_GetFlagStatus(LM75_I2C, I2C_FLAG_RXNE) == RESET);

  /* Store LM75_I2C received data */
  RegValue = I2C_ReceiveData(LM75_I2C);

  /* Return configuration register value */
  return (RegValue);
}
Example #17
0
Status I2C_Read(I2C_TypeDef* I2Cx, uint8_t *buf,uint32_t nbyte, uint8_t SlaveAddress)
{
  __IO uint32_t Timeout = 0;

  //    I2Cx->CR2 |= I2C_IT_ERR;  interrupts for errors 

  if (!nbyte)
    return Success;



  // Wait for idle I2C interface

  Timed(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

  // Enable Acknowledgement, clear POS flag

  I2C_AcknowledgeConfig(I2Cx, ENABLE);
  I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);

  // Intiate Start Sequence (wait for EV5

  I2C_GenerateSTART(I2Cx, ENABLE);
  Timed(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

  // Send Address

  I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Receiver);

  // EV6
  
  Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR));

  if (nbyte == 1)
    {

      // Clear Ack bit      

      I2C_AcknowledgeConfig(I2Cx, DISABLE);       

      // EV6_1 -- must be atomic -- Clear ADDR, generate STOP

      __disable_irq();
      (void) I2Cx->SR2;                           
      I2C_GenerateSTOP(I2Cx,ENABLE);      
      __enable_irq();

      // Receive data   EV7

      Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_RXNE));
      *buf++ = I2C_ReceiveData(I2Cx);

    }
  else if (nbyte == 2)
    {
      // Set POS flag

      I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);

      // EV6_1 -- must be atomic and in this order

      __disable_irq();
      (void) I2Cx->SR2;                           // Clear ADDR flag
      I2C_AcknowledgeConfig(I2Cx, DISABLE);       // Clear Ack bit
      __enable_irq();

      // EV7_3  -- Wait for BTF, program stop, read data twice

      Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF));

      __disable_irq();
      I2C_GenerateSTOP(I2Cx,ENABLE);
      *buf++ = I2Cx->DR;
      __enable_irq();

      *buf++ = I2Cx->DR;

    }
  else 
    {
      (void) I2Cx->SR2;                           // Clear ADDR flag
      while (nbyte-- != 3)
	{
	  // EV7 -- cannot guarantee 1 transfer completion time, wait for BTF 
          //        instead of RXNE

	  Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF)); 
	  *buf++ = I2C_ReceiveData(I2Cx);
	}

      Timed(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF));  

      // EV7_2 -- Figure 1 has an error, doesn't read N-2 !

      I2C_AcknowledgeConfig(I2Cx, DISABLE);           // clear ack bit

      __disable_irq();
      *buf++ = I2C_ReceiveData(I2Cx);             // receive byte N-2
      I2C_GenerateSTOP(I2Cx,ENABLE);                  // program stop
      __enable_irq();

      *buf++ = I2C_ReceiveData(I2Cx);             // receive byte N-1

      // wait for byte N

      Timed(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); 
      *buf++ = I2C_ReceiveData(I2Cx);

      nbyte = 0;

    }

  // Wait for stop

  Timed(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF));
  return Success;

 errReturn:

  // Any cleanup here
  return Error;

}
Example #18
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;
    }
/*******************************************************************************
* Function Name  : I2C_LM75_ConfReg_Read
* Description    : Read the configuration register from the LM75.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
uint8_t I2C_LM75_ConfReg_Read(void)
{
  uint32_t RegValue = 0;

  /*----- Transmission Phase -----*/
  /* Send I2C1 START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on I2C1 EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(I2C1, LM75_Addr, I2C_Direction_Transmitter);
  
  /* Test on I2C1 EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(I2C1, LM75_CONF_Reg);
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }

  /*----- Reception Phase -----*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }
  
  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(I2C1, LM75_Addr, I2C_Direction_Receiver);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }

  /* Disable I2C1 acknowledgement */
  I2C_AcknowledgeConfig(I2C1, DISABLE);
  
  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);

  /* Test on EV7 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  /* EV7 */
  {
  }
  
  /* Store I2C1 received data */
  RegValue = I2C_ReceiveData(I2C1);

  /* Return configuration register value */
  return (RegValue);    
}
Example #20
0
uint8_t I2C_ReadShort(uint16_t reg_address, uint16_t dev_address)
{
	uint16_t data = 0;
	uint32_t timeout = I2C_TIMEOUT;
	dev_address = dev_address << 1;

	I2C_AcknowledgeConfig(I2C1, ENABLE);

	while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)) {
		if (! timeout--)
			Usart1Put('q');
	}


	I2C_GenerateSTART(I2C1, ENABLE);

	timeout = I2C_TIMEOUT;
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)){
		if (! timeout--)
			Usart1Put('w');
	}


	I2C_Send7bitAddress(I2C1, dev_address, I2C_Direction_Transmitter);

	timeout = I2C_TIMEOUT;
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
		if (! timeout--)
			Usart1Put('e');
	}

	I2C_SendData(I2C1, reg_address);	// write register address
	timeout = I2C_TIMEOUT;
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
		if (! timeout--)
			Usart1Put('r');

	}

	/* restart */
	I2C_GenerateSTART(I2C1, ENABLE);
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)){
			if (! timeout--)
				Usart1Put('t');
	}

	I2C_Send7bitAddress(I2C1, dev_address, I2C_Direction_Receiver);
	timeout = I2C_TIMEOUT;
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){
		if (! timeout--)
			Usart1Put('y');
	}

	/* before last one, disable ACK */
	I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Next);
	I2C_AcknowledgeConfig(I2C1, DISABLE);


	/* Receive */
	I2C_ReceiveData(I2C1);
	timeout = I2C_TIMEOUT;
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){
		if (! timeout--)
			Usart1Put('u');
	}

	/* Receive */
	data =	I2C_ReceiveData(I2C1);
	timeout = I2C_TIMEOUT;
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){
		if (! timeout--)
			Usart1Put('i');
	}

	I2C_GenerateSTOP(I2C1, ENABLE);
	timeout = I2C_TIMEOUT;
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)){
		if (! timeout--)
			Usart1Put('o');
	}


	return data;
}
/*******************************************************************************
* Function Name  : I2C_LM75_ShutDown
* Description    : Enables or disables the LM75.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void I2C_LM75_ShutDown(FunctionalState NewState)
{
  uint32_t RegValue = 0;

  /*----- Transmission Phase -----*/
  /* Send I2C1 START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on I2C1 EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }

  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(I2C1, LM75_Addr, I2C_Direction_Transmitter);
  
  /* Test on I2C1 EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }

  /* Send the configuration register data pointer */
  I2C_SendData(I2C1, LM75_CONF_Reg);
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))  /* EV8 */
  {
  }

  /*----- Reception Phase -----*/
  /* Send Re-STRAT condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }
  
  /* Send STLM75 slave address for read */
  I2C_Send7bitAddress(I2C1, LM75_Addr, I2C_Direction_Receiver);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))  /* EV6 */
  {
  }
  
  /* Disable I2C1 acknowledgement */
  I2C_AcknowledgeConfig(I2C1, DISABLE);
  
  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);

  /* Test on EV7 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  /* EV7 */
  {
  }
  
  /* Store I2C1 received data */
  RegValue = I2C_ReceiveData(I2C1);

  /*----- Transmission Phase -----*/
  /* Send I2C1 START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on I2C1 EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* EV5 */
  {
  }
  
  /* Send STLM75 slave address for write */
  I2C_Send7bitAddress(I2C1, LM75_Addr, I2C_Direction_Transmitter);
  
  /* Test on I2C1 EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */
  {
  }
  
  /* Send the configuration register data pointer */
  I2C_SendData(I2C1, LM75_CONF_Reg);
  
  /* Test on I2C1 EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */
  {
  }

  /* Enable or disable SD bit */
  if (NewState != DISABLE)
  {
    /* Disable LM75 */
    I2C_SendData(I2C1, RegValue | LM75_SD_Set);
  }
  else
  {
    /* Enable LM75 */
    I2C_SendData(I2C1, RegValue & LM75_SD_Reset);
  }

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

  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE);     
}
Example #22
0
int8_t I2c::send_ack()
{
    int8_t err = 0;
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    return err;
}
Example #23
0
// Read data from I2C port
// input:
//   buf - pointer to data buffer
//   nbytes - number of bytes to receive
//   SlaveAddress - address of slave device
// return:
//   I2C_ERROR if there was a timeout during I2C operations, I2C_SUCCESS otherwise
I2C_Status I2C2_Read(uint8_t *buf, uint32_t nbytes, uint8_t SlaveAddress) {
	volatile uint32_t TimeOut;

	I2C_AcknowledgeConfig(I2C2_PORT,ENABLE); // Enable Acknowledgment
	I2C_NACKPositionConfig(I2C2_PORT,I2C_NACKPosition_Current); // Clear POS flag

	// Initiate start sequence
	I2C_GenerateSTART(I2C2_PORT,ENABLE);
	// Wait for EV5
	TimeOut = 0;
	while (!I2C_CheckEvent(I2C2_PORT,I2C_EVENT_MASTER_MODE_SELECT) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
	if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;

	// Send slave address
	I2C_Send7bitAddress(I2C2_PORT,SlaveAddress,I2C_Direction_Receiver); // Send slave address
	// Wait for EV6
	TimeOut = 0;
	while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_ADDR) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
	if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;

	// There are can be three cases:
	//   read 1 byte
	//   read 2 bytes
	//   read more than 2 bytes
	if (nbytes == 1) {
		// Receive 1 byte (AN2824 figure 2)
		I2C_AcknowledgeConfig(I2C2_PORT,DISABLE); // Disable I2C acknowledgment (clear ACK bit)
		// EV6_1 must be atomic operation (AN2824)
		__disable_irq();
		(void) I2C2_PORT->SR1; // Clear ADDR
		(void) I2C2_PORT->SR2;
		I2C_GenerateSTOP(I2C2_PORT,ENABLE); // Send STOP condition
		__enable_irq();
		// Wait for RxNE flag (receive buffer not empty) EV7
		TimeOut = 0;
		while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_RXNE) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
		if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;
		*buf++ = I2C_ReceiveData(I2C2_PORT); // Receive byte
	} else if (nbytes == 2) {
		// Receive 2 bytes (AN2824 figure 2)
		I2C_NACKPositionConfig(I2C2_PORT,I2C_NACKPosition_Next); // Set POS flag
		// EV6_1 must be atomic operation (AN2824)
		__disable_irq();
		(void) I2C2_PORT->SR2; // Clear ADDR
		I2C_AcknowledgeConfig(I2C2_PORT,DISABLE); // Clear ACK bit
		__enable_irq();
		// Wait for BTF flag set (byte transfer finished) EV7_3
		TimeOut = 0;
		while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_BTF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
		if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;

		__disable_irq();
		I2C_GenerateSTOP(I2C2_PORT,ENABLE); // Send STOP condition
		*buf++ = I2C2_PORT->DR; // Faster than call I2C_ReceiveData()
		__enable_irq();

		*buf++ = I2C2_PORT->DR; // Read second received byte
	} else {
		// Receive more than 2 bytes (AN2824 figure 1)
		(void) I2C2_PORT->SR2; // Clear ADDR flag
		while (nbytes-- != 3) {
			// Wait for BTF (cannot guarantee 1 transfer completion time)
			TimeOut = 0;
			while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_BTF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
			if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;
			*buf++ = I2C_ReceiveData(I2C2_PORT);
		}
		// Wait for BTF flag set (byte transfer finished) EV7_2
		TimeOut = 0;
		while (!I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_BTF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
		if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;

		I2C_AcknowledgeConfig(I2C2_PORT,DISABLE); // Clear ACK bit

		__disable_irq();
		*buf++ = I2C_ReceiveData(I2C2_PORT); // Receive byte N-2
		I2C_GenerateSTOP(I2C2_PORT,ENABLE); // Send STOP condition
		__enable_irq();

		*buf++ = I2C_ReceiveData(I2C2_PORT); // Receive byte N-1
		// Wait for last byte received
		TimeOut = 0;
		while (!I2C_CheckEvent(I2C2_PORT,I2C_EVENT_MASTER_BYTE_RECEIVED) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
		if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;
		*buf++ = I2C_ReceiveData(I2C2_PORT); // Receive last byte

		nbytes = 0;
	}

	// Wait for STOP flag
	TimeOut = 0;
	while (I2C_GetFlagStatus(I2C2_PORT,I2C_FLAG_STOPF) && TimeOut < I2C_WAIT_TIMEOUT) TimeOut++;
	if (TimeOut == I2C_WAIT_TIMEOUT) return I2C_ERROR;

	return I2C_SUCCESS;
}
Example #24
0
/**
  * @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 to know when the transfer is complete.
  * 
  * @note This function ensures data reading from EEPROM, it assumes that I2C is 
  *       used with polling or its interrupt priority is not the highest in the 
  *       application. 
  *       Method 2 transfer sequence is implemented in this function(refer to RM0016
  *       for more details). 3 bytes, 2bytes and 1 byte reception cases are handled.           
  * 
  * @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)
{

  /* While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus( I2C_FLAG_BUSBUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }

  /* Send START condition */
  I2C_GenerateSTART(ENABLE);

  /* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }

  /* Send EEPROM address for write */
  I2C_Send7bitAddress( (uint8_t)sEEAddress, I2C_DIRECTION_TX);

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

#ifdef sEE_M24C64_32

  /* Send the EEPROM's internal address to read from: MSB of the address first */
  I2C_SendData( (uint8_t)((ReadAddr & 0xFF00) >> 8));    

  /* Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }

  /* Send the EEPROM's internal address to read from: LSB of the address */
  I2C_SendData( (uint8_t)(ReadAddr & 0x00FF));    

#endif /* sEE_M24C64_32 */

  /* Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(I2C_FLAG_TRANSFERFINISHED) == RESET)
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /* Send START condition a second time */  
  I2C_GenerateSTART( ENABLE);
  
  /* Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  } 
  
  /* Send EEPROM address for read */
  I2C_Send7bitAddress((uint8_t)sEEAddress, I2C_DIRECTION_RX);

  /* Read data from first byte until byte N-3 */
  if ((uint16_t)(*NumByteToRead)> 3) 
    {
      /* Poll on BTF */
      sEETimeout = sEE_FLAG_TIMEOUT;
      while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET)
      {
        if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
      } 

      /* Read a byte from the EEPROM */
      *pBuffer = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      *pBuffer++;

      /* Decrement the read bytes counter */
      (uint16_t)(*NumByteToRead)--;
    }

  /*  Remains three data for read: data N-2, data N-1, Data N */
  /* Three Bytes Master Reception procedure (POLLING) ------------------------*/
  if ((uint16_t)(*NumByteToRead) == 3)  
  {
    /* Data N-2 in DR and data N -1 in shift register */
    /* Poll on BTF */
      sEETimeout = sEE_FLAG_TIMEOUT;
      while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET)
      {
        if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
      } 

      /* Clear ACK */
      I2C_AcknowledgeConfig(I2C_ACK_NONE);

      /* Call User callback for critical section start (should typically disable interrupts) */
      sEE_EnterCriticalSection_UserCallback();

      /* Read Data N-2 */
      *pBuffer = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      *pBuffer++;

      /* Program the STOP */
      I2C_GenerateSTOP(ENABLE);

      /* Read DataN-1 */
      *pBuffer = I2C_ReceiveData();

       /* Call User callback for critical section end (should typically re-enable interrupts) */
       sEE_ExitCriticalSection_UserCallback();

      /* Point to the next location where the byte read will be saved */
      *pBuffer++;

      /* Poll on RxNE */
      sEETimeout = sEE_FLAG_TIMEOUT;
      while (I2C_GetFlagStatus( I2C_FLAG_RXNOTEMPTY) == RESET)
      {
        if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
      }
      /* Read DataN */
      *pBuffer = I2C_ReceiveData();

      /* Reset the number of bytes to be read from the EEPROM */
      NumByteToRead = 0;

    }
  
  /* If number of data to be read is 2 */
  /* Tow Bytes Master Reception procedure (POLLING) ---------------------------*/
  if ((uint16_t)(*NumByteToRead) == 2)
  {
    /* Enable acknowledgement on next byte (set POS and ACK bits)*/
    I2C_AcknowledgeConfig(I2C_ACK_NEXT);
    
    /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(I2C_GetFlagStatus( I2C_FLAG_ADDRESSSENTMATCHED) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }
    
    /* Clear ADDR register by reading SR1 then SR3 register (SR1 has already been read) */
     (void)I2C->SR3;
        
    /* Disable Acknowledgement */
    I2C_AcknowledgeConfig(I2C_ACK_NONE);
    
    /* Wait for BTF flag to be set */
      sEETimeout = sEE_FLAG_TIMEOUT;
      while (I2C_GetFlagStatus( I2C_FLAG_TRANSFERFINISHED) == RESET)
      {
        if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
      } 
    
    /* Call User callback for critical section start (should typically disable interrupts) */
    sEE_EnterCriticalSection_UserCallback();
    
    /* Program the STOP */
      I2C_GenerateSTOP(ENABLE);
      
    /* Read Data N-1 */
      *pBuffer = I2C_ReceiveData();

      /* Point to the next location where the byte read will be saved */
      *pBuffer++;  
           
    /* Call User callback for critical section end (should typically re-enable interrupts) */
       sEE_ExitCriticalSection_UserCallback();
       
    /* Read Data N */
      *pBuffer = I2C_ReceiveData();
          
    /* Reset the number of bytes to be read from the EEPROM */
      NumByteToRead = 0;   
  }
  
  /* If number of data to be read is 1 */
  /* 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( I2C_FLAG_ADDRESSSENTMATCHED) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    } 
       
    /* Disable Acknowledgement */
    I2C_AcknowledgeConfig(I2C_ACK_NONE);   

    /* Call User callback for critical section start (should typically disable interrupts) */
    sEE_EnterCriticalSection_UserCallback();
    
    /* Clear ADDR register by reading SR1 then SR3 register (SR1 has already been read) */
    (void)sEE_I2C->SR3;
    
    /* Send STOP Condition */
    I2C_GenerateSTOP( ENABLE);
   
    /* Call User callback for critical section end (should typically re-enable interrupts) */
    sEE_ExitCriticalSection_UserCallback();
    
    /* Wait for the byte to be received */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(I2C_GetFlagStatus( I2C_FLAG_RXNOTEMPTY) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }
    
    /* Read the byte received from the EEPROM */
    *pBuffer = I2C_ReceiveData();
    
    /* 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->CR2 & I2C_CR2_STOP)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }  
    
    /* Re-Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig( I2C_ACK_CURR);    
  }
  /* If all operations OK, return sEE_OK (0) */
  return sEE_OK;  
}
/****************************************************************************************************
 * @fn      I2C_Slave_Handler
 *          Handles the I2C Slave communication events
 *
 ***************************************************************************************************/
void I2C_Slave_Handler(I2C_TypeDef *pI2C, uint8_t irqCh)
{
    uint32_t i2cslvstate = I2C_GetLastEvent(pI2C);
    uint8_t slvRxData;

    /* If error event - clear it */
    if ((irqCh == I2C_SLAVE_BUS_ERROR_IRQ_CH) && ((i2cslvstate & 0xFF00) != 0))
    {
        pI2C->SR1 &= 0x00FF;

        if ((i2cslvstate & 0xFF00) == I2C_EVENT_SLAVE_ACK_FAILURE)
        {
            /* Master NAKed - this was end of transaction when slave is transmitting */
            isr_evt_set(I2C_SLAVE_XFER_DONE, asfTaskHandleTable[I2CSLAVE_COMM_TASK_ID].handle );
            slave_xfer.rxCnt = 0;
            return;
        }
    }

    /* Below three states are for Slave mode: Address Received, TX, and RX. */
    switch ( i2cslvstate )
    {
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:  /* 00020040 */
    case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF):
        SensorHubIntLow(); //Deassert Interrupt
        slvRxData = (uint8_t)I2C_ReceiveData(pI2C);
        slave_xfer.rxCnt++;
        if (slave_xfer.rxCnt == 1) //First byte received must be the register address
        {
            switch (slvRxData)
            {
            case SH_REG_IRQ_CAUSE:
                slave_xfer.txBuff = &SlaveRegMap.irq_cause;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_RD_LEN:
                slave_xfer.txBuff = &SlaveRegMap.read_len;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_ACK:
                //TODO -- Need to define state machine logic that would handle ACK
                break;

            case SH_REG_REQUEST:
                //TODO
                break;

            case SH_REG_WHO_AM_I:
                slave_xfer.txBuff = &SlaveRegMap.whoami;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_VERSION0:
                slave_xfer.txBuff = &SlaveRegMap.version0;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_VERSION1:
                slave_xfer.txBuff = &SlaveRegMap.version1;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_RD_MEM:
                slave_xfer.txBuff = &SlaveRegMap.rd_mem[0];
                slave_xfer.txSz = SlaveRegMap.read_len;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_WR_MEM:
            default:
                //Not supported at this time so just NACK it for now
                I2C_AcknowledgeConfig(pI2C, DISABLE);
                break;

            case 0xEE: //Ack write
                //Ack is ignored for now
                break;
            }
        }
        else
        {
            //TODO Implement host command functions
        }
        break;

    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:  /* 00060082 */
        slave_xfer.rxCnt = 0; /* I2C Read Mode - no more receive */
        /* Fall thru */
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: /* 00060080 */
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
    case 0x00060004: //Sometimes we get this event and the driver is stuck in ISR!
        /* In transmit we will do not want to send data beyond the register set */
        if (&slave_xfer.txBuff[slave_xfer.txCnt] < &SlaveRegMap.endMarker)
        {
            I2C_SendData(pI2C, slave_xfer.txBuff[slave_xfer.txCnt++]);
        }
        else
        {
            I2C_SendData(pI2C, I2C_OVERREACH_VAL); //This value signifies read beyond allowed range
        }
        break;

    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: /* 00020002 */
        /* Nothing to do except continue */
        break;

    case I2C_EVENT_SLAVE_STOP_DETECTED: /* This is end of transaction when slave is receiving */
        /* if (STOPF==1) Read SR1;Write CR1 */
        I2C_GetFlagStatus(pI2C, I2C_FLAG_STOPF);
        I2C_Cmd(pI2C, ENABLE);
        isr_evt_set(I2C_SLAVE_XFER_DONE, asfTaskHandleTable[I2CSLAVE_COMM_TASK_ID].handle );
        slave_xfer.rxCnt = 0;
        /* Re-enable ACK (in case it was disabled) */
        I2C_AcknowledgeConfig(pI2C, ENABLE);
        break;

    default:
        break;
    }
}
Example #26
0
/***************************************************************************//**
 * @brief      Reads a block of data from the EEPROM.
 * @param[in]  pBuffer : pointer to the buffer that receives the data read
 *                       from the EEPROM.
 * @param[in]  ReadAddr : EEPROM's internal address to read from.
 * @param[in]  NumByteToRead : number of bytes to read from the EEPROM.
 * @return     None
 ******************************************************************************/
void I2C_EE_BufferRead(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
{
    /* While the bus is busy */
    while(I2C_GetFlagStatus(I2C_EE, I2C_FLAG_BUSY));

    /* Send START condition */
    I2C_GenerateSTART(I2C_EE, ENABLE);

    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send EEPROM address for write */
    I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);

    /* Test on EV6 and clear it */
    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Send the EEPROM's internal address to read from: MSB of the address first */
    I2C_SendData(I2C_EE, (uint8_t)((ReadAddr & 0xFF00) >> 8));

    /* Test on EV8 and clear it */
    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send the EEPROM's internal address to read from: LSB of the address */
    I2C_SendData(I2C_EE, (uint8_t)(ReadAddr & 0x00FF));

    /* Test on EV8 and clear it */
    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send STRAT condition a second time */
    I2C_GenerateSTART(I2C_EE, ENABLE);

    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send EEPROM address for read */
    I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Receiver);

    /* Test on EV6 and clear it */
    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    /* While there is data to be read */
    while(NumByteToRead)
    {
        if(NumByteToRead == 1)
        {
            /* Disable Acknowledgement */
            I2C_AcknowledgeConfig(I2C_EE, DISABLE);

            /* Send STOP Condition */
            I2C_GenerateSTOP(I2C_EE, ENABLE);
        }

    /* Test on EV7 and clear it */
        if(I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            /* Read a byte from the EEPROM */
            *pBuffer = I2C_ReceiveData(I2C_EE);

            /* Point to the next location where the byte read will be saved */
            pBuffer++;

            /* Decrement the read bytes counter */
            NumByteToRead--;
        }
    }

    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2C_EE, ENABLE);
}
//--------------------------------------------------------------
// Auslesen einer Adresse per I2C von einem Slave
// slave_adr => I2C-Basis-Adresse vom Slave
// adr       => Register Adresse die gelesen wird
//
// Return_wert :
//  0...255 , Bytewert der gelesen wurde
//  < 0     , Error
//--------------------------------------------------------------
int16_t UB_I2C3_ReadByte(uint8_t slave_adr, uint8_t adr)
{
  int16_t ret_wert=0;
  uint32_t timeout=I2C3_TIMEOUT;

  // Start-Sequenz
  I2C_GenerateSTART(I2C3, ENABLE);
  
  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-1));
  }

  // ACK disable
  I2C_AcknowledgeConfig(I2C3, DISABLE);

  // Slave-Adresse senden (write)
  I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Transmitter); 

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-2));
  }  

  // ADDR-Flag löschen
  I2C3->SR2;

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-3));
  }  

  // Adresse senden
  I2C_SendData(I2C3, adr);

  timeout=I2C3_TIMEOUT;
  while ((!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2C3, I2C_FLAG_BTF))) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-4));
  }

  // Start-Sequenz
  I2C_GenerateSTART(I2C3, ENABLE);

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_SB)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-5));
  }

  // Slave-Adresse senden (read)
  I2C_Send7bitAddress(I2C3, slave_adr, I2C_Direction_Receiver);

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_ADDR)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-6));
  }

  // ADDR-Flag löschen
  I2C3->SR2;

  timeout=I2C3_TIMEOUT;
  while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_RXNE)) {
    if(timeout!=0) timeout--; else return(P_I2C3_timeout(-7));
  } 

  // Stop-Sequenz
  I2C_GenerateSTOP(I2C3, ENABLE);

  // Daten auslesen
  ret_wert=(int16_t)(I2C_ReceiveData(I2C3));

  // ACK enable
  I2C_AcknowledgeConfig(I2C3, ENABLE);

  return(ret_wert);
}
Example #28
0
void i2c_ev_handler(void)
{
    static uint8_t subaddress_sent, final_stop;                         // flag to indicate if subaddess sent, flag to indicate final bus condition
    static int8_t index;                                                // index is signed -1 == send the subaddress
    uint8_t SReg_1 = I2C1->SR1;                                         // read the status register here

    if (SReg_1 & 0x0001) {                                              // we just sent a start - EV5 in ref manual
        I2C1->CR1 &= ~0x0800;                                           // reset the POS bit so ACK/NACK applied to the current byte
        I2C_AcknowledgeConfig(I2C1, ENABLE);                            // make sure ACK is on
        index = 0;                                                      // reset the index
        if (reading && (subaddress_sent || 0xFF == reg)) {              // we have sent the subaddr
            subaddress_sent = 1;                                        // make sure this is set in case of no subaddress, so following code runs correctly
            if (bytes == 2)
                I2C1->CR1 |= 0x0800;                                    // set the POS bit so NACK applied to the final byte in the two byte read
            I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);    // send the address and set hardware mode
        } else {                                                        // direction is Tx, or we havent sent the sub and rep start
            I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter); // send the address and set hardware mode
            if (reg != 0xFF)                                            // 0xFF as subaddress means it will be ignored, in Tx or Rx mode
                index = -1;                                             // send a subaddress
        }
    } else if (SReg_1 & 0x0002) {                                       // we just sent the address - EV6 in ref manual
        // Read SR1,2 to clear ADDR
        __DMB();                                                        // memory fence to control hardware
        if (bytes == 1 && reading && subaddress_sent) {                 // we are receiving 1 byte - EV6_3
            I2C_AcknowledgeConfig(I2C1, DISABLE);                       // turn off ACK
            __DMB();
            (void)I2C1->SR2;                                            // clear ADDR after ACK is turned off
            I2C_GenerateSTOP(I2C1, ENABLE);                             // program the stop
            final_stop = 1;
            I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);                     // allow us to have an EV7
        } else {                                                        // EV6 and EV6_1
            (void)I2C1->SR2;                                            // clear the ADDR here
            __DMB();
            if (bytes == 2 && reading && subaddress_sent) {             // rx 2 bytes - EV6_1
                I2C_AcknowledgeConfig(I2C1, DISABLE);                   // turn off ACK
                I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);                // disable TXE to allow the buffer to fill
            } else if (bytes == 3 && reading && subaddress_sent)        // rx 3 bytes
                I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);                // make sure RXNE disabled so we get a BTF in two bytes time
            else                                                        // receiving greater than three bytes, sending subaddress, or transmitting
                I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
        }
    } else if (SReg_1 & 0x004) {                                        // Byte transfer finished - EV7_2, EV7_3 or EV8_2
        final_stop = 1;
        if (reading && subaddress_sent) {                               // EV7_2, EV7_3
            if (bytes > 2) {                                            // EV7_2
                I2C_AcknowledgeConfig(I2C1, DISABLE);                   // turn off ACK
                read_p[index++] = (uint8_t)I2C1->DR;                    // read data N-2
                I2C_GenerateSTOP(I2C1, ENABLE);                         // program the Stop
                final_stop = 1;                                         // required to fix hardware
                read_p[index++] = (uint8_t)I2C1->DR;                    // read data N - 1
                I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);                 // enable TXE to allow the final EV7
            } else {                                                    // EV7_3
                if (final_stop)
                    I2C_GenerateSTOP(I2C1, ENABLE);                     // program the Stop
                else
                    I2C_GenerateSTART(I2C1, ENABLE);                    // program a rep start
                read_p[index++] = (uint8_t)I2C1->DR;                    // read data N - 1
                read_p[index++] = (uint8_t)I2C1->DR;                    // read data N
                index++;                                                // to show job completed
            }
        } else {                                                        // EV8_2, which may be due to a subaddress sent or a write completion
            if (subaddress_sent || (writing)) {
                if (final_stop)
                    I2C_GenerateSTOP(I2C1, ENABLE);                     // program the Stop
                else
                    I2C_GenerateSTART(I2C1, ENABLE);                    // program a rep start
                index++;                                                // to show that the job is complete
            } else {                                                    // We need to send a subaddress
                I2C_GenerateSTART(I2C1, ENABLE);                        // program the repeated Start
                subaddress_sent = 1;                                    // this is set back to zero upon completion of the current task
            }
        }
        // we must wait for the start to clear, otherwise we get constant BTF
        while (I2C1->CR1 & 0x0100) { ; }
    } else if (SReg_1 & 0x0040) {                                       // Byte received - EV7
        read_p[index++] = (uint8_t)I2C1->DR;
        if (bytes == (index + 3))
            I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);                    // disable TXE to allow the buffer to flush so we can get an EV7_2
        if (bytes == index)                                             // We have completed a final EV7
            index++;                                                    // to show job is complete
    } else if (SReg_1 & 0x0080) {                                       // Byte transmitted EV8 / EV8_1
        if (index != -1) {                                              // we dont have a subaddress to send
            I2C1->DR = write_p[index++];
            if (bytes == index)                                         // we have sent all the data
                I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);                // disable TXE to allow the buffer to flush
        } else {
            index++;
            I2C1->DR = reg;                                             // send the subaddress
            if (reading || !bytes)                                      // if receiving or sending 0 bytes, flush now
                I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);                // disable TXE to allow the buffer to flush
        }
    }
    if (index == bytes + 1) {                                           // we have completed the current job
        subaddress_sent = 0;                                            // reset this here
        if (final_stop)                                                 // If there is a final stop and no more jobs, bus is inactive, disable interrupts to prevent BTF
            I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_ERR, DISABLE);       // Disable EVT and ERR interrupts while bus inactive
        busy = 0;
    }
}
/**
  * @brief  Reads a buffer of 4 bytes from IO_Expander registers.
  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR
  *         or IOE_2_ADDR. 
  * @param  RegisterAddr: The target register adress (between 00x and 0x24)
  * @retval : The value of the read register (0xAA if Timout occured)   
  */
uint32_t I2C_ReadDataBuffer(u8 DeviceAddr, uint32_t RegisterAddr)
{
  u8 Buffer[4] , idx = 2;
  
  /* Initialize the buffer */
  Buffer[0] = 0; 
  Buffer[1] = 0; 
  Buffer[2] = 0; 
  Buffer[3] = 0;   
  
  /* Disable the I2C1 peripheral  */
  I2C_Cmd(I2C1, DISABLE);

  /* Reset all I2C2 registers */
  I2C_SoftwareResetCmd(I2C1, ENABLE);
  I2C_SoftwareResetCmd(I2C1, DISABLE);

  /* Configure the I2C peripheral */
  IOE_I2C_Config();
  
  /* Enable the I2C peripheral */
  I2C_GenerateSTART(I2C1, ENABLE);
 
  TimeOut = TIMEOUT_MAX;
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) 
  {
    if (TimeOut-- == 0) return IOE_TIEMOUT;
  }
   
  /* Send device address for write */
  I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Transmitter);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))  
  {
    if (TimeOut-- == 0) return IOE_TIEMOUT;
  }
  
  /* Clear EV6 by setting again the PE bit */
  I2C_Cmd(I2C1, ENABLE);
  
  /* Send the device's internal address to write to */
  I2C_SendData(I2C1, RegisterAddr);  
  
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 
  {
    if (TimeOut-- == 0) return IOE_TIEMOUT;
  }
  
  /* Send STRAT condition a second time */  
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) 
  {
    if (TimeOut-- == 0) return IOE_TIEMOUT;
  }
  
  /* Send EEPROM address for read */
  I2C_Send7bitAddress(I2C1, DeviceAddr, I2C_Direction_Receiver);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) 
  {
    if (TimeOut-- == 0) return IOE_TIEMOUT;
  }
  
  /* While there is data to be read */
  while(idx)  
  {
    if(idx == 1)
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C1, DISABLE);
      
      /* Send STOP Condition */
      I2C_GenerateSTOP(I2C1, ENABLE);
    }
    
    /* Test on EV7 and clear it */
    if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  
    {      
      /* Read a byte from the EEPROM */
      Buffer[idx-1] = I2C_ReceiveData(I2C1);
    
      /* Decrement the read bytes counter */
      idx--;        
    }   
  }
  
  /* Enable Acknowledgement to be ready for another reception */
  I2C_AcknowledgeConfig(I2C1, ENABLE);
  
  /* return a pointer to the buffer */
  return *(uint32_t *)Buffer;
}