Setting GPIO for one-wire communication (IMX6ULL)

Grettings.
I’m having troubles trying to set my IMX6ULL to working with one-wire protocol; using same pin to send and receive signals.
Particularly i want to control temperature sensor DS18S20, but i cant get it to do the “initialization procedure”, which consists in sending a pulse to the sensor and then receive the “acknowledge” signal from it.

I’m using colibri IMX6ULL WB 512 (core image minimal 5.7.2-devel-20230726155409+build) with a custom board, where i set pin SODIMM 137 to the sensor:

&pinctrl_gpio2 {
	fsl,pins = <
		MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02	0x1d0b0	/* SODIMM 137 */
	>;
};


In initialization procedure i send the module a low signal for 480us and then i change the pin setting to “in”, and that’s where i can’t get the presence pulse from the sensor.
I sensed the pin with an oscilloscope and definetly the sensor works fine, therefore i’m able to see the low signal, but in my C program the logic level never changes.

This low signal lasts for about 50 us, but once i set the pin config to “in” im not able to detect any change.

Maybe it has something to do with the pin config itself, i’ve tried with pull-up/down config, CMOS /Schmitt Trigger in, but nothing changes (sensor datasheet says that sensor output is an opendrain with a pullup resistor). I also tried to set other pin to just “in” config and connected to the sensor to see if that was the problem but once again it didn’t work.

I would like some advices in what i should look at here, thank you!

Please check regarding SNVS pad you are using. Pinctrl groups can either contain SNVS or non-SNVS pads, but not the mix of SNVS and non-SNVS pads. SNVS pinctrl group can belong only to iomuxc_snvs, and not to iomuxc.
If using two pads connected together, then configure output one as open drain, so that you don’t need to change IO direction.

Hi Edward thanks for answering.

I’ve tried to set the pin like you mentioned:

&pinctrl_snvs_usbc_det{
		fsl,pins = <
		MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02	0xf8b0	/* SODIMM 137 */
			
		>;
	};

Read pin :

&pinctrl_snvs_gpio1 {
	/delete-property/ fsl,pins;
	fsl,pins = < 
		MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05	0x110b0 /* SODIMM 131 */
	>;
};

And the pin works fine it’s just i can’t get to detect that pulse. (By the way i tried all the combinations between open drain/cmos and schimitt trigger.

Used this simple script
#!/bin/sh
echo 130 > /sys/class/gpio/export
echo 133 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio130/direction
echo "in"> /sys/class/gpio/gpio133/direction
echo 1 > /sys/class/gpio/gpio130/value
sleep 0.1
echo 0 > /sys/class/gpio/gpio130/value
sleep 0.00048
echo 130 > /sys/class/gpio/unexport
sleep 0.000005
cat /sys/class/gpio/gpio133/value
sleep 0.000035
cat /sys/class/gpio/gpio133/value
sleep 0.00034

But i can’t see that change of state i’m seeing in my oscilloscope.. Maybe it’s hardware related?

To capture that pulse, you need to use a GPIO interrupt. Please check the following threads:

In Linux, especially on 6ULL, everything shorter than 10ms is hard real time. Shorter than 2ms is extreme real time. Are you kidding catching 50us pulse in bash script? I didn’t time sleep 0 call, but I guess it is longer than 50us when lucky to hit I-cache.
Perhaps you could solve it with C and libgpiod, but even for C it is challenging and not guaranteed due to Linux nature. Use external MCU or perhaps upgrade to iMX7 with real time M4 code on the same chip.

Hi @germanmorgan ,

Were you able to solve this issue?

Please let me know if you have any doubts.

Best regards,
Daniel Morais

Hi Daniel, thank you all for your replies. Im trying @Edward solution right now, altough i’m seeing it’s gonna be difficult.

I didn’t have the “libgpiod” library installed on my Linux sv so i’m trying to install it, but i’m getting this error:

$ ./autogen.sh --enable-tools=yes --host=arm-angstrom-linux-gnueabi --prefix=/home/yocto-project/GSM_C/libgpiod_german
autoreconf: Entering directory `.’
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, ‘autostuff’.
libtoolize: copying file ‘autostuff/ltmain.sh’
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, ‘m4’.
libtoolize: copying file ‘m4/libtool.m4’
libtoolize: copying file ‘m4/ltoptions.m4’
libtoolize: copying file ‘m4/ltsugar.m4’
libtoolize: copying file ‘m4/ltversion.m4’
libtoolize: copying file ‘m4/lt~obsolete.m4’
autoreconf: running: /usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/autoconf --force
configure.ac:170: error: Unexpanded AX_ macro found. Please install GNU autoconf-archive.
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
autoreconf: /usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/autoconf failed with exit status: 1

Maybe if i try using"poll.h" library i will get some results? I’m kinda out of solutions, and we can’t change hardware at this stage

Hi @germanmorgan ,

Have you ever built an image using this documentation? The libgpiod is available on Yocto as a package by default on the BSP 5 layers, you can find it below:

layers/meta-openembedded/meta-oe/recipes-support/libgpiod/libgpiod_1.4.3.bb

The easiest way to install this package into your image is by adding the following line to the conf/local.conf file and building the entire image:

IMAGE_INSTALL_append += " libgpiod"

Please let me know if you have any other doubts.

Best regards,
Daniel Morais

Daniel, i managed to run libgpiod by flashing the image every time i wanted to make some change to my C program. Anyways, i wasn’t able to detect any change of edge.

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: gpio-event <CHIP-NAME> <OFFSET>\n");
        return EXIT_FAILURE;
    }

    const char *chip_name = argv[1];
    int offset = atoi(argv[2]);

    struct gpiod_line *line = get_gpio_line(chip_name, offset);
    if (!line) {
        return EXIT_FAILURE;
    }

    set_line_mode(line, GPIOD_LINE_ACTIVE_STATE_HIGH);

    struct timespec start_time;
    clock_gettime(CLOCK_MONOTONIC, &start_time);

    // Espera 500 ms
    usleep(RETARDO_MS);

    gpiod_line_set_value(line, 0);
    wait_microseconds(RETARDO_US);

    gpiod_line_release(line);
    line = get_gpio_line(chip_name, offset);
    if (!line) {
        return EXIT_FAILURE;
    }

    if (gpiod_line_request_both_edges_events(line, "gpio-event") < 0) {
        perror("Error al configurar la línea GPIO");
        gpiod_line_release(line);
        return EXIT_FAILURE;
    }

    struct gpiod_line_event event;
    struct timespec end_time;
    while (1) {
        gpiod_line_event_wait(line, NULL);

        if (gpiod_line_event_read(line, &event) == 0) {
            clock_gettime(CLOCK_MONOTONIC, &end_time);
            long elapsed_time_ns = (end_time.tv_sec - start_time.tv_sec) * 1000000000 + (end_time.tv_nsec - start_time.tv_nsec);

            if (event.event_type == GPIOD_LINE_EVENT_RISING_EDGE) {
                printf("Flanco de subida detectado. Tiempo transcurrido: %ld ns.\n", elapsed_time_ns);
            } else if (event.event_type == GPIOD_LINE_EVENT_FALLING_EDGE) {
                printf("Flanco de bajada detectado. Tiempo transcurrido: %ld ns.\n", elapsed_time_ns);
            }
        }
    }

    gpiod_line_release(line);
    return EXIT_SUCCESS;
}

Maybe the only way to get this running would be to writing a specific C driver for the sensor?

Hi @germanmorgan ,

As mentioned by @Edward , obtaining accurate timings for these sensors can be challenging on the userspace side. With that in mind, I believe that libgpiod may not provide the necessary support to achieve your desired result.

Considering this, the most straightforward alternative would likely involve using a kernel driver. You can find the w1_therm.c driver, which appears to support the sensor you’re working with. Additionally, you can access relevant documentation here. I recommend implementing this driver and assessing whether it meets your requirements.

If you have any further questions, please don’t hesitate to reach out.

Best regards,
Daniel Morais