eclipse / mraa

Linux Library for low speed IO Communication in C with bindings for C++, Python, Node.js & Java. Supports generic io platforms, as well as Intel Edison, Intel Joule, Raspberry Pi and many more.
http://mraa.io
MIT License
1.37k stars 614 forks source link

Galileo Gen2 and AIO: pull-up resistor bug #390

Closed xbolshe closed 8 years ago

xbolshe commented 8 years ago

Let's see https://github.com/intel-iot-devkit/mraa/blob/master/src/x86/intel_galileo_rev_g.c

// ANALOG strncpy(b->pins[14].name, "A0", 8); b->pins[14].aio.pinmap = 0; b->pins[14].aio.mux_total = 1; b->pins[14].aio.mux[0].pin = 49; b->pins[14].aio.mux[0].value = 1;

strncpy(b->pins[15].name, "A1", 8);
b->pins[15].aio.pinmap = 1;
b->pins[15].aio.mux[0].pin = 51;
b->pins[15].aio.mux[0].value = 1;
b->pins[15].aio.mux_total = 0;

strncpy(b->pins[16].name, "A2", 8);
b->pins[16].aio.pinmap = 2;
b->pins[16].aio.mux_total = 1;
b->pins[16].aio.mux[0].pin = 53;
b->pins[16].aio.mux[0].value = 1;

strncpy(b->pins[17].name, "A3", 8);
b->pins[17].aio.mux_total = 1;
b->pins[17].aio.mux[0].pin = 55;
b->pins[17].aio.mux[0].value = 1;

I'm not sure about bugs, but have questions:

  1. Why only A1 has mux_total = 0, while A0,A2,A3 have mux_total = 1 ?
  2. Why MUX 49,51,53 and 55 values are equal 1 while for a normal ADC operation need to disable pull-up/pull-down resistors using a direction value "INPUT" ?

BR, xbolshe

arfoll commented 8 years ago
  1. Very odd @tingleby any ideas? Our QA test this combination fairly well so I'm surprised if we have an issue there but maybe, at least there should be a comment to explain this oddity
  2. I'm confused as to what you mean exactly there :/
xbolshe commented 8 years ago

2.Look at https://communities.intel.com/thread/94135 It seems MRAA does not control pull-up resistors while using ADC convertor. And there is a voltage on an analog pin, when there is no external connection.

Here is a related part of Gen2 circuit diagram:

pullup-resistors

xbolshe commented 8 years ago

And simplified picture:

simpic

xbolshe commented 8 years ago

And PIN configuration:

pullup-config

xbolshe commented 8 years ago

Now have: Direction = Output Value = 1 (VCC voltage to resistor)

Shall be: Direction = Input Value = Any

And code with bug:

mraa_result_t mraa_setup_mux_mapped(mraa_pin_t meta) { int mi;

for (mi = 0; mi < meta.mux_total; mi++) {
    mraa_gpio_context mux_i;
    mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
    if (mux_i == NULL) {
        return MRAA_ERROR_INVALID_HANDLE;
    }
    // this function will sometimes fail, however this is not critical as
    // long as the write succeeds - Test case galileo gen2 pin2
    mraa_gpio_dir(mux_i, MRAA_GPIO_OUT);
    mraa_gpio_owner(mux_i, 0);

    if (mraa_gpio_write(mux_i, meta.mux[mi].value) != MRAA_SUCCESS) {
        mraa_gpio_close(mux_i);
        return MRAA_ERROR_INVALID_RESOURCE;
    }
    mraa_gpio_close(mux_i);
}

return MRAA_SUCCESS;

}

xbolshe commented 8 years ago

Seems need to add pull-up resistor control for ADC conversion in MRAA API.

alext-mkrs commented 8 years ago

Just to make sure (because as @arfoll mentioned this part of the functionality should be quite well-tested) - what exactly is the problem here from the user standpoint, sort of "so what if we don't control these"?

xbolshe commented 8 years ago

Problem: ADC performs a measurement of unexpected signal (when an additional resistor is connected to the GND or VCC, or an analog pin is connected to the GND or VCC via digital outputs of A0,A1,A2,...). An unexpected signal may be changed from time to time and randomly.

joemcmanus commented 8 years ago

My perspective of the problem as a user of the Galileo Gen 2 is that the A0 can not be used to read input of sensors.

As an example I have an TMP36 wired to A0 and another wired to A1. Reading the values using python and MRAA I get different readings.

I use this program here: https://github.com/joemcmanus/analog/blob/master/analog.py

TMP36 on A0:

| Raw MRAA Reading | 1384 | | MRAA Voltage Calc | 1.6899 |

TMP on A1: | Raw MRAA Reading | 584 | | MRAA Voltage Calc | 0.7131 |

The voltage on A0 is just wrong...

Cheers, -Joe

xbolshe commented 8 years ago

In the problem case of @joemcmanus the following PIN configuration is applied while reading A0:

GPIOs 48-63, i2c/0-0027, pcal9555a, can sleep: gpio-48 (sysfs ) in hi gpio-49 (sysfs ) out hi gpio-50 (sysfs ) in lo gpio-51 (sysfs ) in lo

gpio-49 enables a pull-up resistor to VCC.

And A1 works correctly because of A1.mux_total = 0

arfoll commented 8 years ago

It's weird because I've tried with the muxes, using mux_total=1, clean reboots and after initialising i2c (which will flip the muxes), and A0 & A1 are fairly stable. A1 is usually a little on the low side but I can't see anything much different to usual. I'm happy to take the change to set mux_total=1 since that seems to be what "should" be done and doesn't seem to harm anything but it doesn't imho fix any issues of galileo gen2 ADC being a little 'dodgy'. in testing (admitedly ages ago) we tried mraa against arduino on gen2 (totally different implementations) and found ADC results matched.

joemcmanus commented 8 years ago

My testing is on the Intel Galileo Gen 2 using the IoTDevKit image iot-devkit-201510010757-mmcblkp0-galileo.direct . I have tested this on two different Galileo Gen 2's reading using MRAA and reading from the file system /sys/bus/iio/devices/iio:device0/in_voltage0_raw .

Full thread on the intel community https://communities.intel.com/thread/94135 .

xbolshe commented 8 years ago

@arfoll I have checked circuit diagrams and found that:

I may expect that after booting many boards have a stable and repeatable state of GPIOs. That is why in many situations there is no problem. But if in some cases GPIOs are changes before operations (because of new firmware, some programs, etc.), MRAA processing is unexpected. And need to perform a full initialisation of GPIOs before operations.

So, a current MRAA version does not perform a full initialisation of GPIOs as needed for Galileo Gen2 board.

Why does intel_edison_fab_c.c have pullup_map[] in mraa_intel_edison_aio_init_pre as well as mraa_gpio_dir(pullup_pin, MRAA_GPIO_IN) while Gen2 has not ?

Just need to repeat the idea in intel_edison_fab_c.c regarding pullup_map[] for Gen2.

xbolshe commented 8 years ago

Also there is a problem with:

A4:

b->pins[18].aio.mux_total = 3;
b->pins[18].aio.mux[0].pin = 60;
b->pins[18].aio.mux[0].value = 1;
b->pins[18].aio.mux[1].pin = 78;
b->pins[18].aio.mux[1].value = 0;
b->pins[18].aio.mux[2].pin = 57;
b->pins[18].aio.mux[2].value = 0;

A5:

b->pins[19].aio.mux_total = 3;
b->pins[19].aio.mux[0].pin = 60;
b->pins[19].aio.mux[0].value = 1;
b->pins[19].aio.mux[1].pin = 79;
b->pins[19].aio.mux[1].value = 0;
b->pins[19].aio.mux[2].pin = 59;
b->pins[19].aio.mux[2].value = 1;

Why is a different value used for pin 59 and 57 ?

BR, xbolshe

xbolshe commented 8 years ago

It is possible that enabled and uncontrolled pull-up/pull-down resistors block I2C bus on A4/A5. That causes that there is a problem with GPIO control of many pins.

xbolshe commented 8 years ago

Some pictures how to reproduce an I2C time-out issue with an external wire: Same situation is present with internal pull-up/down resistors.

a5to33v

a5www

xbolshe commented 8 years ago

Here is my proposal to fix: https://github.com/intel-iot-devkit/mraa/pull/459

BR, xbolshe

alext-mkrs commented 8 years ago

The fix was commited with 3397c95c0a15fa42d15ed0b7a4b04ff0f6d17276 and 95c259f6b2420f04078ea83ec5c9a9a9e52f3a77, closing this one.