Maxim 1-wire libraries I2C breaks on STM32 moving from mbed-os v5.x to v6.x

I’m not sure where the right place to put this is, since the MaximInterface library doesn’t have an issue tracker here or on on Gitlab where it’s hosted. I’m looking for any guidance I can get.

Maxim has two libraries for its 1-wire ecosystem, the legacy OneWire library and MaximInterface which superseded it. Both contain abstractions which wrap their I2C masters to make communication with the 1-wire bus attached to the master transparent to the client code. Both libraries appear to be fairly straightforward users of Mbed’s I2C APIs, and both exhibit the following behavior where they behave as expected in mbed-os 5.14 and don’t in all of the 6.x versions.

I have a Nucleo F446RE attached to a DS2482-800 on IC23 (I have tried with IC21 as well). All eight 1-wire channels of the DS2482-800 have 1-wire devices attached to their bus. The rest of the environment is as follows:

Parameter Value
Board Nucleo F446RE
Dev Environment Manjaro Linux
Compiler GNU Arm Embedded Toolchain 9-2020-q2-update 9.3.1 20200408
Build Tools mbed-cli and cmake
Mbed OS Version works on 5.15.4, fails on 6.0.0, 6.1.0, 6.2.0

The MaximInterface library works as-is when I tested it on 5.15.4, and will detect the 1-wire devices on their respective busses.

However, it won’t immediately compile on mbed-os 6+ because of its use of Serial and wait_ms. By simply removing the Uart masters and replacing the depricated waits with thread_sleep_for the library will compile in both 5.15.4 and all of the 6.x versions of mbed-os.

MaximInterface with the API fixes works in 5.15.4 the same as the unmodified version. However, when running in 6.0.0, 6.1.0, and 6.2.0 the bus reset fails with a “Nack Error”.

This is the basic test program for mbed-os 6.x based on the MaximInterface example with the additional channel selection for the DS2482-800. It’s slightly different than the 5.15 version because of BufferedSerial.

#define SERIAL_SPEED 115200

#include "mbed.h"
#include <MaximInterfaceCore/HexString.hpp>
#include <MaximInterfaceCore/RomCommands.hpp>
#include <MaximInterfaceDevices/DS2482_DS2484.hpp>
#include <MaximInterfaceMbed/I2CMaster.hpp>

BufferedSerial serial(USBTX, USBRX);

I2C i2c_bus(PB_4, PA_8);
MaximInterfaceMbed::I2CMaster i2c_wrapper(i2c_bus);
MaximInterfaceDevices::DS2482_800 one_wire_master(i2c_wrapper, 0x30);

FileHandle *mbed::mbed_override_console(int fd) {
    return &serial;
}

void DetectChannel(int channel) {
    auto result = one_wire_master.initialize();
    if (!result) {
        printf("Failed to initialize DS2482-800: %s\r\n", result.error().message().c_str());
        return;
    }

    result = one_wire_master.selectChannel(channel);
    if (!result) {
        printf("Failed to select channel %i: %s\r\n", channel, result.error().message().c_str());
        return;
    }

    MaximInterfaceCore::SearchRomState search_state;
    do {
        result = MaximInterfaceCore::searchRom(one_wire_master, search_state);
        if (!result) {
            printf("Failed to find device: %s\r\n", result.error().message().c_str());
            return;
        }

        printf("Ch %i Found ROM ID: %s\r\n", channel, MaximInterfaceCore::toHexString(search_state.romId).c_str());
    } while (!search_state.lastDevice);
}

int main() {
    serial.set_baud(SERIAL_SPEED);
    printf("\r\n\r\nStarting 1-Wire Search Program\r\n");

    uint tick_count = 0;
    while (true)
    {
        printf(" > tick! %u\r\n", tick_count++);

        for (int i = 0; i < 8; ++i) {
            DetectChannel(i);
        }

        ThisThread::sleep_for(1000);
    }
}

Some basic printf debugging suggests that in mbed-os v6.x the failure occurs during the 1-wire bus reset, specifically in a function called pollBusy where what seems to be a single byte read from the I2C bus sits in a polling loop. The second read attempt always fails, and the return value indicates a NACK error.

MaximInterface/MaximInterfaceDevices/DS2482_DS2484.cpp

Result<uint_least8_t> DS2482_DS2484::readRegister() const {
  uint_least8_t buf;
  TRY(master->readPacket(address_, make_span(&buf, 1), I2CMaster::Stop));
  return buf;
}

Result<uint_least8_t> DS2482_DS2484::pollBusy() {
  const int pollLimit = 200;

  int pollCount = 0;
  uint_least8_t status;
  do {

    TRY_VALUE(status, readRegister());  // Error seems to happen here on the second loop

    if (pollCount++ >= pollLimit) {
      return HardwareError;
    }
  } while ((status & status_1WB) == status_1WB);

  return status;
}

Interestingly, the legacy OneWire library also seems to fail in the second single byte read in a polling loop as part of the 1-wire bus reset. Both libraries seem to be fairly simple users of the Mbed I2C object, so I’m at a loss for what might have changed between mbed-os 5.15 and 6.x.

Any insight, guidance, or general help is appreciated. I’m not quite sure what to do or try next.

I think I’m encountering a similar issue. I’m trying to use the legacy OneWire library as part of DS1820 - Dallas' DS1820 family temperature sensor. For mor… | Mbed

And It just seems to give up after sending the ‘search ROM’ command:

Before and after this point there is no activity on the OneWire pin.

I’m using the mbed online compiler with a nucleo F303RE. Not sure how to check my exact mbedos version but it’s from the last 2 months so I assume it’s 6.x.

edit: I’m not accessing through I2C, but the issues seem similar

@kuutei, I think it would be best if you moved your conversation to a different thread. It’s unrelated to the problem for which this thread was opened, which refers to the two official Maxim libraries and specific issues they seem to be having with the I2C driver, not Zoltan’s library.

As of now the original question remains unsolved and unanswered.

As an aside, I can tell you that I have Zoltan’s library working with a DS18B20 as well as a DS2413 on a Nucleo STM32F446RE using mbed-os 6.2 in the environment and toolchain I described in my first post above.

@mattjarvisast I agree, sorry for hijacking your thread.

I’ve posted a new thread at DS1820 / OneWire library doesn't work on mbedos5, mbedos6 (NUCLEO-F303RE)

Thanks for sharing your working configuration.

edit: Problem ultimately solved by using a 20kOhm pullup instead, or using many (>=5) DS18B20 on the same bus.

1 Like