Введение

Драйвер клавиатуры ADP5588

ADP5588 - контроллер полноценной QWERTY клавиатуры. Контроллер имеет интерфейс I2C и поддерживат до 80 кнопок (матрица 8х10). Довольно просто сделать для него полноценную клавиатуру, правда, понадобится пересобирать ядро Linux.

Из дополнительных плюсов - можно назначать неиспользуемые ножки как GPIO (18 ножек)

В моём случае нужна была клавиатура 5х5, которая подключалась . Контроллеров клавиатуры 4х4 полно, а вот для 5х5 ничего лучше не нашёл.

Т.к. используется не полная матрица, то было решено использовать не драйвер ядра, а написать свою простенькую С++ класс, который опрашивает контроллер по шине I2C и добавляет сообщения о нажатых клавишах в общий поток программы.

На эту простую утилиту ушло довольно много рабочего времени, поэтому хочу изложить свой опыт и рассказать о граблях на которые я наступал.

Корпус

Корпус у микросхемы LFCSP (4 mm × 4 mm) с подогнутыми под себя ножками. Вручную запаять довольно ложно. В другом корпусе не выпускается.

Подключение

Перерыл Datasheet на ADP5588 несколько раз, так и не нашёл какие номиналы подтягивающих резисторов ей нужны. На шину I2C стандартно идут подтягивающие резисторы 10к. Соответственно поставил их на SCL, SDA,а также на INT и RST (напомню, что подтягивающие резисторы ставятся между выводом и напряжением питания). Что оказалось неправильно: микросхема периодически повисала и переставала отвечать. Оказывается на RST нужно ставить резистор гораздо меньшего номинала: 1-3к, иначе напряжение на RST слишком низкое и микросхема устав от работы начинает пребывать в вечном ресете.

Напряжение питания

Не сразу заметил, что максимальное напряжение питания микросхемы не 3.3V, а 3.0V, хотя в Absolute Maximum Ratings сказано, что она выдерживает до 4В. Некоторые питают её от 3.3V и контроллер клавиатуры вполне работает. Но если мы делаем серийно изготавливаемое устройство, которое будет работать круглые сутки, то намеренное превышение данных из даташита - всё-таки преступление.

Решение есть - запитать её от отдельного линейного стабилизатора 5В->3.3В, а ножки SCL, SDA и INT подключить через резисторы 270 Ом. Этого сопротивления с одной стороны достаточно, чтобы логическая "1"  шины I2C со стороны контроллера верхнего уровня (в моём случае это Beagle Bone Black) была 3.3 В, а со стороны контроллера клавиатуры - около 3.0В. Сильно увеличивать значение сопротивления тоже не рекомендуется т.к. в этом случае уровень логического "0" со стороны BeagleBone будет слегка приподниматься.

Адрес микросхемы

Разработчики из Analog devices пишут, что микросхема имеет 2 адреса 0х68 и 0х69, один на запись, другой на чтения). Строго говоря - они не правы. Адрес на шине I2C считается без последнего бита, который отвечает за запись. Т.е. адрес устройства на шине I2C у микросхемы 0х38! А бит записи сам будет устанавливаться в зависимости от операции.

Под линуксом просканировать все дотупные устройства поможет утилита i2cdetect.

Настройка на чтение клавиш

Как ни странно, но по умолчанию микросхема работает не с клавиатурой, а с GPIO. Для переключение ножек в режим клавиатуры нужно настроить регистры KP_GPIO1 и KP_GPIO2. Для матрицы 5х5 записываем туда значение 00011111 т.е. 0х1F.

Также нужно настроить, чтобы нажатые клавиши попадали в буфер (макс. 10 значений). Для этого в регистры GPI_EM_REG1 и GPI_EM_REG2 записываем то же самое значение 0x1F.

Обязательно нужно задать регистр CFG_REG, один из бит которого отвечает за очень полезную функцию - автоинкремент (о ней будет сказано чуть позже).
Самый младший бит регистра отвечает за прерывания по событию клавиатуры. Очень хотелось бы не постоянно опрашивать клавиатуру, а обращаться к ней как только произойдёт событие (ножка INT установится в "0").
Но не получилось: При установке бита отвечающего за прерывание клавиатуры, при первом же нажатии клавиши виснет сам контроллер и вдобавок вешает шину I2C (помогает только отключение питания).
В итоге пришлось обойтись без прерываний. Для включения автоинкремента я записываю CFG_REG = 0xE0;

Как читать данные

Регистров для чтения данных - 10 штук (адреса 0х04 - 0х0D). Чтобы не вычитывать данные с каждого из них нужно включить автоинкремент, и читать только из одного, например 0x04. При чтении из регистра туда будет автоматически записываться следующее событие.

Старший бит данных отвечает за нажатие/отпускание клавиши. Т.е. пока нет данных мы будем вычитывать 0х00, при нажатии клавиши на пересечении R0 и C0 мы получим код 129 (десятичный), а при отпускании 1.

Заключение

Надеюсь, подобное руководство поможет кому-то сэкономить своё драгоценное время. Если у вас есть дополнения или исправление - не стесняйтесь, пишите комментарии.

Добавить комментарий


Поиск