This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Help: we met a problem about GPIO drive.

Other Parts Discussed in Thread: AM1810, DA8XX, OMAPL138

Hi Professionals! We met a problem and hope you can help with analysis.

Question :
-1) I set AM1810 GP3[0] as GPIO port which played a role of "input".
In the code file "/linux-2.6.33-rt29-psp03.30.00.02/arch/arm/mach-davinci/da850.c", we modified as follows:
MUX_CFG(DA850, EMA_D_8, 8, 28, 15, 8, false)

const short da850_evm_user_dp_pins[] __initdata = {DA850_EMA_D_8, -1};
In the code file "/linux-2.6.33-rt29-psp03.30.00.02/arch/arm/mach-davinci/board-da850-evm.c", we modified as follows:
da8xx_pinmux_setup(da850_evm_user_dp_pins);

In the drive module for our system, I set as follows:
gpio_direction_input(3*16);//GP3.0input
data = gpio_get_value(3*16);
BUT, gpio_get_value is always 0, whatever GP3.0 high level or low level.

-2) I set AM1810 GP5[10] as GPIO port which played a role of "output". It was used to control LED and worked successfully. If I tried to read this port, gpio_get_value(5*16+10) kept 0.

-3) Thus seems we could conclude that for this GPIO port we defined, it is written-only, cannot be read.

But why? 

Thank you!

Best regards!

  • Hi Guotao,

    We do not support the AM1810 in the high speed interface forum. I am moving this post over to the ARM processor forum for support.

  • Hi,

    I presume that you have done pinmuxing properly for the GPIO and please make sure the same.

    In the drive module for our system, I set as follows:
    gpio_direction_input(3*16);//GP3.0input
    data = gpio_get_value(3*16);
    BUT, gpio_get_value is always 0, whatever GP3.0 high level or low level.

    I suspect that the problem could be GPIO no which you defined in "gpio_get_value"

    Actually, You can find out the GPIO no from TRM guide.

    GPIO3[0] = GPIO no is 49 but you have define 3*16 = 48

    Try to use,

    gpio_direction_input((3*16)+1);//GP3.0input
    data = gpio_get_value((3*16)+1);

    OR

    To avoid confusion, Use direct GPIO no from TRM,

    gpio_direction_input(49);//GP3.0input
    data = gpio_get_value(49);

    Also you can export and access your GPIO from user space linux.

    http://processors.wiki.ti.com/index.php/GPIO_Driver_Guide#User_Space_-_Sysfs_control

    Ex:

    echo 49 > /sys/class/gpio/export

    echo "in" > /sys/class/gpio/gpio49/direction

    cat /sys/class/gpio/gpio49/value

    Please let us know the results.

  • Hi Titus! Thank you for helping with the new problem again.

    Actually in this post, we set it as in the original code and we just picked up an example of 48. And we also used 49/50.. at the same time. But the same problem happened. 

     

    Why could it work for LED, but cannot read?

  • I believe linux numbesr it's GPIOs starting from 0. Conceptually, linux has 32 gpios per chip even though in reality there are 16 gpios per bank. The TRM starts from 1. I vaguely remember StarterWare is one of the few GPIO libraries that count from 1. The various board file(eg. board-da850-evm.c) use the macro GPIO_TO_PIN(() to hide the banking arrangement. Do you call gpio_request() before other gpio calls? That might cause problems. From a style standpoint, I don't think it is a good idea to redefine DA850_EMA_D_8. This definition is from EMIFA. You should define your own. Putting it all together would be something like this:

    1) mach-davinci/da850.c
    static const struct mux_config da850_pins[] = {
    ...
    MUX_CFG(DA850, GPIO3_0, 8, 28, 15, 8, false) // Add to end
    };

    2) mach-davinci/include/mach/mux.h
    enum davinci_da850_index
    {
    ...
      DA850_GPIO3_0 // <-- Add to end of enum
    };

    3) mach-davinci/board-da850-evm.c

    static inline void da850_evm_setup_nor_nand(void)
    {
    ...
    #if 0 // Add
     ret = davinci_cfg_reg_list(da850_evm_nor_pins);
     if (ret)
       pr_warning("da850_evm_init: nor mux setup failed: %d\n", ret);
     da850_evm_init_nor();
    #else // Add
      pr_warning("da850_evm_init: skip nor mux setup\n"); // Add to avoid muxing over GP3[0]
    #endif // Add
    ...
    }
    ...
    static __init void da850_evm_init(void)
    {
    ...
      ret = davinci_cfg_reg(DA850_GPIO3_0);
      if (ret)
        pr_warning("da850_evm_init:" setup failed %d\n", ret);
    }

    3) Your driver probe
    #define YOUR_INPUT_PIN GPIO_TO_PIN(3, 0)

      ret = gpio_request(YOUR_INPUT_PIN, "your_input_pin");
      if (ret)
        pr_warning("Cannot open GPIO %d\n", YOUR_INPUT_PIN);
      gpio_direction_input(YOUR_INPUT_PIN);

  • Hi,

    In the drive module for our system, I set as follows:
    gpio_direction_input(3*16);//GP3.0input
    data = gpio_get_value(3*16);
    BUT, gpio_get_value is always 0, whatever GP3.0 high level or low level.

    Why could it work for LED, but cannot read?


    No need to say the below points, Just I'm ensuring that you have knowledge on this.

    It ( GPIO5[10] ) is output and you would connect this GPIO to pull up with transistor but suppose if GPIO is input, you would connect the i/p GPIO pin to pull down with switch connection and it drive always low.

    And then i/p GPIO will drive high when you press switch if you connect the switch other end to VCC but it depends on design.

    We can drive high/low the i/p GPIO while pressing switch but it depends on design.

    Please refer our LCDK board schematic which comprises switch & LED designs.

    If your team has been experienced with CCS, then you can try starterware code for gpio examples with debugging.

    http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/115/t/341382.aspx

    As Norman told, Ensure that you have proper pinmuxing for the GPIO and also I hope that you have done good pinmuxing since you can control LED as well.

  • Hi,

    echo 49 > /sys/class/gpio/export

    echo "in" > /sys/class/gpio/gpio49/direction

    cat /sys/class/gpio/gpio49/value

    Have you tried this and how about the results?

    This is very common and good method for GPIO access.

    echo 49 > /sys/class/gpio/export

    echo "in" > /sys/class/gpio/gpio49/direction

    Press the switch continuously which is mapped to GPIO 49

    cat /sys/class/gpio/gpio49/value

    Release the switch which is mapped to GPIO 49

    cat /sys/class/gpio/gpio49/value

    Please let us know the status..

  • Hi Titus! Thank you!

    Sorry I wrongly understood it as I just interpreted my colleague's depiction directly here.  But he understood your meaning very well, but he doesn't think the problem comes from what you said earlier.  Combining with your thoughts, he is working on it now.

    I will update the progress timely here.

    At present, it is sure we can get right GPIO value by manully testing GPIO: Sysfs control, which means it has nothing to do with the hardwares.

  • Hi all! we met another problem and i have copied in the first post. Thank you. Your help is very important for us.

  • Hi Guotao,

    Question Two: Another question we don't understand and need your help: 

    We cite the printout here during the starting up process. As it is shown in red, we first time met this warning-"Unable to obtain voltage regulator for CVDD; voltage scaling unsupported". How can we figure it out?


    I would like to suggest that create new thread for this issue with mentioning new problem and it could help others.

    We will follow up it the GPIO issue in the same current thread.

    Thanks for your understanding.

  • Hi Norman and also Titus! 

    "echo 48 > /sys/class/gpio/export
    echo "in" > /sys/class/gpio/gpio48/direction
    cat /sys/class/gpio/gpio48/value"

    We can manually read the right value for gpio3.0 by the above operation as I mentioned in the last post, but gpio3.0 is still 0 via software after modifying software as you suggested. Actually we used 8 pins, namely gpio3.0-gpio3.7. Anyway gpio_get_value keeps 0. 

    BTW, our linux kernal version: linux-2.6.33-rt29-psp03.30.00.02

    Thank you!  

    and for the question two, I will create a new thread in this forum, and thanks for reminding.

  • Hi,

    We can manually read the right value for gpio3.0 by the above operation as I mentioned in the last post, but gpio3.0 is still 0 via software after modifying software as you suggested. Actually we used 8 pins, namely gpio3.0-gpio3.7. Anyway gpio_get_value keeps 0.

    Then, It is clear that you have problem with driver implementation,

    For GPIO,

    You have to call "gpio_request(49, "module_name") " API function before going to access the GPIO.

    Ex:

    gpio_request(49, "gpio_driver")

    I have written gpio driver with latest kernel (TI SDK) for OMAPL138 SDI EVM board.

    GPIO 165 is mapped to on board switch, thats why, I have configured as a input.

    GPIO 166 & 167 are mapped to on board LEDs, thats why, I have configured as a output.

    Compile the attached driver as module and cross compile the application file.

    Or else you can take this driver as example and modify it accordingly.

    Note:

    These GPIOs were derived by IO expander.

    5074.gpio_driver.tar.gz

  • Hi Titus and Norman! We fixed this problem on GPIO drive with your help. Comparing with the files you provided, we found there was some problem on the intermediate variables when we called the correpsonding functions. 

    Thank you very much. 

  • Hi Guotao,


    I'm glad to hear this news from you.

    Thanks for your update.