LINUX.ORG.RU

GPIO, подтягивание линии к нулю (DTS)

 


0

2

У меня возникла проблема.

Нужно при загрузке ядра выполнить подтягивание линии GPIO 52 к нижнему порогу (уровню). При этом, чтение из порта должно сохранять данную установку.

Выставление режима GPIO_ACTIVE_LOW | GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN пробовал выполнить так:

my-board.dts:

/ {
  ...
  mykey {
    compatible = "key";
    pinctrl-names = "default";
    // pinctrl-0 = <&pinctrl_gpio1_xxx>;
    key-gpios = <&gpio1 20 7>;
    interrupt-parent = <&gpio1>;
    interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
  };
  ...
};

Пробовал ещё так:

/ {
  ...
  gpio_keys {
    compatible = "gpio-keys";
    key_tab {
      label = "tab";
      gpios = <&gpio1 20 7>;
      gpio-key,wakeup;
      debounce-interval = <50>;
      linux,code = <15>; /* KEY_TAB */
    };
  };
  ...
};

Но линия не опускается по дефолту в ноль.

Помогает так:

#!/usr/bin/python3

def wr(fn, v):
  try:
    with open(fn, 'wt') as f:
      f.write(v)
  except OSError as e:
    s = repr(e)
    print(f'[WARNING] {s}')

DIR='/sys/class/gpio'
NUM='52'

wr(f'{DIR}/unexport', NUM)
wr(f'{DIR}/export', NUM)
wr(f'{DIR}/gpio{NUM}/direction', "out")
wr(f'{DIR}/gpio{NUM}/value', "1")

wr(f'{DIR}/unexport', NUM)
wr(f'{DIR}/export', NUM)
wr(f'{DIR}/gpio{NUM}/direction', "in")
wr(f'{DIR}/gpio{NUM}/edge', "both")

import select
import os
poll = select.poll()

fn = f'{DIR}/gpio{NUM}/value'
TIMEOUT = 3000
f = open(fn, 'rt')
fd = f.fileno()
poll.register(fd, select.POLLPRI)
print('fd =', fd)

poll.poll(TIMEOUT)
v = f.read()
print('v = , v)

k = 0

while True:
  events = poll.poll(TIMEOUT)
  print('ev =', events)
  if events:
    for pfd, pev in events:
      if pev & select.POLLPRI > 0:
        os.lseek(fd, 0, os.SEEK_SET)
        v = f.read().strip()
        print('v =', v)

poll.unregister(fd)
f.close()

# EOF

, но лишь на короткое время, до первого чтения из порта (при этом, .dts я не правлю)

Подскажите, что делаю не так? Если можно, экспертный совет, без шуток. Документацию по флагам брал из linux-x.x.x/Documentation и читал когда-то «DTS for Dummies». Толковой документации по настройке дерева DTS не понял, где найти. Похоже, что всё зависит от конкретного оборудования, и надо ближе знать электротехнические термины.

P.S. Код не очень красивый, это черновой набросок.

Нужно при загрузке ядра выполнить подтягивание линии GPIO 52 к нижнему порогу (уровню). При этом, чтение из порта должно сохранять данную установку.

Я хоть и сварщик не опытный, но представить себе это не могу: если ты притянул ногу к земле, то как с нее единицу прочитать без оттяжки назад?

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

если ты притянул ногу к земле, то как с нее единицу прочитать без оттяжки назад?

Ну… эти три флага ведь сочетаются:

/* Bit 0 express polarity */
#define GPIO_ACTIVE_HIGH 0
#define GPIO_ACTIVE_LOW 1

/* Bit 1 express single-endedness */
#define GPIO_PUSH_PULL 0
#define GPIO_SINGLE_ENDED 2

/* Bit 2 express Open drain or open source */
#define GPIO_LINE_OPEN_SOURCE 0
#define GPIO_LINE_OPEN_DRAIN 4

Допустимы их комбинации.

i_am_not_ai
() автор топика
Ответ на: комментарий от i_am_not_ai

То что в коде что-то можно написать и скомпилировать еще не значит что это имеет смысл.

Ну как ты физически это представляешь? Если линию с одного конца заземлили то на ней уже 1 ни как не выставить на другом.

urxvt ★★★★★
()

надо смотреть описание gpio в данном процессоре и реализацию опций пинов в драйвере gpio.
на каком-то стм32, сталкивался помнится что если одновременно установить несколько флагов на выход (в пределах одного регистра) то на выходе проскакивала «иголка». пришлось сначала выставлять выходные значения и только после этого переводить gpio из режима ввод в режим вывода. тогда гонки состояний не было.

pfg ★★★★★
()
Ответ на: комментарий от urxvt

но представить себе это не могу: если ты притянул ногу к земле, то как с нее единицу прочитать без оттяжки назад?

Подтяжка происходит достаточно большим сопротивлением, так что влияет только на поведение не подключенного пина.

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

ищи где настраивается pinmux/pinctrl/и т.п. в цепочке dtsi

Я так понимаю, некоторые блоки я могу из dtsi выкинуть, если pin’ы у меня используются по другому назначению - например, чисто как GPIO?

i_am_not_ai
() автор топика
Ответ на: комментарий от i_am_not_ai

Всё зависит от конкретного случая.

Например, у Allwinner в pinctrl ряд блоков пинов помечается как /omit-if-no-ref/, в другом случае приходиться делать копии dtsi и вносить изменения. Смотри примеры dts на твой проц.

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

Подтяжка происходит достаточно большим сопротивлением, так что влияет только на поведение не подключенного пина.

М... Можешь привести номинал резистора, когда на линии будет 0 и как ее потом вернуть в 1 не отключая этот резистор?

                              +5V
                               |
A -----------------------+-----+-- B
                         |
                        +-+
                        | | 
                        | |
                        +-+
                         |
                       --+--
                         |
                        ---
                         -

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Если ты нарисуешь резистор к 5В рельсе, то можно будет посчитать.

Если кратко - если ток в линии больше чем может чем пропустить через себя подтягивающий резистор - то установится соответствующий потенциал(если ток достаточно большой, а сопротивление достаточно высокое, падение напряжение будет незаметным).

Dark_SavanT ★★★★★
()
Ответ на: комментарий от Dark_SavanT
dev A                     dev B
---+----        ...       --+-- +5V
   |                           
  +-+                     
  | |                      
  | | R1 100                    
  +-+                     
   |                      
---+----        ...       --+- pin
                            |
                           +-+
                           | |
                           | | R2 1000
                           +-+
                            |
-------        ...        --+-- GND


Правильно ли я тебя понимаю, что на первом этапе B притягивает через R2 линию к 0 а на втором устройство A выставляет ее в 1 с помощью меньшего резистора?

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Типа того. В чипе есть два варианта - либо тянется через резистор(там 40-100кОм обычно, чем дальше от контроолеров, тем нежнее), либо open-drain, это напрямую через транзистор, но если сунуть в линию слишком много, то этот самый транзистор и сделает пыщ. I2C так работает.

Ситуация, когда в двух точках тянут каждый к своему напряжению через резисторы - приводит к тому, что на линии хренпоймичо(мы же про цифру говорим) получается и это схемотехническая ошибка.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от pfg

надо смотреть описание gpio в данном процессоре и реализацию опций пинов в драйвере gpio

Почитал Linux Reference Manual на проц, там вроде всё толково описано.

Нашёл отсылку на drivers/pinctrl/*.c, там названия pads. Буду дальше копать.

Примеров бы найти.

i_am_not_ai
() автор топика