]> git.friedersdorff.com Git - max/tmk_keyboard.git/blobdiff - tmk_core/protocol/ibmpc.c
Add my keymap
[max/tmk_keyboard.git] / tmk_core / protocol / ibmpc.c
index cb612eb1c08490a53f5368b9b638054496e3cf84..0e94e301214c35078e7a26db2f3603d31d9feecc 100644 (file)
@@ -105,12 +105,13 @@ int16_t ibmpc_host_send(uint8_t data)
 
     /* terminate a transmission if we have */
     inhibit();
-    wait_us(100); // 100us [4]p.13, [5]p.50
+    wait_us(100);    // [5]p.54
 
     /* 'Request to Send' and Start bit */
     data_lo();
-    clock_hi();
-    WAIT(clock_lo, 10000, 1);   // 10ms [5]p.50
+    wait_us(100);
+    clock_hi();     // [5]p.54 [clock low]>100us [5]p.50
+    WAIT(clock_lo, 10000, 1);   // [5]p.53, -10ms [5]p.50
 
     /* Data bit[2-9] */
     for (uint8_t i = 0; i < 8; i++) {
@@ -134,15 +135,18 @@ int16_t ibmpc_host_send(uint8_t data)
     /* Stop bit */
     wait_us(15);
     data_hi();
+    WAIT(clock_hi, 50, 6);
+    if (ibmpc_protocol == IBMPC_PROTOCOL_AT_Z150) { goto RECV; }
+    WAIT(clock_lo, 50, 7);
 
     /* Ack */
-    WAIT(data_lo, 50, 6);
-    WAIT(clock_lo, 50, 7);
+    WAIT(data_lo, 50, 8);
 
     /* wait for idle state */
-    WAIT(clock_hi, 50, 8);
-    WAIT(data_hi, 50, 9);
+    WAIT(clock_hi, 50, 9);
+    WAIT(data_hi, 50, 10);
 
+RECV:
     // clear buffer to get response correctly
     recv_data = 0xFFFF;
     ibmpc_host_isr_clear();
@@ -208,6 +212,7 @@ int16_t ibmpc_host_recv(void)
         }
     }
 
+    //dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0;
     dprintf("r%02X ", ret);
     return ret;
 }
@@ -225,10 +230,15 @@ int16_t ibmpc_host_recv_response(void)
 
 void ibmpc_host_isr_clear(void)
 {
+    ibmpc_isr_debug = 0;
+    ibmpc_protocol = 0;
+    ibmpc_error = 0;
     isr_state = 0x8000;
     recv_data = 0xFFFF;
 }
 
+#define LO8(w)  (*((uint8_t *)&(w)))
+#define HI8(w)  (*(((uint8_t *)&(w))+1))
 // NOTE: With this ISR data line can be read within 2us after clock falling edge.
 // To read data line early as possible:
 // write naked ISR with asembly code to read the line and call C func to do other job?
@@ -245,8 +255,8 @@ ISR(IBMPC_INT_VECT)
     if (isr_state == 0x8000) {
         timer_start = t;
     } else {
-        // should not take more than 1ms
-        if (timer_start != t && (uint8_t)(timer_start + 1) != t) {
+        // This gives 2.0ms at least before timeout
+        if ((uint8_t)(t - timer_start) >= 3) {
             ibmpc_isr_debug = isr_state;
             ibmpc_error = IBMPC_ERR_TIMEOUT;
             goto ERROR;
@@ -313,6 +323,7 @@ ISR(IBMPC_INT_VECT)
                     goto NEXT;
                 } else {
                     // XT_Clone-done
+                    ibmpc_isr_debug = isr_state;
                     isr_state = isr_state>>8;
                     ibmpc_protocol = IBMPC_PROTOCOL_XT_CLONE;
                     goto DONE;
@@ -338,6 +349,7 @@ ISR(IBMPC_INT_VECT)
                     goto NEXT;
                 } else {
                     // no stop bit: XT_IBM-done
+                    ibmpc_isr_debug = isr_state;
                     isr_state = isr_state>>8;
                     ibmpc_protocol = IBMPC_PROTOCOL_XT_IBM;
                     goto DONE;
@@ -349,11 +361,17 @@ ISR(IBMPC_INT_VECT)
         case 0b01010000:
         case 0b11010000:
             // AT-done
-            // DO NOT check stop bit. Zenith Z-150(AT) asserts stop bit as low for no reason.
-            // https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#zenith-z-150-beige
             // TODO: parity check?
+            ibmpc_isr_debug = isr_state;
+            // stop bit check
+            if (isr_state & 0x8000) {
+                ibmpc_protocol = IBMPC_PROTOCOL_AT;
+            } else {
+                // Zenith Z-150 AT(beige/white lable) asserts stop bit as low
+                // https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#zenith-z-150-beige
+                ibmpc_protocol = IBMPC_PROTOCOL_AT_Z150;
+            }
             isr_state = isr_state>>6;
-            ibmpc_protocol = IBMPC_PROTOCOL_AT;
             goto DONE;
             break;
         case 0b01100000:
@@ -379,7 +397,7 @@ DONE:
         ibmpc_error = IBMPC_ERR_FF;
         goto ERROR;
     }
-    if ((recv_data & 0xFF00) != 0xFF00) {
+    if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) {
         // buffer full
         ibmpc_error = IBMPC_ERR_FULL;
         goto ERROR;