Тактовая частота контроллера клавиатуры CLK_KBD = 1/24 CLC. CLC = 6.25МГц (0.16мкс). Таким образом, период CLK_KBD = 3.84мкс. Из CLK_KBD формируется рабочая тактовая частота CLK_KBD1_16 = 1/16 CLK_KBD (период 61.44мкс), а так же вспомогательные фазы CLK_KBD_0B и CLK_KBD_0D.
Счетчик CTR_KBD_Y, управляющий сканированием столбцов Y, тактируется CLK_KBD1_16, и считает циклически от 0 до 0x0F.
Счетчик CTR_KBD_X, управляющий бегущим нулем на X, тактируется CLK_KBD1_16 * 16 (983.04мкс), считает циклически от 0 до 0x0F, причем, счет 0..0x7 - фаза нажатия клавиш, счет 0x08 - фаза отжатия клавиш, 0x09..0x0F - холостая фаза.
Таким образом, один полный цикл опроса клавиатуры занимает 15728.64мкс (15.728мс), что равно почти целому кадру развертки.
На каждый счет CTR_KBD_X, приходится полный цикл сканирования столбцов Y (1..15, 0-й столбец отсутствует).
Код нажатой клавиши в регистре KBD_DATA формируется из текущего состояния обеих счетчиков. Старший полубайт - это счетчик CTR_KBD_X, младший полубайт - это счетчик CTR_KBD_Y.
Остановка тактовой частоты CLK_KBD происходит по событию KEY_READY, которое, в свою очередь, формируется по заднему фронту события KEY_MISMATCH, которое формируется всякий раз при нажатии или отжатии клавиши.
По чтению регистра данных клавиатуры KBD_DATA, снимается событие KEY_READY, и тактовая частота запускается заново.
Бегущий ноль на линии X промодулирован частотой CLK_KBD1_16. Т.е. активен во время низкого уровня CLK_KBD1_16.
В этой же тактовой фазе активен сигнал на выходе дешифратора DC_CTR_Y, который управляет сканированием линий Y.
Основные модули контроллера:
Y_MEMORY_A, Y_MEMORY_B и Y_MEMORY_C - регистры, запоминающие столбцы Y, в которых нажата хотя бы одна клавиша.
Y_MEMORY_A - отражает текущее состояние столбцов, т.к. целиком очищается перед фазой сканирования, а устанавливается во время фазы сканирования.
Y_MEMORY_B - отражает суммарное предыдущее и текущее состояние столбцов с нажатыми клавишами. Регистр не очищается после предыдущего цикла, а устанавливается аналогично Y_MEMORY_A во время фазы сканирования. Очистка Y_MEMORY_B происходит копированием содержимого Y_MEMORY_A во второй фазе цикла.
Y_MEMORY_C - хранит предыдущую копию Y_MEMORY_B, и обновляется в тактовом цикле CLK_KBD_0D. На основе разницы Y_MEMORY_B и Y_MEMORY_C формируется событие нажатия/отжатия клавиши KEY_MISMATCH.
Главный цикл опроса клавиатуры состоит из трех фаз - фазы определения нажатия клавиши, фазы определения отжатия клавиши, и холостой фазы.
Первая фаза - определение нажатия клавиш (счетчик CTR_KBD_X = 0x00..0x07):
В активной фазе CLK_KBD1_16 (CLK_KBD1_16 = 0) схемой COL_Y_COMP сигнал на выходе дешифратора сравнивается с входами порта Y. В случае наличия на соответствующeй линии нуля (нажата клавиша на пересечении ряда X, и столбца Y), в регистрах Y_MEMORY_A и Y_MEMORY_B устанавливается бит соответствующий столбцу Y. Если обновленное содержимое Y_MEMORY_B отличается от значения, зафиксированного в предыдущем цикле в Y_MEMORY_C, то возникает событие KEY_MISMATCH.
По окончанию активной фазы CLK_KBD1_16, снимается сигнал с линий X, вследствие чего пропадает сигнал и на линиях Y. Также отключается дешифратор DC_CTR_Y, управляющий компаратором COL_Y_COMP.
После этого следует короткий импульс тактового цикла CLK_KBD_0D, записывающий текущее значение Y_MEMORY_B в регистр последнего значения Y_MEMORY_C, вследствие чего отключается событие KEY_MISMATCH, если оно было активно. По снятию события KEY_MISMATCH активизируется событие KEY_READY, останавливающее тактирование CLK_KBD, предлагая программе считать из регистра KEY_DATA код нажатой клавиши. После чтения кода клавиши, тактирование CLK_KBD возобновляется.
Вторая фаза - определение отжатия клавиш (счетчик CTR_KBD_X = 0x08):
В активной фазе CLK_KBD1_16 (CLK_KBD1_16 = 0) на линии X0 так же появляются тактовые импульсы CLK_KBD1_16, что является побочным эффектом и не используется. Схема сравнения COL_Y_COMP отключена.
По окончанию активной фазы CLK_KBD1_16, следует короткий импульс тактового цикла CLK_KBD_0B, по которому в регистре Y_MEMORY_B сбрасывается текущий бит, если сброшен такой же бит в регистре Y_MEMORY_A.
Таким образом, если Y_MEMORY_B все еще помнит клавишу, нажатую в предыдущем цикле, а в текущем цикле она была отпущена (отсутствует в Y_MEMORY_A), возникает событие KEY_MISMATCH.
После этого следует короткий импульс тактового цикла CLK_KBD_0D, по которому сбрасывается бит в регистре Y_MEMORY_A, соответствующий линии Y. Т.е. фактически происходит очистка Y_MEMORY_A перед следующим циклом.
Также переписывается Y_MEMORY_B в Y_MEMORY_C, вследствие чего отключается событие KEY_MISMATCH, если оно было активно. По снятию события KEY_MISMATCH активизируется событие KEY_READY, останавливающее тактирование CLK_KBD, предлагая программе считать из регистра KEY_DATA код отжатой клавиши. После чтения кода отжатия клавиши, тактирование CLK_KBD возобновляется.
Третья фаза - холостая (счетчик CTR_KBD_X = 0x09..0x0F):
В этой фазе так же появляется бегущий ноль на линиях X, промодулированный по CLK_KBD1_16, однако это никак не используется.
Влияние EP на опрос клавиатуры:
EP также, как и активное событие KEY_READY, блокирует установку нажатой клавиши в регистрах Y_MEMORY_A и Y_MEMORY_B в первой фазе цикла опроса. Следует заметить, что блокировка по KEY_READY является излишней, т.к. во время события KEY_READY тактовая частота контроллера клавиатуры остановлена.
Помимо этого, EP запрещает бегущий ноль на линиях X.
Также, EP разрешает вывод регистра KBD_BUS на линии Y. Кроме содержимого KBD_BUS (линии Y3..Y15), на линию Y2 выводится тактовая частота контроллера клавиатуры CLK_KBD, а на линию Y1 - сигнал чтения регистра KBD_BUS.
Условно недокументированные особенности, возможности и ошибки:
1. Поскольку код нажатия клавиши формируется в момент фактического нажатия, когда счетчики Y и X указывают на конкретную клавишу, в регистре KBD_DATA формируется полный код нажатой клавиши.
Однако, код отжатия клавиши формируется уже после фактического отжатия клавиши, когда счетчик Y указывает на актуальный столбец, а счетчик X указывает на ряд 0. Поэтому в регистре KBD_DATA формируется неполный код отжатия клавиши, по которому можно определить лишь столбец Y, в котором отпущены все клавиши, но не ряд X.
2. Из регистра KBD_BUS (177704) можно считывать состояние порта Y в реальном времени.
3. Из регистра KBD_DATA (177702) можно считывать текущее состояние счетчиков CTR_KBD_X и CTR_KBD_Y. Причем, учитывая, что чтение счетчиков никак не синхронизировано с тактовой частотой контроллера клавиатуры, не исключена возможность чтения счетчиков в промежуточной фазе счета, когда одна часть счетчика уже установлена, а другая нет. Для того, чтобы понять, возможно ли такое попадание в середину фазы счета, надо изучать всю схемотехнику УКНЦ в целом.
4. Если в течение одного цикла счетчика CTR_KBD_X нажаты и удерживаются две и более клавиши в одном столбце, то первое чтение KBD_DATA, даст код первой зафиксированной в столбце клавиши. Вторая и остальные нажатые в этом цикле, и в этом столбце клавиши, определены не будут. Т.е. фактически одновременное нажатие нескольких клавиш в столбце может привести к потере события нажатия одной из них.
5. Возможно написание собственного опроса клавиатуры, т.к. программно доступны счетчики X, Y, и состояние порта Y. На практике же такой опрос будет очень медленным, из-за того, что полный цикл сканирования клавиатуры равен почти 16мс, что сопоставимо с размером одного кадра развертки (20мс).
6. Все биты счетчиков CTR_KBD_X и CTR_KBD_Y сбрасываются по INIT, за исключением бита 0 счетчика CTR_KBD_X, который сбрасывается по DLCO.
7. Следует заметить, что схема опроса клавиатуры имеет немалую логическую избыточность, и на втором этапе реверса оптимизирована.
[свернуть]