X-Git-Url: https://git.friedersdorff.com/?a=blobdiff_plain;f=tmk_core%2Fprotocol%2Fadb.c;h=3600595121ce1b606e5ba66eeb08026a393842a7;hb=f8685ce694329529d93c4e3afb8aae25d7ec5959;hp=3f4e14bac47bf69f25d96b8400ff59ed91e0245d;hpb=d702fe7504753617911501d886c4e4e0a33d607f;p=max%2Ftmk_keyboard.git diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c index 3f4e14ba..36005951 100644 --- a/tmk_core/protocol/adb.c +++ b/tmk_core/protocol/adb.c @@ -1,5 +1,5 @@ /* -Copyright 2011 Jun WAKO +Copyright 2011-19 Jun WAKO Copyright 2013 Shay Green This software is licensed with a Modified BSD License. @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include "adb.h" +#include "print.h" // GCC doesn't inline functions normally @@ -86,97 +87,180 @@ bool adb_host_psw(void) * * */ -uint16_t adb_host_kbd_recv(void) +uint16_t adb_host_kbd_recv(uint8_t addr) { - return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); + return adb_host_talk(addr, ADB_REG_0); } #ifdef ADB_MOUSE_ENABLE +__attribute__ ((weak)) void adb_mouse_init(void) { - return; + return; } -uint16_t adb_host_mouse_recv(void) -{ - return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); +__attribute__ ((weak)) +void adb_mouse_task(void) { + return; } #endif -uint16_t adb_host_talk(uint8_t addr, uint8_t reg) +// This sends Talk command to read data from register and returns length of the data. +uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { - uint16_t data = 0; + for (int8_t i =0; i < len; i++) buf[i] = 0; + cli(); attention(); - send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg); + send_byte((addr<<4) | ADB_CMD_TALK | reg); place_bit0(); // Stopbit(0) + // TODO: Service Request(Srq): + // Device holds low part of comannd stopbit for 140-260us + // + // Command: + // ......._ ______________________ ___ ............_ ------- + // | | | | | | | + // Command | | | | | Data bytes | | + // ........|___| | 140-260 |__| |_............|___| + // |stop0 | Tlt Stop-to-Start |start1| |stop0 | + // + // Command without data: + // ......._ __________________________ + // | | + // Command | | + // ........|___| | 140-260 | + // |stop0 | Tlt Stop-to-Start | + // + // Service Request: + // ......._ ______ ___ ............_ ------- + // | 140-260 | | | | | | + // Command | Service Request | | | | Data bytes | | + // ........|___________________| |__| |_............|___| + // |stop0 | |start1| |stop0 | + // ......._ __________ + // | 140-260 | + // Command | Service Request | + // ........|___________________| + // |stop0 | + // This can be happened? + // ......._ ______________________ ___ ............_ ----- + // | | | | | | 140-260 | + // Command | | | | | Data bytes | Service Request | + // ........|___| | 140-260 |__| |_............|_________________| + // |stop0 | Tlt Stop-to-Start |start1| |stop0 | + // + // "Service requests are issued by the devices during a very specific time at the + // end of the reception of the command packet. + // If a device in need of service issues a service request, it must do so within + // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs." + // + // "A device sends a Service Request signal by holding the bus low during the low + // portion of the stop bit of any command or data transaction. The device must lengthen + // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15." + // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored + xprintf("R"); sei(); - return -30; // something wrong + return 0; } if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) sei(); - return 0; // No data to send + return 0; // No data from device(not error); + } + + // start bit(1) + if (!wait_data_hi(40)) { + xprintf("S"); + sei(); + return 0; + } + if (!wait_data_lo(100)) { + xprintf("s"); + sei(); + return 0; } - uint8_t n = 17; // start bit + 16 data bits + uint8_t n = 0; // bit count do { + // + // |<- bit_cell_max(130) ->| + // | |<- lo ->| + // | | |<-hi->| + // _______ + // | | | + // | 130-lo | lo-hi | + // |________| | + // uint8_t lo = (uint8_t) wait_data_hi(130); if (!lo) - goto error; + goto error; // no more bit or after stop bit uint8_t hi = (uint8_t) wait_data_lo(lo); if (!hi) - goto error; + goto error; // stop bit extedned by Srq? - hi = lo - hi; - lo = 130 - lo; + if (n/8 >= len) continue; // can't store in buf - data <<= 1; - if (lo < hi) { - data |= 1; - } - else if (n == 17) { - sei(); - return -20; + buf[n/8] <<= 1; + if ((130 - lo) < (lo - hi)) { + buf[n/8] |= 1; } } - while ( --n ); - - // Stop bit can't be checked normally since it could have service request lenghtening - // and its high state never goes low. - if (!wait_data_hi(351) || wait_data_lo(91)) { - sei(); - return -21; - } - sei(); - return data; + while ( ++n ); error: sei(); - return -n; + return n/8; +} + +uint16_t adb_host_talk(uint8_t addr, uint8_t reg) +{ + uint8_t len; + uint8_t buf[8]; + len = adb_host_talk_buf(addr, reg, buf, 8); + if (len != 2) return 0; + return (buf[0]<<8 | buf[1]); } -void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) +void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { cli(); attention(); - send_byte(cmd); + send_byte((addr<<4) | ADB_CMD_LISTEN | reg); place_bit0(); // Stopbit(0) + // TODO: Service Request _delay_us(200); // Tlt/Stop to Start place_bit1(); // Startbit(1) - send_byte(data_h); - send_byte(data_l); + for (int8_t i = 0; i < len; i++) { + send_byte(buf[i]); + //xprintf("%02X ", buf[i]); + } place_bit0(); // Stopbit(0); sei(); } +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) +{ + uint8_t buf[2] = { data_h, data_l }; + adb_host_listen_buf(addr, reg, buf, 2); +} + +void adb_host_flush(uint8_t addr) +{ + cli(); + attention(); + send_byte((addr<<4) | ADB_CMD_FLUSH); + place_bit0(); // Stopbit(0) + _delay_us(200); // Tlt/Stop to Start + sei(); +} + // send state of LEDs -void adb_host_kbd_led(uint8_t led) +void adb_host_kbd_led(uint8_t addr, uint8_t led) { - // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) - // send upper byte (not used) - // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: - adb_host_listen(0x2A,0,led&0x07); + // Listen Register2 + // upper byte: not used + // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock + adb_host_listen(addr, 2, 0, led & 0x07); } @@ -325,7 +409,7 @@ Commands bits commands ------------------------------------------------------ - - - - - 0 0 0 0 Send Request(reset all devices) + - - - - 0 0 0 0 Send Reset(reset all devices) A A A A 0 0 0 1 Flush(reset a device) - - - - 0 0 1 0 Reserved - - - - 0 0 1 1 Reserved @@ -433,6 +517,16 @@ Keyboard LEDs & state of keys(Register2) | +----------------------------- Delete +------------------------------- Reserved +Address, Handler ID and bits(Register3) + 1514131211 . . 8 7 . . . . . . 0 + | | | | | | | | | | | | | | | | + | | | | | | | | +-+-+-+-+-+-+-+- Handler ID + | | | | +-+-+-+----------------- Address + | | | +------------------------- 0 + | | +--------------------------- Service request enable(1 = enabled) + | +----------------------------- Exceptional event(alwyas 1 if not used) + +------------------------------- 0 + ADB Bit Cells bit cell time: 70-130us low part of bit0: 60-70% of bit cell