While testing the BNO086 with the Arduino Giga I noticed that setting the I2C clock at 400khz would cause the BNO086 to not sent any of reports. Tested with a couple of examples.
However if I try any other clock > 100khz or <400khz (specifically I tried 200khz and 350Khz) I get the "red blinking LED of doom". So my guess is that nothing but 100 and 400khz is supported by the giga.
Can someone confirm this - will probably make this a github issue as well.
It seems a software/timing issue, but I still wan to be sure that your I2C wires are okay.
The Qwiic connector is wrong, and if also the wires are wrong, then the official I2C standard gives you 10 cm for the total length of the I2C bus.
Page 54, paragraph 7.5 of the official I2C standard: https://www.nxp.com/docs/en/user-guide/UM10204.pdf
Sorry for taking long to answer - was off doing chores Anyway here is a series a pictures so you can see the connections and wires the red light after loading at 350khz:
This is very similar to how the UNO R4 I2C is setup - intermediate frequencies are not supported only standard, fast and fast_plus which I don't know is supported for the H7.
Can you try the 'I2C_SPEED_FREQ_FAST' as parameter. Can you make an Issue on Github ?
Maybe the BNO086 has troubles with the 400kHz, but it should work with any clock frequency between 100 and 400kHz. I think you don't have to check with other Arduino boards.
A Logic Analyzer can measure the clock and a USB Logic Analyzer can analyze and decode the signals on your computer.
A Raspberry Pi Pico can be turned into a Logic Analyzer, but I have not tried that.
I'm very fond of the LHT00SU1 in combination with sigrok/PulseView. It costs 25 euros. The 5 dollar 24MHz 8 channel Logic Analyzers do work, but the usb connector easily breaks.
Its a bit different. With the R4 it would only accept standard or fast. In this case it does accept the frequency as I will show in a bit.
As I said in post #1, the BNO086 does indeed have a problem at 400Khz that is why they recommend setting the I2C clock at 350khz. Unfortunately the Mbedos does not calculate frequencies dynamically, it only support 100Khz (standard) and 400khz (fast).
Using a Salae8, here are the traces at 100Khz and 400Khz
As far as I can see from what I saw in MBedos all three buses use the same logic, i.e., you can only use Standard(100K) or Fast(400K).
Yeah setting the I2C clock is not easy and doubt Mbed will change their logic the way they do it since they are supporting so may different processors.
Thought about it but didnt see a way of setting it without compiling the whole core again - not as easy as it was with the R4. Probably should try something like the mpu9250 at 400K but I already know it will work since that is that will work at higher clocks.
Did a bunch more tracing and testing and I just posted this in the issue I created on github. Seems it should be able to calculate intermediate frequencies:
Doing a trace found the following:
In mbed_config.h calculating the I2C timing from the requested frequency is enabled: #define MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO 1
Tracing that it appears in ArduinoCore-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h
in i2c_device.c for the H7 (targets/TARGET_STM/TARGET_STM32H7/i2c_device.c in the mbedos repo you can see the calculation
so technically it should be calculating the setting for frequency at 350khz.
i2c_device.h is referenced in ArduinoCore-mbed/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h
Not sure if this is associated with this issue on the portenta:
Additional info I did attach a jlink for debugging and all that can confirm is that the red lights of doom happen when setClock(350000) is called which happens in Wire.cpp: master->frequency(freq);
/* Only predefined timing for below frequencies are supported */
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
/* Derives I2C timing value with respect to I2C input clock source speed
and I2C bus frequency requested. "Init.Timing" is passed to this function to
reduce multiple computation of timing value which there by reduces CPU load.
*/
handle->Init.Timing = i2c_get_timing(obj_s->i2c, handle->Init.Timing, \
obj_s->current_hz, hz);
/* Only non-zero timing value is supported */
MBED_ASSERT(handle->Init.Timing != 0);
/* hz value is stored for computing timing value next time */
obj_s->current_hz = hz;
#endif // I2C_IP_VERSION_V2
Wonder if they ran into some issue, or simply did not want to take the time to make it work...
EDIT: - Personally I believe that putting asserts into the code, that is distributed in a precompiled static library, with debug information removed, which the only debug information you can get is the red blinking led... Is maybe not the best approach!
I agree wholeheartedly. No clue what the error really was until I dug into the code. Had a gut feeling but.... In addition debugger is rather useless with the static library as we both found out.