cancel
Showing results for 
Search instead for 
Did you mean: 

Connection i2c between Stm32LO72CZY6TR (B-LO72Z-LRWAN1)

mibou23
Associate II

Hi guys,

I'm trying to connect a bosch sensor BNO055 (adafruit) by I2C to my Stm32L072CZ6YTR. I'm new with the environnement of STM32 so i try to program the ship with basic tutorial about STM32 I2C connection. I have write the functions who permit to read and write on the i2C bus but i have no respond of my ship when the program call this functions.

For helping you, to understant where is my problem, i copy the code that i have write to initialize the sensor ( i just follow the structure include in the Bosch Sensortech Datasheet).

The problem come from the fonction write and read because my BNO055 is properly connected to my STM32. If someone have experience with BNO055 please help me to resolve my problem.

The function for that I used to read or write are here :

0690X000008iOLRQA2.png0690X000008iOP4QAM.png

The code that i use to test the i2c connection ( I simply try to read register with constant value):

0690X000008iOPJQA2.png

0690X000008iOPOQA2.png

If someone on this forum can explain to me where is my error, that can be very useful for me. Thank you.

9 REPLIES 9

Pretty sure the reg_data isn't 10 bytes wide.

Talking to an OLED attached to the Murata module using the Mem functions.

HAL_I2C_Mem_Read(&I2CHandle, Addr, Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 1000);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mibou23
Associate II

OK, thanks for your answer. I think that i have no connection between my sensor and my STM32...

I receive no acknowledge of the sensor and my process of initialisation always end with an HAL_ERROR. I juste initialise I2C1 in standard mode with CubeMX and put the clock to the good frequency for the sensor.

Have you and idea of the error of initialisation of my code with CubeMx i do that prevent the connection between the sensor and the STM32 ?

I don't use CubeMX. Paste the MSP initialization code as a code-block (see </> icon), not as a screen shot.

Using I2C1 PB9/PB9 as SCl/SDA here.

The address should be 0x50 (0x28 << 1) for the BOSCH part.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mibou23
Associate II

The initialization was ok. The error came from the adress of the peripherique. I directly used the "#define BNO055_I2C_ADDR1 " who was write on the Bosch Datasheet.

I'm really grathefull for your help. The communication seems working now.

Can you explain me why we can't use the define give by the manufacturer and we need to shift to obtain the good adress ?

Because the slave address is 7 bit while most people see I2C physical bit transaction to be 8+1 (8 bits one direction, 1 on the other).

EEPROM typically would be address 0x50 but in practice, most people say 0xA0/A1 (write and read included).

I integrated BMX055 cousin's chip to my sensor board. it has 3 I2C slave addresses. By making a I2C adress radar sweep at boot time, a sanity check is done, works for new boards too.

I use GPIO I2C for it's pinout flexibility and here is my code extract from Bosch baseline:

 /*	\Brief: The function is used as I2C bus write
 *	\Return : Status of the I2C write
 *	\param dev_addr : The device address of the sensor
 *	\param reg_addr : Address of the first register,
 *              will data is going to be written
 *	\param reg_data : It is a value hold in the array,
 *		will be used for write the value into the register
 *	\param cnt : The no of byte of data to be write
 */
s8 BMM050_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
{
	s32 iError = BMM050_INIT_VALUE;
	u8 array[I2C_BUFFER_LEN];
	u8 stringpos = BMM050_INIT_VALUE;
 
	array[BMM050_INIT_VALUE] = reg_addr;
//	for (stringpos = BMM050_INIT_VALUE; stringpos < cnt; stringpos++)
//		array[stringpos + C_BMM050_ONE_U8X] = *(reg_data + stringpos);
        
        
        //gSTModBMM050.SubAdrByteCount = 1;
        gSTModBMM050.SubAdrBytes[0] = reg_addr; 
 
        gSTModBMM050.pReadByte = 0;
        gSTModBMM050.ReadByteCount = 0;
  
        gSTModBMM050.pWriteByte = reg_data;
        gSTModBMM050.WriteByteCount = cnt;
          
        I2C_MasterIO_AccessDevice(&gSTModBMM050);
        
	/*
	* Please take the below function as your reference for
	* write the data using I2C communication
	* "IERROR = I2C_WRITE_STRING(DEV_ADDR, ARRAY, CNT+C_BMM050_ONE_U8X)"
	* add your I2C write function here
	* iError is an return value of I2C read function
	* Please select your valid return value
	* In the driver SUCCESS defined as BMM050_INIT_VALUE
    * and FAILURE defined as -C_BMM050_ONE_U8X
	* Note :
	* This is a full duplex operation,
	* The first read data is discarded, for that extra write operation
	* have to be initiated. For that cnt+C_BMM050_ONE_U8X operation done
	* in the I2C write string function
	* For more information please refer data sheet SPI communication:
	*/
	return (s8)iError;
}
 
 /*	\Brief: The function is used as I2C bus read
 *	\Return : Status of the I2C read
 *	\param dev_addr : The device address of the sensor
 *	\param reg_addr : Address of the first register,
 *            will data is going to be read
 *	\param reg_data : This data read from the sensor,
 *            which is hold in an array
 *	\param cnt : The no of byte of data to be read
 */
s8 BMM050_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
{
	s32 iError = BMM050_INIT_VALUE;
	u8 array[I2C_BUFFER_LEN] = {BMM050_INIT_VALUE};
	u8 stringpos = BMM050_INIT_VALUE;
 
	array[BMM050_INIT_VALUE] = reg_addr;
	/* Please take the below function as your reference
	 * for read the data using I2C communication
	 * add your I2C rad function here.
	 * "IERROR = I2C_WRITE_READ_STRING(
	 *  DEV_ADDR, ARRAY, ARRAY, C_BMM050_ONE_U8X, CNT)"
	 * iError is an return value of SPI write function
	 * Please select your valid return value
	 * In the driver SUCCESS defined as BMM050_INIT_VALUE
     * and FAILURE defined as -C_BMM050_ONE_U8X
	 */
//	for (stringpos = BMM050_INIT_VALUE; stringpos < cnt; stringpos++)
//		*(reg_data + stringpos) = array[stringpos];
 
        //gSTModBMM050.SubAdrByteCount = 1;
        gSTModBMM050.SubAdrBytes[0] = reg_addr; 
 
        gSTModBMM050.pWriteByte = 0;
        gSTModBMM050.WriteByteCount = 0;
  
        gSTModBMM050.pReadByte = reg_data;
        gSTModBMM050.ReadByteCount = cnt;
          
        I2C_MasterIO_AccessDevice(&gSTModBMM050);
	return (s8)iError;
}

Simplified my file by creating only 1 function to deals with any I2C slave device type of protocol, except Sensirion devices which unfortunately requires clock stretching with I don't implement.

it is a 7-bit address, it is left (high order) aligned on the bus, the low order bit indicating read/write. The ST HW doesn't shift, so you need to be detail orientated, different micro-controllers implement this in a number of ways, all valid, and documented.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

One I2C example which should be provided for all is the sweep of all I2C slave addresses. Would be handy for most developpers and avoid each one of them code it over and over.

I've certainly built bus probing code in the past. One of the functions of the ACK is to know if you have a functional peripheral on the bus. The original Philips concept was to allow for modular systems where features/functions could be added. In a TV things like a remote control, digital tuner or teletext, or on a CD player controlling volume or CODEC setting.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AVI-crak
Senior

The BNO055 has its own Cortex-M0 processor. All read / write operations pass through it, hardware decryption of the address of the crystal is supported - everything else is programmed. As a result, the response / ready signal may have a delay. At this point, the BNO055 keeps the data line or CK at zero.

Without exception, gyroscopes and composite sensors have dead time when they make measurements. At this point, the sensor may not respond, or strongly delay the response.

In addition, BNO055 can perform small programs from its flash memory, the start is performed by an external command. From the factory, BNO055 comes with a publicly available firmware version. If nothing works for you, then you have managed to change it.

And yes, the BNO055 is a complex and expensive sensor to study, first you need to practice on cats.