BME680 with STM32F103C8

Hi. I am planning to use BME680 in my project but have some questions. I already downloaded sample code for BSEC and bme680 api and looked through it. But I dont understand why I must use BSEC. Is it important to use BSEC and also *.lib file for my platform or I can use only functions from bme680.c? When I compile my project in Keil MDK5 it gives a lot of errors L6406E: No space in execution regions with .ANY selector matching .....because I use in this project E-Ink display and nrf24l01.

Also I have problem in communicating with sensor. I already filled bus_write and bus_read functions:

 

int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
    uint16_t i;
	  int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */

    /*
     * Data on the bus should be like
     * |------------+---------------------|
     * | I2C action | Data                |
     * |------------+---------------------|
     * | Start      | -                   |
     * | Write      | (reg_addr)          |
     * | Write      | (reg_data[0])       |
     * | Write      | (....)              |
     * | Write      | (reg_data[len - 1]) |
     * | Stop       | -                   |
     * |------------+---------------------|
     */
    I2C_AcknowledgeConfig(I2C_PORT,ENABLE); // Enable I2C acknowledgment
	  I2C_GenerateSTART(I2C_PORT,ENABLE);
	  while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_MODE_SELECT)){}; // Wait for EV5
	  UART1_Transmit_string("\r\nStart sent");	
	
	
	  I2C_Send7bitAddress(I2C_PORT,dev_addr,I2C_Direction_Transmitter); // Send slave address
		UART1_Transmit_string("\r\nDev_addr sent");
	  while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}; // Wait for EV6
	  	
			
	  I2C_SendData(I2C_PORT,reg_addr); // Send register address
		UART1_Transmit_string("\r\nReg_addr sent");
	  while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
	  				
	  for(i=0; i < data_len; i++)
     {	
    	I2C_SendData(I2C_PORT, reg_data_ptr[i]); // Send all bytes
	    while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
      }
  	I2C_GenerateSTOP(I2C_PORT,ENABLE);
    return rslt;
}

int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
	   uint16_t i =0;
	   uint8_t status = 0;

	I2C_AcknowledgeConfig(I2C_PORT,ENABLE); // Enable I2C acknowledgment
	I2C_GenerateSTART(I2C_PORT,ENABLE);
	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_MODE_SELECT)); // Wait for EV5
	
	I2C_Send7bitAddress(I2C_PORT,dev_addr,I2C_Direction_Transmitter); // Send slave address 0x76
	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // Wait for EV6
	
	I2C_SendData(I2C_PORT,reg_addr); // Send register address
	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Wait for EV8
	
	I2C_GenerateSTOP(I2C_PORT,ENABLE); // Send STOP condition
	delay_ms_sys(1);
	
	I2C_GenerateSTART(I2C_PORT,ENABLE); // Send repeated START condition (aka Re-START)
	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_MODE_SELECT)); // Wait for EV5
	
	I2C_Send7bitAddress(I2C_PORT,dev_addr,I2C_Direction_Receiver); // Send slave address for READ
	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); // Wait for EV6
	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_RECEIVED)); // Wait for EV7 (Byte received from slave)
	
	status = I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_BYTE_RECEIVED);
	//status = I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
	for(i=0; i < data_len; i++)
     {
	   reg_data_ptr[i] = I2C_ReceiveData(I2C_PORT); // Receive high byte   
	   while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_RECEIVED)); // Wait for EV7 (Byte received from slave)
		 }
		 
     I2C_GenerateSTOP(I2C_PORT,ENABLE); // Send STOP condition
		 
	/* Return 0 for Success, non-zero for failure */	
  if(status == 1)return 0;
  else		return status;   
}

 

but sensor did not answering(I checked it with logic analyzer). It stops after slave address sent(0x76).

 

Best reply by Inactive Member

I don't have access to the documentation of your I2C library, but you may want to check how the implementation of I2C_Send7bitAddress() handles the slave address alignement.

The BME680 in I2C mode expects the Save Address to be left aligned, with the LSB as R/W bit:

Here is an example of chip ID read I2C transaction (note that in the Analyzer Settings, Address Display is set to "7-bit, address bits only"):

With your library, you may need to manually shift the slave address, e.g.:

 

I2C_Send7bitAddress(I2C1, (dev_addr << 1), I2C_Direction_Transmitter); // Send slave address for write
//[...]
I2C_Send7bitAddress(I2C1, (dev_addr << 1), I2C_Direction_Receiver); // Send slave address for read

 

View original
8 replies
Resolved