О каких вычислениях речь ????
Вид для печати
ZEK, давайте все вживую завтра буду проверять , если время будет .
И так - решили все же заводить строб чтения клавы ?
1) сколько он длительностью минимально- максимально?
2) Я накидаю код - пока минимальный на проверку реакции :
На пин заводим положительный импульс , по фронту прерывание, в прерывании
манипуляции и выхлоп строба в порт .
Снимаю все лог.анализатором . Для ускорения процесса внешний сигнал буду генерировать отдельным пином на той же борде .
А там уже бум гадать ...
Ну в общем да, с прерыванием полная лажа - меньше 600 nS даже в тесте, и даже на асме не получим .
Как ранее и хотел- надо рыть аппаратную реализацию, на DMA, событиях и т.д.
Короче пошел я дальше извращаться .
Кстати могу на 103 и F4 до кучи по тестить .:biggrin:
Да, что еще хотел узнать ,
можно еще узнать время, между установкой на адресах и фронтом /IN_K&K?
Мобыть здесь уместимся ?:biggrin:
---------- Post added at 09:28 ---------- Previous post was at 09:20 ----------
Вот смотрю я на схему Phoenix - вижу вход тактовой -14МГц .:biggrin:
Вот кто мне может на пальцах объяснить как в ZXMC сие работает .
Может извращениями занимаемси - загоняя все в такие жесткие рамки? :biggrin:
И еще :
Можно примеры чтения клавиатуры, на спекковском асме , если можно с раскладкой тактов.
Способы увеличения скорости:
1. Если не пробовали, сделать вывод заранее рассчитанного значения из массива:
На C:
PORT_KEY_DATA = BUFFER [PORT_KEY_ADDRESS]
На ассемблере:
IN R28, PORT_KEY_ADDRESS ; загрузка адреса клавиатуры в младший байт регистра Y
LD TMP, Y ; чтение байта из буфера/таблицы по адресу Y
OUT PORT_KEY_DATA, TMP ; запись байта в порт данных клавиатуры.
2. Сделать схему на самом дешевом арме, 8 регистрах и 20 двойных диодах - очень быстрая схема и контрольная сумма
3. Сделать схему без микроконтроллера и контрольной суммы на 8 регистрах и 20 двойных диодах. 3 входных сигнала вместо одного RX - - очень быстрая схема, но нет контрольной суммы пакета
4. Сделать схему без микроконтроллера на ПЛИС, включая протокол типа UART - очень быстрая схема и контрольная сумма, но неполноценный UART
5. Сделать на ATMЕГЕ c частотой 20 МГц, у которой есть два свободных порта, и RX на третьем. Писать на ассемблере. Трудно найти подходящий МК по доступной цене.
В контроллере клавиатуры Феникса скорее всего есть wait-ы, в KEYB&SINC нет wait-oв.
zst, Да дело в том что в прерывание мы попадаем через 600nS после фронта.
В те условия что поставил ZEK похоже хрен впишемся.:biggrin:
Блин хоть внешнюю RAM двунаправленую ставь .:biggrin:
Посмотрел чтение портов в Z80 - крутизна .
pic parallel slave port?
Как Вам такое :
SRAM самая дешевая . Выкинуть пуллапы с данных клавиатуры + мультиплекс на адреса .
Имеем аппаратную эмуляцию клавы практически без кромсания схемы спекки.
Теряем - 8 пинов + 5пинов + 1управление мультиплексом + 1 SRAM запись.
Не надо привязываться к сигналам спекки + обновление данных раз в 20mS за глаза и за уши...
Опять таки - определить латентность прерываний .
Тут дело не в скорости выхлопа - а время реакции ...
Atmega48 за 1.5$
2 атмеги?
По данным ZEK время перехода на функцию обработки прерываний должно быть 12/48=0.25 мкс. А у вас 0.6 мкс. Что-то не так. Или частота не 48 МГц. Или 12 тактов это для F100-103, а у F051 количество тактов равно 0.6*48 = 28.8
Пробовали для измерения в функции обработки прерываний просто уровень сигнала менять без дополнительных команд ?
ZEK, можно на ПЛИС EPM3064 написать аналог схемы на регистрах + интерфейс UART?
Мы что-то долго разрабатываем компьютерную часть ZX Remote KEYPADа. А на какой конфигурации удаленной части мы остановились и что для реализации нужно ? Если подвести итоги обсуждения, то намечается коробочка с индикатором от телефона и двумя кнопками для выбора типа джойстика и команд.
К этой коробочке можно подключить:
- Mini KeyPad из 6 механических кнопок
- SEGA джойстик
- NES/SNES джойстик
- PS/2 клавиатуру
- PS/2 мышку
- USB клавиатуру
- USB мышку
- USB джойстик
Не много ли ? Что в этом списке лишнее ? Если у нас будет клавиатура и мы будем передавать ее данные через 2 байта, что с ними делать дальше в компьютерном блоке ? Нужно учитывать, что в оригинальном Спектруме у KEMPSTON джойстика и мышки одинаковые адреса и они не могли быть подключены одновременно.
Если делать в стиле Спектрума, то на 1816ВЕ31 + восемь регистров + ...
Да все верно, для F0 не 12 тактов а 16 и плюс латентность прерываний, заложенная вендором,
и плюс то что у F0 0.9MIPS и плюс пара тактов на установку пина
Точно так же ,Цитата:
Сообщение от zst
собственно почему и не особо уповал на прерывания , надо аппаратный способ рыть или внешнее железо.
---------- Post added at 22:23 ---------- Previous post was at 22:21 ----------
Ну в Вашем списке все кроме USB можно на STM32F051 реализовать.
А если 12-16 механических кнопок подключить к арму через регистры сдвига, то можно будет загружать их как NES/SNES.
Количество выводов:
Механические кнопки через регистры = 3
NES/SNES = 3
SEGA = 7
Индикатор от телефона = 3 ?
UART TX = 1
2 * PS/2 = 4
Итого: 3 + 3 + 7 + 3 +1 + 4 = 21
Нужен 64-ногий арм с учетом совместимости с +5 В.
arm с usb хостом и хабом + cpld
как по мне, самое интересный вариант, особеноо если вместо экранчика вывод накладывать на видевыхлоп, видео армрм просто вывести будет, dma
Может dsPIC?
Гы ... На F4 без оптимизации , тупой вывод из массива в соответствии с захваченными адресами - 330nS . 168МГц тактовая от HSE.
http://s43.radikal.ru/i101/1401/22/9f106e644965.png
http://s017.radikal.ru/i430/1401/7e/52fd22ec7cb7.png
Код:void EXTI2_IRQHandler (void)
{
uint16_t input_buff;
uint8_t output_buff=0;
EXTI_STB_ON;
input_buff=(GPIOB->IDR)&0x00ff;
switch(input_buff)
{
case 0x01:output_buff |=key_buff[0];break;
case 0x02:output_buff |=key_buff[1];break;
case 0x04:output_buff |=key_buff[2];break;
case 0x08:output_buff |=key_buff[3];break;
case 0x10:output_buff |=key_buff[4];break;
case 0x20:output_buff |=key_buff[5];break;
case 0x40:output_buff |=key_buff[6];break;
case 0x80:output_buff |=key_buff[7];break;
default:break;
}
GPIOB->ODR=output_buff;
EXTI_STB_OFF;
EXTI->PR |=EXTI_PR_PR2;
Код:EXTI2_IRQHandler PROC
;;;2
;;;3 void EXTI2_IRQHandler (void)
000000 2000 MOVS r0,#0
;;;4 {
;;;5 uint16_t input_buff;
;;;6 uint8_t output_buff=0;
;;;7
;;;8
;;;9 EXTI_STB_ON;
000002 2202 MOVS r2,#2
000004 4b48 LDR r3,|L1.296|
000006 619a STR r2,[r3,#0x18]
;;;10
;;;11 input_buff=(GPIOB->IDR)&0x00ff;
000008 4a48 LDR r2,|L1.300|
00000a 6812 LDR r2,[r2,#0]
00000c b2d1 UXTB r1,r2
;;;12 switch(input_buff)
00000e 2910 CMP r1,#0x10
000010 d020 BEQ |L1.84|
000012 dc08 BGT |L1.38|
000014 2901 CMP r1,#1
000016 d00d BEQ |L1.52|
000018 2902 CMP r1,#2
00001a d00f BEQ |L1.60|
00001c 2904 CMP r1,#4
00001e d011 BEQ |L1.68|
000020 2908 CMP r1,#8
000022 d127 BNE |L1.116|
000024 e012 B |L1.76|
|L1.38|
000026 2920 CMP r1,#0x20
000028 d018 BEQ |L1.92|
00002a 2940 CMP r1,#0x40
00002c d01a BEQ |L1.100|
00002e 2980 CMP r1,#0x80
000030 d120 BNE |L1.116|
000032 e01b B |L1.108|
|L1.52|
;;;13 {
;;;14 case 0x01:output_buff |=key_buff[0];break;
000034 4a3e LDR r2,|L1.304|
000036 7812 LDRB r2,[r2,#0] ; key_buff
000038 4310 ORRS r0,r0,r2
00003a e01c B |L1.118|
|L1.60|
;;;15 case 0x02:output_buff |=key_buff[1];break;
00003c 4a3c LDR r2,|L1.304|
00003e 7852 LDRB r2,[r2,#1] ; key_buff
000040 4310 ORRS r0,r0,r2
000042 e018 B |L1.118|
|L1.68|
;;;16 case 0x04:output_buff |=key_buff[2];break;
000044 4a3a LDR r2,|L1.304|
000046 7892 LDRB r2,[r2,#2] ; key_buff
000048 4310 ORRS r0,r0,r2
00004a e014 B |L1.118|
|L1.76|
;;;17 case 0x08:output_buff |=key_buff[3];break;
00004c 4a38 LDR r2,|L1.304|
00004e 78d2 LDRB r2,[r2,#3] ; key_buff
000050 4310 ORRS r0,r0,r2
000052 e010 B |L1.118|
|L1.84|
;;;18 case 0x10:output_buff |=key_buff[4];break;
000054 4a36 LDR r2,|L1.304|
000056 7912 LDRB r2,[r2,#4] ; key_buff
000058 4310 ORRS r0,r0,r2
00005a e00c B |L1.118|
|L1.92|
;;;19 case 0x20:output_buff |=key_buff[5];break;
00005c 4a34 LDR r2,|L1.304|
00005e 7952 LDRB r2,[r2,#5] ; key_buff
000060 4310 ORRS r0,r0,r2
000062 e008 B |L1.118|
|L1.100|
;;;20 case 0x40:output_buff |=key_buff[6];break;
000064 4a32 LDR r2,|L1.304|
000066 7992 LDRB r2,[r2,#6] ; key_buff
000068 4310 ORRS r0,r0,r2
00006a e004 B |L1.118|
|L1.108|
;;;21 case 0x80:output_buff |=key_buff[7];break;
00006c 4a30 LDR r2,|L1.304|
00006e 79d2 LDRB r2,[r2,#7] ; key_buff
000070 4310 ORRS r0,r0,r2
000072 e000 B |L1.118|
|L1.116|
;;;22 default:break;
000074 bf00 NOP
|L1.118|
000076 bf00 NOP ;14
;;;23 }
;;;24
;;;25 GPIOB->ODR=output_buff;
000078 4a2c LDR r2,|L1.300|
00007a 1d12 ADDS r2,r2,#4
00007c 6010 STR r0,[r2,#0]
;;;26
;;;27 EXTI_STB_OFF;
00007e f44f3200 MOV r2,#0x20000
000082 4b29 LDR r3,|L1.296|
000084 619a STR r2,[r3,#0x18]
;;;28 EXTI->PR |=EXTI_PR_PR2;
000086 4a2b LDR r2,|L1.308|
000088 6812 LDR r2,[r2,#0]
00008a f0420204 ORR r2,r2,#4
00008e 4b29 LDR r3,|L1.308|
000090 601a STR r2,[r3,#0]
;;;29
;;;30 }
000092 4770 BX lr
;;;31
ENDP
zst, Если интересно - небольшой quick_start для F4
http://kazus.ru/forums/showthread.php?t=106278
Отлично ! 150 ns от начала импульса прерывания до результата команды EXTI_STB_ON;
Теперь давайте займемся оптимизацией:
1. Импульс прерывания нужно сделать другой полярности. То есть при чтении из порта клавиатуры IN_FE (IN_K&K) сигнал равен 0, а не 1.
2. Немного сократим функцию прерывания:
3. Массив key_buff2 заполним заранее, сразу после получения пакета по UART:Код:...
EXTI_STB_ON;
GPIOB->ODR = key_buff2 [(GPIOB->IDR)&0x00ff];
EXTI_STB_OFF;
...
Код:...
for (key_address = 0; key_address <= 255; key_address++) // цикл адреса с клавиатуры от 0 до 255 для заполнения массива данных с клавиатуры
{
key_data = 255; // начальный результат - все единицы - кнопки не нажаты
tmp_byte = key_address; // копируем для разбора по битам
for (b = 7; b >= 0; b--) // цикл по битам адреса с клавиатуры
{
tmp_byte &= 0x00ff; // обнуляем все биты, кроме 8 младших
if (tmp_byte < 128) // если старший бит в байте 0, то
{
key_data &= key_buff[b]; // добавляем к результату состояние соответствующего ряда клавиатуры из пакета
}
tmp_byte = tmp_byte << 1; // сдвигаем байт адреса влево
}
key_buff2[key_address] = key_data; // рассчитанный байт клавиатуры для данного адреса клавиатуры записываем в массив
}
Дык в курсе , все это легко переделывается :
Код:EXTI->IMR |= EXTI_IMR_MR2;
EXTI->RTSR |=EXTI_RTSR_TR2; <- меняем на EXTI->FTSR |=EXTI_FTSR_TR2;
NVIC_SetPriority(EXTI2_IRQn ,12);
NVIC_EnableIRQ(EXTI2_IRQn );
Вы все таки хотите буфер на 256 , А смысл, если теперь укладываемся ?Цитата:
2. Немного сократим функцию прерывания:
Код:...
EXTI_STB_ON;
GPIOB->ODR = key_buff2 [(GPIOB->IDR)&0x00ff];
EXTI_STB_OFF;
...
Я тут протащил эмуляцию - самый тяжелый вариант когда входной буфер адресов равен 0xFF.
Смотрите сами - 600nS . Думаю норм если, учесть что это быдлокод, да еще и отладку выкинуть.
http://s020.radikal.ru/i717/1401/c0/621fac793760.png
Код:void EXTI2_IRQHandler (void)
{
uint8_t input_buff;
uint8_t output_buff=0;
EXTI_STB_ON;
input_buff=(uint8_t)(GPIOB->IDR)&0x00ff;
input_buff=0xFF;
if(input_buff & 0x01)output_buff |=key_buff[0];
if(input_buff & 0x02)output_buff |=key_buff[1];
if(input_buff & 0x04)output_buff |=key_buff[2];
if(input_buff & 0x08)output_buff |=key_buff[3];
if(input_buff & 0x10)output_buff |=key_buff[4];
if(input_buff & 0x20)output_buff |=key_buff[5];
if(input_buff & 0x40)output_buff |=key_buff[6];
if(input_buff & 0x80)output_buff |=key_buff[7];
GPIOB->ODR=output_buff;
EXTI_STB_OFF;
EXTI->PR |=EXTI_PR_PR2;
}
Код:EXTI2_IRQHandler PROC
;;;2
;;;3 void EXTI2_IRQHandler (void)
000000 2000 MOVS r0,#0
;;;4 {
;;;5 uint8_t input_buff;
;;;6 uint8_t output_buff=0;
;;;7
;;;8
;;;9 EXTI_STB_ON;
000002 2202 MOVS r2,#2
000004 4b46 LDR r3,|L1.288|
000006 619a STR r2,[r3,#0x18]
;;;10
;;;11 input_buff=(uint8_t)(GPIOB->IDR)&0x00ff;
000008 4a46 LDR r2,|L1.292|
00000a 6812 LDR r2,[r2,#0]
00000c b2d1 UXTB r1,r2
;;;12 input_buff=0xFF;
00000e 21ff MOVS r1,#0xff
;;;13
;;;14 if(input_buff & 0x01)output_buff |=key_buff[0];
000010 f0110f01 TST r1,#1
000014 d002 BEQ |L1.28|
000016 4a44 LDR r2,|L1.296|
000018 7812 LDRB r2,[r2,#0] ; key_buff
00001a 4310 ORRS r0,r0,r2
|L1.28|
;;;15 if(input_buff & 0x02)output_buff |=key_buff[1];
00001c f0110f02 TST r1,#2
000020 d002 BEQ |L1.40|
000022 4a41 LDR r2,|L1.296|
000024 7852 LDRB r2,[r2,#1] ; key_buff
000026 4310 ORRS r0,r0,r2
|L1.40|
;;;16 if(input_buff & 0x04)output_buff |=key_buff[2];
000028 f0110f04 TST r1,#4
00002c d002 BEQ |L1.52|
00002e 4a3e LDR r2,|L1.296|
000030 7892 LDRB r2,[r2,#2] ; key_buff
000032 4310 ORRS r0,r0,r2
|L1.52|
;;;17 if(input_buff & 0x08)output_buff |=key_buff[3];
000034 f0110f08 TST r1,#8
000038 d002 BEQ |L1.64|
00003a 4a3b LDR r2,|L1.296|
00003c 78d2 LDRB r2,[r2,#3] ; key_buff
00003e 4310 ORRS r0,r0,r2
|L1.64|
;;;18 if(input_buff & 0x10)output_buff |=key_buff[4];
000040 f0110f10 TST r1,#0x10
000044 d002 BEQ |L1.76|
000046 4a38 LDR r2,|L1.296|
000048 7912 LDRB r2,[r2,#4] ; key_buff
00004a 4310 ORRS r0,r0,r2
|L1.76|
;;;19 if(input_buff & 0x20)output_buff |=key_buff[5];
00004c f0110f20 TST r1,#0x20
000050 d002 BEQ |L1.88|
000052 4a35 LDR r2,|L1.296|
000054 7952 LDRB r2,[r2,#5] ; key_buff
000056 4310 ORRS r0,r0,r2
|L1.88|
;;;20 if(input_buff & 0x40)output_buff |=key_buff[6];
000058 f0110f40 TST r1,#0x40
00005c d002 BEQ |L1.100|
00005e 4a32 LDR r2,|L1.296|
000060 7992 LDRB r2,[r2,#6] ; key_buff
000062 4310 ORRS r0,r0,r2
|L1.100|
;;;21 if(input_buff & 0x80)output_buff |=key_buff[7];
000064 f0110f80 TST r1,#0x80
000068 d002 BEQ |L1.112|
00006a 4a2f LDR r2,|L1.296|
00006c 79d2 LDRB r2,[r2,#7] ; key_buff
00006e 4310 ORRS r0,r0,r2
|L1.112|
;;;22
;;;23 GPIOB->ODR=output_buff;
000070 4a2c LDR r2,|L1.292|
000072 1d12 ADDS r2,r2,#4
000074 6010 STR r0,[r2,#0]
;;;24
;;;25 EXTI_STB_OFF;
000076 f44f3200 MOV r2,#0x20000
00007a 4b29 LDR r3,|L1.288|
00007c 619a STR r2,[r3,#0x18]
;;;26 EXTI->PR |=EXTI_PR_PR2;
00007e 4a2b LDR r2,|L1.300|
000080 6812 LDR r2,[r2,#0]
000082 f0420204 ORR r2,r2,#4
000086 4b29 LDR r3,|L1.300|
000088 601a STR r2,[r3,#0]
;;;27
;;;28 }
00008a 4770 BX lr
;;;29
ENDP
Хорошо , я тут накидаю и протащу .Цитата:
3. Массив key_buff2 заполним заранее, сразу после получения пакета по UART:
Надо еще внешний стимулятор сделать, раскинуть порты и подумать как сие соптимизировать на счет пинов . Думается все в один порт ...
Тут надо добавлять к результату по &
Да, это бы позволило ставить MК по проще / дешевле. К тому же в некоторых компьютерах сигнал чтения с клавиатуры может формироваться долго, что для механической клавиатуры не важно, а у нашей схемы не будет запаса. Да и некоторые Z80 работают на частоте 7МГц.Цитата:
...
Хорошо , я тут накидаю и протащу .
Кстати USB работает только на частоте 48 МГц.
Это Вы о чем? И к чему ? 4xx есть OTG Hs а это 480мбитс.
Повесил на вход кнопку :
http://s020.radikal.ru/i705/1401/2b/12b8541b1f0a.png
Как видите все стабильно, те же 600nS при проверке всего порта.
Где она справляется , покажи будь добр .
Если это о ZXMC , то не находишь что совершенно разные вещи сравниваем ?
И если ты помнишь - изначально я F0 предлагал - чисто джойстики подключить , без клавы.
У меня уже тесты прошли и все пашет - два STM32F030 +2 x nRF24L01 + джойстик NES .
Начинаю ковырять сторону джойстика на предмет прожорливости ...