07-26-2019 07:51 PM - edited 07-26-2019 07:56 PM
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).
Solved! Go to Solution.
08-01-2019 10:46 AM - edited 08-01-2019 10:48 AM
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
08-01-2019 10:48 AM
08-01-2019 05:46 PM
Thanks guys, I already found where problem was. It is slave address as you wrote. Yesterday, after posting screenshot from LA, I tried to set gas_sensor.dev_id = 0xEC and I recieved ack from BME. And now I see your answers for the same thing. In my code I am using STM32F10x_StdPeriph_Lib_V3.5.0, and in library I2C_Send7bitAddress realized in such way:
/**
* @brief Transmits the address byte to select the slave device.
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
* @param Address: specifies the slave address which will be transmitted
* @param I2C_Direction: specifies whether the I2C device will be a
* Transmitter or a Receiver. This parameter can be one of the following values
* @arg I2C_Direction_Transmitter: Transmitter mode
* @arg I2C_Direction_Receiver: Receiver mode
* @retval None.
*/
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_DIRECTION(I2C_Direction));
/* Test on the direction to set/reset the read/write bit */
if (I2C_Direction != I2C_Direction_Transmitter)
{
/* Set the address bit0 for read */
Address |= OAR1_ADD0_Set; // Address |= 0x0001
}
else
{
/* Reset the address bit0 for write */
Address &= OAR1_ADD0_Reset; // Address &= 0xFFFE
}
/* Send the address */
I2Cx->DR = Address;
}
Now I am put in this function 0xEC address for writing to and 0xED for reading from BME.
02-23-2021 01:29 PM - edited 02-23-2021 01:30 PM
Hello Guy's,
I am using STM32f103C8T6 module as a arduino framework but I am unble to complile the below mentioned BMSC library in Platform IO.