After implementing the MLX90614 driver for NuttX I noticed that although the write command to change the device I2C address in the EEPROM was reporting success, after the power cycle the new address was not working. Worst: even the previous address was not working.

Basically the device appears damaged and didn’t respond to any I2C command.

Then doing my research I discovered a Melexis document about SMBus communication:

I am creating a NuttX device driver for Melexis MLX90614 and it is a nice adventure.

First I downloaded the adafruit lib and tested it on Arduino Uno just to confirm the sensor was working, but I didn’t look the source code because I always prefer to read the datasheet and implement the driver from scratch.

All things fine, the mlxtest example worked correctly and I got the ambient temperature and the object temperature printed correctly.

Then I created the driver and decided to test it on STM32F103, but discovered that I2C_TRANSFER() for STM32F103 is broken. No problem, let to test it on STM32F4Discovery board:

“I haven’t checked your CRC implementation but there is a mistake in the MLX datasheet or at least it’s badly written. You have to include all the I2C frame’s data for the PEC’s calculation not just the replied data. For a read word command you have to include [SA_W, Command, SA_R, LSB, MSB] and for a write word command [SA_W, Command, LSB, MSB]. So, for their first example the calculation must be made on [ 0xB4, 0x07, 0xB5, 0xD2, 0x3A ] and not just on [ 0xD2, 0x3A ] and this way you get the expected 0x30.”

What this guy is saying is: we need to include all the bits of the Slave Address, the address needs to be seen as 8-bit including the the less significant bit Write or Read. So I2C Write at address 0x5A is seen as 0xB4 and I2C Read is seen as 0xB5 (pay attention at bits over the “5A” in the logic analyzer image above).

nsh> ls -l /mnt
/mnt:
-rw-rw-rw- 48 test.txt
nsh>
nsh> cat /mnt/test.txt
This is a small test!
Just to prove the idea!!!

Now I decided to send a bigger file (4KiB) :

I used the COPYING file of NuttX, just cutting it to 4KiB:

$ sudo dd if=COPYING of=/COPYING bs=1 count=4096

Then on minicom:

nsh> dd if=/dev/console of=/mnt/COPYING bs=64 count=64
Ctrl + A - Y

After selecting the file I noticed that the TXD LED on USB/Serial adapter was blinking at each 1 second. So after about 64 seconds it transfered the 4KiB file.

nsh> ls -l /mnt
/mnt:
-rw-rw-rw- 48 test.txt
-rw-rw-rw- 4096 COPYING
nsh> cat /mnt/COPYING
COPYING -- Describes the terms under which Nuttx is distributed. A
copy of the BSD-style licensing is included in this file. In my
words -- I believe that you should free to use NuttX in any
environment, private, private, commercial, open, closed, etc.
provided only that you repect the modest copyright notices as
...
uIP
^^^
Many lower-level networking components of NuttX derive from uIP which
has a similar BSD style

That is it! It is not the faster transfer solution but it proved to work.
I think this same approach should have worked on Linux at that time.