X-Git-Url: https://git.friedersdorff.com/?a=blobdiff_plain;f=tmk_core%2Fprotocol%2Fadb.c;h=3600595121ce1b606e5ba66eeb08026a393842a7;hb=7f7b7ffdc21361a9760fdc006b070787b1aaaa00;hp=164255efaeccf25b63c2a0cbbafb3d890b4317e8;hpb=230ed4bdef855202a4c340fe645f05e2ca124521;p=max%2Ftmk_keyboard.git diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c index 164255ef..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 @@ -92,84 +93,167 @@ uint16_t adb_host_kbd_recv(uint8_t addr) } #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; + buf[n/8] <<= 1; + if ((130 - lo) < (lo - hi)) { + buf[n/8] |= 1; } - else if (n == 17) { - sei(); - return -20; - } - } - 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; } -void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) +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_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { cli(); attention(); - send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg); + 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 addr, uint8_t led) {