Browse Source

Merge branch 'ibm4704_fix_protocol'

tmk 10 years ago
parent
commit
81137b7a61

+ 1 - 0
converter/ibm4704_usb/README.md

@@ -8,6 +8,7 @@ Keyboard initialization process takes a few seconds at start up. During that you
 Update
 Update
 ------
 ------
 2015/05/05  Added keymaps for 107-key, 77-key and 50-key. Thanks, orihalcon @ geekhack!
 2015/05/05  Added keymaps for 107-key, 77-key and 50-key. Thanks, orihalcon @ geekhack!
+2015/05/19  Fixed a protocol handling bug.
 
 
 
 
 
 

+ 3 - 3
converter/ibm4704_usb/config.h

@@ -51,9 +51,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define IBM4704_DATA_DDR    DDRD
 #define IBM4704_DATA_DDR    DDRD
 #define IBM4704_DATA_BIT    0
 #define IBM4704_DATA_BIT    0
 
 
-/* Pin interrupt on  rising edge */
-#define IBM4704_INT_INIT()  do { EICRA |= ((1<<ISC11)|(0<<ISC10)); } while (0)
-#define IBM4704_INT_ON()    do { EIMSK |=  (1<<INT1); } while (0)
+/* Pin interrupt on rising edge of clock */
+#define IBM4704_INT_INIT()  do { EICRA |= ((1<<ISC11)|(1<<ISC10)); } while (0)
+#define IBM4704_INT_ON()    do { EIFR |= (1<<INTF1); EIMSK |= (1<<INT1); } while (0)
 #define IBM4704_INT_OFF()   do { EIMSK &= ~(1<<INT1); } while (0)
 #define IBM4704_INT_OFF()   do { EIMSK &= ~(1<<INT1); } while (0)
 #define IBM4704_INT_VECT    INT1_vect
 #define IBM4704_INT_VECT    INT1_vect
 
 

+ 6 - 5
converter/ibm4704_usb/ibm4704.txt

@@ -57,15 +57,15 @@ Keyboard to Host
 ----------------
 ----------------
 Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
 Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
 
 
-            ____      __   __   __   __   __   __   __   __   __   ________
-    Clock       \____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
+            ____       __   __   __   __   __   __   __   __   __   _______
+    Clock       \_____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
                  ____ ____ ____ ____ ____ ____ ____ ____ ____ ____    
                  ____ ____ ____ ____ ____ ____ ____ ____ ____ ____    
     Data    ____/    X____X____X____X____X____X____X____X____X____X________
     Data    ____/    X____X____X____X____X____X____X____X____X____X________
                 Start   0    1    2    3    4    5    6    7    P  Stop
                 Start   0    1    2    3    4    5    6    7    P  Stop
 
 
 Start bit:  can be long as 300-350us.
 Start bit:  can be long as 300-350us.
 Inhibit:    Pull Data line down to inhibit keyboard to send.
 Inhibit:    Pull Data line down to inhibit keyboard to send.
-Timing:     Host reads bit while Clock is hi.
+Timing:     Host reads bit while Clock is hi.(rising edge)
 Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 
 
 
 
@@ -166,13 +166,14 @@ Data sent from host:
          |   `-----`--- scan code
          |   `-----`--- scan code
          `------------- enable bit(0: enable repeat, 1: enable break)
          `------------- enable bit(0: enable repeat, 1: enable break)
 
 
-    00-77   Enable repeat(78-7F: invalid scancode)
-    80-F7   Enable break(F8-FF: invalid scancode)
+    00-79   Enable repeat
+    80-F9   Enable break(FA-FF are used as other commands, see above.)
     FE      Resend(011ah) no need to use
     FE      Resend(011ah) no need to use
     FF      End(0114h) exits FC command mode.
     FF      End(0114h) exits FC command mode.
 
 
 Response from keyboard:
 Response from keyboard:
     FD      Out of bound - Invalid scancode
     FD      Out of bound - Invalid scancode
+    --      OK - No response means that command is accepted.
 
 
 Examples:
 Examples:
     To enable break code of all keys.
     To enable break code of all keys.

+ 13 - 17
converter/ibm4704_usb/matrix.c

@@ -67,35 +67,31 @@ uint8_t matrix_cols(void)
 
 
 static void enable_break(void)
 static void enable_break(void)
 {
 {
-    uint8_t ret;
     print("Enable break: ");
     print("Enable break: ");
     // valid scancode: 00-79h
     // valid scancode: 00-79h
     for (uint8_t code = 0; code < 0x7A; code++) {
     for (uint8_t code = 0; code < 0x7A; code++) {
-        while (ibm4704_send(0x80|code)) _delay_ms(1);
-        // get none when ok, get FD when out of bound
-        _delay_ms(5);
-        if ((ret = ibm4704_recv()) != 0xff) {
-            xprintf("c%02X:r%02X ", code, ret);
-        }
-        _delay_ms(1);
+        while (ibm4704_send(0x80|code)) _delay_ms(10);
+        _delay_ms(5);   // wait for response
+        // No response(FF) when ok, FD when out of bound
+        xprintf("s%02X:r%02X ", code, ibm4704_recv());
     }
     }
-    _delay_us(1000);
-    while (ibm4704_send(0xFF)) { _delay_ms(1); } // End
+    while (ibm4704_send(0xFF)) { _delay_ms(10); } // End
     print("End\n");
     print("End\n");
 }
 }
 
 
-void matrix_init(void)
-{
-    debug_enable = true;
 
 
+void matrix_setup(void)
+{
     ibm4704_init();
     ibm4704_init();
-    matrix_clear();
+}
 
 
-    _delay_ms(2000);    // wait for starting up debug console
+void matrix_init(void)
+{
+    debug_enable = true;
 
 
     print("IBM 4704 converter\n");
     print("IBM 4704 converter\n");
-    while (ibm4704_send(0xFE)) _delay_ms(1);    // resend
-    _delay_ms(5);
+    matrix_clear();
+    _delay_ms(2000);    // wait for keyboard starting up
     xprintf("Keyboard ID: %02X\n", ibm4704_recv());
     xprintf("Keyboard ID: %02X\n", ibm4704_recv());
     enable_break();
     enable_break();
 }
 }

+ 2 - 0
tmk_core/common/avr/suspend.c

@@ -85,6 +85,8 @@ void suspend_power_down(void)
     power_down(WDTO_15MS);
     power_down(WDTO_15MS);
 }
 }
 
 
+__attribute__ ((weak)) void matrix_power_up(void) {}
+__attribute__ ((weak)) void matrix_power_down(void) {}
 bool suspend_wakeup_condition(void)
 bool suspend_wakeup_condition(void)
 {
 {
     matrix_power_up();
     matrix_power_up();

+ 6 - 0
tmk_core/common/keyboard.c

@@ -62,6 +62,12 @@ static bool has_ghost_in_row(uint8_t row)
 #endif
 #endif
 
 
 
 
+__attribute__ ((weak)) void matrix_setup(void) {}
+void keyboard_setup(void)
+{
+    matrix_setup();
+}
+
 void keyboard_init(void)
 void keyboard_init(void)
 {
 {
     timer_init();
     timer_init();

+ 5 - 3
tmk_core/common/keyboard.h

@@ -58,13 +58,15 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
 }
 }
 
 
 
 
+/* it runs once at early stage of startup before keyboard_init. */
+void keyboard_setup(void);
+/* it runs once after initializing host side protocol, debug and MCU peripherals. */
 void keyboard_init(void);
 void keyboard_init(void);
+/* it runs repeatedly in main loop */
 void keyboard_task(void);
 void keyboard_task(void);
+/* it runs when host LED status is updated */
 void keyboard_set_leds(uint8_t leds);
 void keyboard_set_leds(uint8_t leds);
 
 
-__attribute__ ((weak)) void matrix_power_up(void) {}
-__attribute__ ((weak)) void matrix_power_down(void) {}
-
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 3 - 1
tmk_core/common/matrix.h

@@ -43,7 +43,9 @@ extern "C" {
 uint8_t matrix_rows(void);
 uint8_t matrix_rows(void);
 /* number of matrix columns */
 /* number of matrix columns */
 uint8_t matrix_cols(void);
 uint8_t matrix_cols(void);
-/* intialize matrix for scaning. should be called once. */
+/* should be called at early stage of startup before matrix_init.(optional) */
+void matrix_setup(void);
+/* intialize matrix for scaning. */
 void matrix_init(void);
 void matrix_init(void);
 /* scan all key states on matrix */
 /* scan all key states on matrix */
 uint8_t matrix_scan(void);
 uint8_t matrix_scan(void);

+ 22 - 23
tmk_core/protocol/ibm4704.c

@@ -21,9 +21,10 @@ uint8_t ibm4704_error = 0;
 
 
 void ibm4704_init(void)
 void ibm4704_init(void)
 {
 {
+    inhibit();  // keep keyboard from sending
     IBM4704_INT_INIT();
     IBM4704_INT_INIT();
     IBM4704_INT_ON();
     IBM4704_INT_ON();
-    idle();
+    idle();     // allow keyboard sending
 }
 }
 
 
 /*
 /*
@@ -104,51 +105,44 @@ uint8_t ibm4704_recv_response(void)
     return rbuf_dequeue();
     return rbuf_dequeue();
 }
 }
 
 
+uint8_t ibm4704_recv(void)
+{
+    if (rbuf_has_data()) {
+        return rbuf_dequeue();
+    } else {
+        return -1;
+    }
+}
+
 /*
 /*
 Keyboard to Host
 Keyboard to Host
 ----------------
 ----------------
 Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
 Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
 
 
-        ____      __   __   __   __   __   __   __   __   __   ________
-Clock       \____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
+        ____       __   __   __   __   __   __   __   __   __   _______
+Clock       \_____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
              ____ ____ ____ ____ ____ ____ ____ ____ ____ ____    
              ____ ____ ____ ____ ____ ____ ____ ____ ____ ____    
 Data    ____/    X____X____X____X____X____X____X____X____X____X________
 Data    ____/    X____X____X____X____X____X____X____X____X____X________
             Start   0    1    2    3    4    5    6    7    P  Stop
             Start   0    1    2    3    4    5    6    7    P  Stop
 
 
 Start bit:  can be long as 300-350us.
 Start bit:  can be long as 300-350us.
 Inhibit:    Pull Data line down to inhibit keyboard to send.
 Inhibit:    Pull Data line down to inhibit keyboard to send.
-Timing:     Host reads bit while Clock is hi.
+Timing:     Host reads bit while Clock is hi.(rising edge)
 Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 */
 */
-uint8_t ibm4704_recv(void)
-{
-    if (rbuf_has_data()) {
-        return rbuf_dequeue();
-    } else {
-        return -1;
-    }
-}
-
 ISR(IBM4704_INT_VECT)
 ISR(IBM4704_INT_VECT)
 {
 {
     static enum {
     static enum {
-        INIT, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY,
-    } state = INIT;
+        BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, STOP
+    } state = BIT0;
     // LSB first
     // LSB first
     static uint8_t data = 0;
     static uint8_t data = 0;
     // Odd parity
     // Odd parity
     static uint8_t parity = false;
     static uint8_t parity = false;
 
 
     ibm4704_error = 0;
     ibm4704_error = 0;
-    // return unless falling edge
-    if (clock_in()) { goto RETURN; }    // why this occurs?
 
 
-    state++;
     switch (state) {
     switch (state) {
-        case START:
-            // Data:Low
-            WAIT(data_hi, 10, state);
-            break;
         case BIT0:
         case BIT0:
         case BIT1:
         case BIT1:
         case BIT2:
         case BIT2:
@@ -169,6 +163,10 @@ ISR(IBM4704_INT_VECT)
             }
             }
             if (!parity)
             if (!parity)
                 goto ERROR;
                 goto ERROR;
+            break;
+        case STOP:
+            // Data:Low
+            WAIT(data_lo, 100, state);
             rbuf_enqueue(data);
             rbuf_enqueue(data);
             ibm4704_error = IBM4704_ERR_NONE;
             ibm4704_error = IBM4704_ERR_NONE;
             goto DONE;
             goto DONE;
@@ -176,13 +174,14 @@ ISR(IBM4704_INT_VECT)
         default:
         default:
             goto ERROR;
             goto ERROR;
     }
     }
+    state++;
     goto RETURN;
     goto RETURN;
 ERROR:
 ERROR:
     ibm4704_error = state;
     ibm4704_error = state;
     while (ibm4704_send(0xFE)) _delay_ms(1); // resend
     while (ibm4704_send(0xFE)) _delay_ms(1); // resend
     xprintf("R:%02X%02X\n", state, data);
     xprintf("R:%02X%02X\n", state, data);
 DONE:
 DONE:
-    state = INIT;
+    state = BIT0;
     data = 0;
     data = 0;
     parity = false;
     parity = false;
 RETURN:
 RETURN:

+ 7 - 2
tmk_core/protocol/lufa/lufa.c

@@ -544,7 +544,7 @@ int8_t sendchar(uint8_t c)
 /*******************************************************************************
 /*******************************************************************************
  * main
  * main
  ******************************************************************************/
  ******************************************************************************/
-static void SetupHardware(void)
+static void setup_mcu(void)
 {
 {
     /* Disable watchdog if enabled by bootloader/fuses */
     /* Disable watchdog if enabled by bootloader/fuses */
     MCUSR &= ~(1 << WDRF);
     MCUSR &= ~(1 << WDRF);
@@ -552,7 +552,10 @@ static void SetupHardware(void)
 
 
     /* Disable clock division */
     /* Disable clock division */
     clock_prescale_set(clock_div_1);
     clock_prescale_set(clock_div_1);
+}
 
 
+static void setup_usb(void)
+{
     // Leonardo needs. Without this USB device is not recognized.
     // Leonardo needs. Without this USB device is not recognized.
     USB_Disable();
     USB_Disable();
 
 
@@ -566,7 +569,9 @@ static void SetupHardware(void)
 int main(void)  __attribute__ ((weak));
 int main(void)  __attribute__ ((weak));
 int main(void)
 int main(void)
 {
 {
-    SetupHardware();
+    setup_mcu();
+    keyboard_setup();
+    setup_usb();
     sei();
     sei();
 
 
     /* wait for USB startup & debug output */
     /* wait for USB startup & debug output */

+ 2 - 0
tmk_core/protocol/pjrc/main.c

@@ -46,6 +46,8 @@ int main(void)
     // set for 16 MHz clock
     // set for 16 MHz clock
     CPU_PRESCALE(0);
     CPU_PRESCALE(0);
 
 
+    keyboard_setup();
+
     // Initialize the USB, and then wait for the host to set configuration.
     // Initialize the USB, and then wait for the host to set configuration.
     // If the Teensy is powered without a PC connected to the USB port,
     // If the Teensy is powered without a PC connected to the USB port,
     // this will wait forever.
     // this will wait forever.