//---------------------------------------------------------------------------
// Низкоуровневые функции протокола PS/2
#define ps2_setClock0() { PORTD.PS2_CLOCK = 0; prepared_ddrd |= (1 << PS2_CLOCK); DDRD.PS2_CLOCK = 1; }
#define ps2_setClock1() { prepared_ddrd &= ~(1 << PS2_CLOCK); DDRD.PS2_CLOCK = 0; }
// DataIn и DataOut не нужны - выходы с ОК, 0==Out, In==1
#define ps2_setData0() { PORTD.PS2_DATA = 0; prepared_ddrd |= (1 << PS2_DATA); DDRD.PS2_DATA = 1; }
#define ps2_setData1() { prepared_ddrd &= ~(1 << PS2_DATA); DDRD.PS2_DATA = 0; }
//#define ps2_setData0() { PORTD.PS2_DATA = 0; }
//#define ps2_setData1() { PORTD.PS2_DATA = 1; }
#define ps2_waitClock0() { while(PIND.PS2_CLOCK); }
#define ps2_waitClock1() { while(PIND.PS2_CLOCK==0); }
#define ps2_waitClock() { ps2_waitClock1(); ps2_waitClock0(); }
#define ps2_data() PIND.PS2_DATA
#define ps2_wait() (PIND.PS2_DATA || PIND.PS2_CLOCK)
и вот:
// Отправить байт клавиатуре
// Вход: v_a - байт
void ps2_send() {
// ps2_setDataOut();
ps2_setData0();
delay_us(20);
ps2_setClock1();
delay_us(10);
v_j=0;
ps2_waitClock0();
for(v_i=0; v_i<8; v_i++) {
delay_us(10);
if(v_a&1) { ps2_setData1(); v_j++; } else ps2_setData0();
v_a >>= 1;
ps2_waitClock();
#asm
WDR
#endasm
}
// Бит четности
delay_us(10);
if(v_j&1) { ps2_setData0(); } else { ps2_setData1(); }
ps2_waitClock();
// Стоповый бит
delay_us(10);
ps2_setData1();
ps2_waitClock();
// Пропуск ACK
// ps2_setDataIn();
// Лишний waitClock, из-за него не работали старые клавы
// ps2_waitClock();
if(ps2_data()) reboot(); // Ошибка клавиатуры. Перезагружаем её.
ps2_waitClock1();
ps2_transmitMode();
#asm
WDR
#endasm
}
[свернуть]