Squashed 'tmk_core/' changes from b9e0ea0..caca2c0
caca2c0 Add mouse support to ADB 5b0835a Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8' f2f7556 Remove unneeded tap delays #201 8124195 Fix URL of HID Usage Tables pdf 0bb4679 Fix typo of doc/keycode.txt b24fa1a Fix handling of consumer usage #199 6ae1a3d Improve anti-ghosting behavior for fast typing a4c9763 Fix dfu-programmer parameters b62b3f2 Move ring_buffer.h file 6ec424f Fix debug print 502fb0c Fix ibm4704 protocol with using interrupt git-subtree-dir: tmk_core git-subtree-split: caca2c01553394d959550034c817520d575c7fa0
This commit is contained in:
		
							parent
							
								
									1fe4406f37
								
							
						
					
					
						commit
						4d116a04e9
					
				@ -518,7 +518,12 @@ bool is_tap_key(keypos_t key)
 | 
				
			|||||||
        case ACT_RMODS_TAP:
 | 
					        case ACT_RMODS_TAP:
 | 
				
			||||||
        case ACT_LAYER_TAP:
 | 
					        case ACT_LAYER_TAP:
 | 
				
			||||||
        case ACT_LAYER_TAP_EXT:
 | 
					        case ACT_LAYER_TAP_EXT:
 | 
				
			||||||
            return true;
 | 
					            switch (action.layer_tap.code) {
 | 
				
			||||||
 | 
					                case 0x00 ... 0xdf:
 | 
				
			||||||
 | 
					                case OP_TAP_TOGGLE:
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
        case ACT_MACRO:
 | 
					        case ACT_MACRO:
 | 
				
			||||||
        case ACT_FUNCTION:
 | 
					        case ACT_FUNCTION:
 | 
				
			||||||
            if (action.func.opt & FUNC_TAP) { return true; }
 | 
					            if (action.func.opt & FUNC_TAP) { return true; }
 | 
				
			||||||
 | 
				
			|||||||
@ -70,13 +70,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||||||
 * 1001|oopp|BBBB BBBB   8-bit Bitwise Operation???
 | 
					 * 1001|oopp|BBBB BBBB   8-bit Bitwise Operation???
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * ACT_LAYER_TAP(101x):
 | 
					 * ACT_LAYER_TAP(101x):
 | 
				
			||||||
 * 101E|LLLL| keycode    On/Off with tap key
 | 
					 * 101E|LLLL| keycode    On/Off with tap key    (0x00-DF)[TAP]
 | 
				
			||||||
 * 101E|LLLL|1110 mods   On/Off with modifiers(0xE0-EF)
 | 
					 * 101E|LLLL|1110 mods   On/Off with modifiers  (0xE0-EF)[NOT TAP]
 | 
				
			||||||
 * 101E|LLLL|1111 0000   Invert with tap toggle(0xF0)
 | 
					 * 101E|LLLL|1111 0000   Invert with tap toggle (0xF0)   [TAP]
 | 
				
			||||||
 * 101E|LLLL|1111 0001   On/Off
 | 
					 * 101E|LLLL|1111 0001   On/Off                 (0xF1)   [NOT TAP]
 | 
				
			||||||
 * 101E|LLLL|1111 0010   Off/On
 | 
					 * 101E|LLLL|1111 0010   Off/On                 (0xF2)   [NOT TAP]
 | 
				
			||||||
 * 101E|LLLL|1111 0011   Set/Clear
 | 
					 * 101E|LLLL|1111 0011   Set/Clear              (0xF3)   [NOT TAP]
 | 
				
			||||||
 * 101E|LLLL|1111 xxxx   Reserved(0xF4-FF)
 | 
					 * 101E|LLLL|1111 xxxx   Reserved               (0xF4-FF)
 | 
				
			||||||
 *   ELLLL: layer 0-31(E: extra bit for layer 16-31)
 | 
					 *   ELLLL: layer 0-31(E: extra bit for layer 16-31)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||||||
#ifdef SERIAL_MOUSE_ENABLE
 | 
					#ifdef SERIAL_MOUSE_ENABLE
 | 
				
			||||||
#include "serial_mouse.h"
 | 
					#include "serial_mouse.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef ADB_MOUSE_ENABLE
 | 
				
			||||||
 | 
					#include "adb.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef MATRIX_HAS_GHOST
 | 
					#ifdef MATRIX_HAS_GHOST
 | 
				
			||||||
@ -69,6 +72,9 @@ void keyboard_init(void)
 | 
				
			|||||||
#ifdef SERIAL_MOUSE_ENABLE
 | 
					#ifdef SERIAL_MOUSE_ENABLE
 | 
				
			||||||
    serial_mouse_init();
 | 
					    serial_mouse_init();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef ADB_MOUSE_ENABLE
 | 
				
			||||||
 | 
					    adb_mouse_init();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef BOOTMAGIC_ENABLE
 | 
					#ifdef BOOTMAGIC_ENABLE
 | 
				
			||||||
@ -87,6 +93,9 @@ void keyboard_init(void)
 | 
				
			|||||||
void keyboard_task(void)
 | 
					void keyboard_task(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static matrix_row_t matrix_prev[MATRIX_ROWS];
 | 
					    static matrix_row_t matrix_prev[MATRIX_ROWS];
 | 
				
			||||||
 | 
					#ifdef MATRIX_HAS_GHOST
 | 
				
			||||||
 | 
					    static matrix_row_t matrix_ghost[MATRIX_ROWS];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    static uint8_t led_status = 0;
 | 
					    static uint8_t led_status = 0;
 | 
				
			||||||
    matrix_row_t matrix_row = 0;
 | 
					    matrix_row_t matrix_row = 0;
 | 
				
			||||||
    matrix_row_t matrix_change = 0;
 | 
					    matrix_row_t matrix_change = 0;
 | 
				
			||||||
@ -96,13 +105,21 @@ void keyboard_task(void)
 | 
				
			|||||||
        matrix_row = matrix_get_row(r);
 | 
					        matrix_row = matrix_get_row(r);
 | 
				
			||||||
        matrix_change = matrix_row ^ matrix_prev[r];
 | 
					        matrix_change = matrix_row ^ matrix_prev[r];
 | 
				
			||||||
        if (matrix_change) {
 | 
					        if (matrix_change) {
 | 
				
			||||||
            if (debug_matrix) matrix_print();
 | 
					 | 
				
			||||||
#ifdef MATRIX_HAS_GHOST
 | 
					#ifdef MATRIX_HAS_GHOST
 | 
				
			||||||
            if (has_ghost_in_row(r)) {
 | 
					            if (has_ghost_in_row(r)) {
 | 
				
			||||||
                matrix_prev[r] = matrix_row;
 | 
					                /* Keep track of whether ghosted status has changed for
 | 
				
			||||||
 | 
					                 * debugging. But don't update matrix_prev until un-ghosted, or
 | 
				
			||||||
 | 
					                 * the last key would be lost.
 | 
				
			||||||
 | 
					                 */
 | 
				
			||||||
 | 
					                if (debug_matrix && matrix_ghost[r] != matrix_row) {
 | 
				
			||||||
 | 
					                    matrix_print();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                matrix_ghost[r] = matrix_row;
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            matrix_ghost[r] = matrix_row;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					            if (debug_matrix) matrix_print();
 | 
				
			||||||
            for (uint8_t c = 0; c < MATRIX_COLS; c++) {
 | 
					            for (uint8_t c = 0; c < MATRIX_COLS; c++) {
 | 
				
			||||||
                if (matrix_change & ((matrix_row_t)1<<c)) {
 | 
					                if (matrix_change & ((matrix_row_t)1<<c)) {
 | 
				
			||||||
                    action_exec((keyevent_t){
 | 
					                    action_exec((keyevent_t){
 | 
				
			||||||
@ -136,6 +153,10 @@ MATRIX_LOOP_END:
 | 
				
			|||||||
        serial_mouse_task();
 | 
					        serial_mouse_task();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ADB_MOUSE_ENABLE
 | 
				
			||||||
 | 
					        adb_mouse_task();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // update LED
 | 
					    // update LED
 | 
				
			||||||
    if (led_status != host_keyboard_leds()) {
 | 
					    if (led_status != host_keyboard_leds()) {
 | 
				
			||||||
        led_status = host_keyboard_leds();
 | 
					        led_status = host_keyboard_leds();
 | 
				
			||||||
 | 
				
			|||||||
@ -131,7 +131,7 @@ static action_t keycode_to_action(uint8_t keycode)
 | 
				
			|||||||
        case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
 | 
					        case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
 | 
				
			||||||
            action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
 | 
					            action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
 | 
					        case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
 | 
				
			||||||
            action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
 | 
					            action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case KC_MS_UP ... KC_MS_ACCEL2:
 | 
					        case KC_MS_UP ... KC_MS_ACCEL2:
 | 
				
			||||||
 | 
				
			|||||||
@ -174,7 +174,7 @@ KC_CLEAR_AGAIN                      A2 Keyboard Clear/Again
 | 
				
			|||||||
KC_CRSEL                            A3 Keyboard CrSel/Props
 | 
					KC_CRSEL                            A3 Keyboard CrSel/Props
 | 
				
			||||||
KC_EXSEL                            A4 Keyboard ExSel
 | 
					KC_EXSEL                            A4 Keyboard ExSel
 | 
				
			||||||
/* Modifiers */
 | 
					/* Modifiers */
 | 
				
			||||||
KC_LCTRL            KC_LCTRL        E0 Keyboard LeftControl
 | 
					KC_LCTRL            KC_LCTL         E0 Keyboard LeftControl
 | 
				
			||||||
KC_LSHIFT           KC_LSFT         E1 Keyboard LeftShift
 | 
					KC_LSHIFT           KC_LSFT         E1 Keyboard LeftShift
 | 
				
			||||||
KC_LALT                             E2 Keyboard LeftAlt
 | 
					KC_LALT                             E2 Keyboard LeftAlt
 | 
				
			||||||
KC_LGUI                             E3 Keyboard Left GUI(Windows/Apple/Meta key)
 | 
					KC_LGUI                             E3 Keyboard Left GUI(Windows/Apple/Meta key)
 | 
				
			||||||
 | 
				
			|||||||
@ -198,7 +198,7 @@ There are 8 modifiers which has discrimination between left and right.
 | 
				
			|||||||
 See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes.
 | 
					 See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 In regard to implementation side most of keycodes are identical with [HID usage][HID_usage](pdf) sent to host for real and some virtual keycodes are defined to support special actions.
 | 
					 In regard to implementation side most of keycodes are identical with [HID usage][HID_usage](pdf) sent to host for real and some virtual keycodes are defined to support special actions.
 | 
				
			||||||
[HID_usage]: http://www.usb.org/developers/devclass_docs/Hut1_11.pdf
 | 
					[HID_usage]: http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -46,5 +46,9 @@ ifdef SERIAL_MOUSE_USE_UART
 | 
				
			|||||||
    SRC += $(PROTOCOL_DIR)/serial_uart.c
 | 
					    SRC += $(PROTOCOL_DIR)/serial_uart.c
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifdef ADB_MOUSE_ENABLE
 | 
				
			||||||
 | 
						 OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Search Path
 | 
					# Search Path
 | 
				
			||||||
VPATH += $(TMK_DIR)/protocol
 | 
					VPATH += $(TMK_DIR)/protocol
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@ static inline void place_bit1(void);
 | 
				
			|||||||
static inline void send_byte(uint8_t data);
 | 
					static inline void send_byte(uint8_t data);
 | 
				
			||||||
static inline uint16_t wait_data_lo(uint16_t us);
 | 
					static inline uint16_t wait_data_lo(uint16_t us);
 | 
				
			||||||
static inline uint16_t wait_data_hi(uint16_t us);
 | 
					static inline uint16_t wait_data_hi(uint16_t us);
 | 
				
			||||||
 | 
					static inline uint16_t adb_host_dev_recv(uint8_t device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void adb_host_init(void)
 | 
					void adb_host_init(void)
 | 
				
			||||||
@ -121,12 +122,33 @@ bool adb_host_psw(void)
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// [from Apple IIgs Hardware Reference Second Edition]
 | 
					// [from Apple IIgs Hardware Reference Second Edition]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    ADDR_KEYB  = 0x20,
 | 
				
			||||||
 | 
					    ADDR_MOUSE = 0x30
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t adb_host_kbd_recv(void)
 | 
					uint16_t adb_host_kbd_recv(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return adb_host_dev_recv(ADDR_KEYB);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ADB_MOUSE_ENABLE
 | 
				
			||||||
 | 
					void adb_mouse_init(void) {
 | 
				
			||||||
 | 
						    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t adb_host_mouse_recv(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return adb_host_dev_recv(ADDR_MOUSE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint16_t adb_host_dev_recv(uint8_t device)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint16_t data = 0;
 | 
					    uint16_t data = 0;
 | 
				
			||||||
    cli();
 | 
					    cli();
 | 
				
			||||||
    attention();
 | 
					    attention();
 | 
				
			||||||
    send_byte(0x2C);            // Addr:Keyboard(0010), Cmd:Talk(11), Register0(00)
 | 
					    send_byte(device|0x0C);     // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
 | 
				
			||||||
    place_bit0();               // Stopbit(0)
 | 
					    place_bit0();               // Stopbit(0)
 | 
				
			||||||
    if (!wait_data_hi(500)) {    // Service Request(310us Adjustable Keyboard): just ignored
 | 
					    if (!wait_data_hi(500)) {    // Service Request(310us Adjustable Keyboard): just ignored
 | 
				
			||||||
        sei();
 | 
					        sei();
 | 
				
			||||||
 | 
				
			|||||||
@ -56,7 +56,11 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
				
			|||||||
void     adb_host_init(void);
 | 
					void     adb_host_init(void);
 | 
				
			||||||
bool     adb_host_psw(void);
 | 
					bool     adb_host_psw(void);
 | 
				
			||||||
uint16_t adb_host_kbd_recv(void);
 | 
					uint16_t adb_host_kbd_recv(void);
 | 
				
			||||||
 | 
					uint16_t adb_host_mouse_recv(void);
 | 
				
			||||||
void     adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
 | 
					void     adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
 | 
				
			||||||
void     adb_host_kbd_led(uint8_t led);
 | 
					void     adb_host_kbd_led(uint8_t led);
 | 
				
			||||||
 | 
					void     adb_mouse_task(void);
 | 
				
			||||||
 | 
					void     adb_mouse_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
 | 
				
			|||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <util/delay.h>
 | 
					#include <util/delay.h>
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "ring_buffer.h"
 | 
				
			||||||
#include "ibm4704.h"
 | 
					#include "ibm4704.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,7 +21,9 @@ uint8_t ibm4704_error = 0;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void ibm4704_init(void)
 | 
					void ibm4704_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    inhibit();
 | 
					    IBM4704_INT_INIT();
 | 
				
			||||||
 | 
					    IBM4704_INT_ON();
 | 
				
			||||||
 | 
					    idle();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@ -47,6 +50,8 @@ uint8_t ibm4704_send(uint8_t data)
 | 
				
			|||||||
    bool parity = true; // odd parity
 | 
					    bool parity = true; // odd parity
 | 
				
			||||||
    ibm4704_error = 0;
 | 
					    ibm4704_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IBM4704_INT_OFF();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Request to send */
 | 
					    /* Request to send */
 | 
				
			||||||
    idle();
 | 
					    idle();
 | 
				
			||||||
    clock_lo();
 | 
					    clock_lo();
 | 
				
			||||||
@ -57,7 +62,6 @@ uint8_t ibm4704_send(uint8_t data)
 | 
				
			|||||||
    /* Data bit */
 | 
					    /* Data bit */
 | 
				
			||||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
					    for (uint8_t i = 0; i < 8; i++) {
 | 
				
			||||||
        WAIT(clock_hi, 100, 0x40+i);
 | 
					        WAIT(clock_hi, 100, 0x40+i);
 | 
				
			||||||
        //_delay_us(5);
 | 
					 | 
				
			||||||
        if (data&(1<<i)) {
 | 
					        if (data&(1<<i)) {
 | 
				
			||||||
            parity = !parity;
 | 
					            parity = !parity;
 | 
				
			||||||
            data_hi();
 | 
					            data_hi();
 | 
				
			||||||
@ -79,28 +83,25 @@ uint8_t ibm4704_send(uint8_t data)
 | 
				
			|||||||
    /* End */
 | 
					    /* End */
 | 
				
			||||||
    WAIT(data_lo, 100, 0x36);
 | 
					    WAIT(data_lo, 100, 0x36);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inhibit();
 | 
					    idle();
 | 
				
			||||||
    _delay_us(200); // wait to recover clock to hi
 | 
					    IBM4704_INT_ON();
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
ERROR:
 | 
					ERROR:
 | 
				
			||||||
    inhibit();
 | 
					    idle();
 | 
				
			||||||
    if (ibm4704_error >= 0x30) {
 | 
					    if (ibm4704_error > 0x30) {
 | 
				
			||||||
        xprintf("x%02X ", ibm4704_error);
 | 
					        xprintf("S:%02X ", ibm4704_error);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    _delay_us(200); // wait to recover clock to hi
 | 
					    IBM4704_INT_ON();
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* receive data when host want else inhibit communication */
 | 
					/* wait forever to receive data */
 | 
				
			||||||
uint8_t ibm4704_recv_response(void)
 | 
					uint8_t ibm4704_recv_response(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // 250 * 100us(wait start bit in ibm4704_recv)
 | 
					    while (!rbuf_has_data()) {
 | 
				
			||||||
    uint8_t data = 0;
 | 
					        _delay_ms(1);
 | 
				
			||||||
    uint8_t try = 250;
 | 
					    }
 | 
				
			||||||
    do {
 | 
					    return rbuf_dequeue();
 | 
				
			||||||
        data = ibm4704_recv();
 | 
					 | 
				
			||||||
    } while (try-- && ibm4704_error);
 | 
					 | 
				
			||||||
    return data;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@ -121,49 +122,69 @@ Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
 | 
				
			|||||||
*/
 | 
					*/
 | 
				
			||||||
uint8_t ibm4704_recv(void)
 | 
					uint8_t ibm4704_recv(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint8_t data = 0;
 | 
					    if (rbuf_has_data()) {
 | 
				
			||||||
    bool parity = true;    // odd parity
 | 
					        return rbuf_dequeue();
 | 
				
			||||||
    ibm4704_error = IBM4704_ERR_NONE;
 | 
					    } else {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
    idle();
 | 
					 | 
				
			||||||
    _delay_us(5);   // wait for line settles
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* start bit */
 | 
					 | 
				
			||||||
    WAIT(clock_lo, 100, 0x11); // wait for keyboard to send
 | 
					 | 
				
			||||||
    WAIT(data_hi, 100, 0x12);  // can be delayed that long
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    WAIT(clock_hi, 100, 0x13); // first rising edge which can take longer
 | 
					 | 
				
			||||||
    /* data */
 | 
					 | 
				
			||||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
					 | 
				
			||||||
        WAIT(clock_hi, 100, 0x20+i);
 | 
					 | 
				
			||||||
        //_delay_us(5);
 | 
					 | 
				
			||||||
        if (data_in()) {
 | 
					 | 
				
			||||||
            parity = !parity;
 | 
					 | 
				
			||||||
            data |= (1<<i);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        WAIT(clock_lo, 150, 0x28+i);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
    /* parity */
 | 
					
 | 
				
			||||||
    WAIT(clock_hi, 100, 0x17);
 | 
					ISR(IBM4704_INT_VECT)
 | 
				
			||||||
    if (data_in() != parity) {
 | 
					{
 | 
				
			||||||
        ibm4704_error = IBM4704_ERR_PARITY;
 | 
					    static enum {
 | 
				
			||||||
        goto ERROR;
 | 
					        INIT, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY,
 | 
				
			||||||
    }
 | 
					    } state = INIT;
 | 
				
			||||||
    WAIT(clock_lo, 150, 0x18);
 | 
					    // LSB first
 | 
				
			||||||
 | 
					    static uint8_t data = 0;
 | 
				
			||||||
    /* stop bit */
 | 
					    // Odd parity
 | 
				
			||||||
    WAIT(clock_hi, 100, 0x19);
 | 
					    static uint8_t parity = false;
 | 
				
			||||||
    WAIT(data_lo, 1, 0x19);
 | 
					
 | 
				
			||||||
 | 
					    ibm4704_error = 0;
 | 
				
			||||||
    inhibit();
 | 
					    // return unless falling edge
 | 
				
			||||||
    _delay_us(200); // wait to recover clock to hi
 | 
					    if (clock_in()) { goto RETURN; }    // why this occurs?
 | 
				
			||||||
    return data;
 | 
					
 | 
				
			||||||
ERROR:
 | 
					    state++;
 | 
				
			||||||
    if (ibm4704_error > 0x12) {
 | 
					    switch (state) {
 | 
				
			||||||
        xprintf("x%02X ", ibm4704_error);
 | 
					        case START:
 | 
				
			||||||
    }
 | 
					            // Data:Low
 | 
				
			||||||
    inhibit();
 | 
					            WAIT(data_hi, 10, state);
 | 
				
			||||||
    _delay_us(200); // wait to recover clock to hi
 | 
					            break;
 | 
				
			||||||
    return -1;
 | 
					        case BIT0:
 | 
				
			||||||
 | 
					        case BIT1:
 | 
				
			||||||
 | 
					        case BIT2:
 | 
				
			||||||
 | 
					        case BIT3:
 | 
				
			||||||
 | 
					        case BIT4:
 | 
				
			||||||
 | 
					        case BIT5:
 | 
				
			||||||
 | 
					        case BIT6:
 | 
				
			||||||
 | 
					        case BIT7:
 | 
				
			||||||
 | 
					            data >>= 1;
 | 
				
			||||||
 | 
					            if (data_in()) {
 | 
				
			||||||
 | 
					                data |= 0x80;
 | 
				
			||||||
 | 
					                parity = !parity;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case PARITY:
 | 
				
			||||||
 | 
					            if (data_in()) {
 | 
				
			||||||
 | 
					                parity = !parity;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (!parity)
 | 
				
			||||||
 | 
					                goto ERROR;
 | 
				
			||||||
 | 
					            rbuf_enqueue(data);
 | 
				
			||||||
 | 
					            ibm4704_error = IBM4704_ERR_NONE;
 | 
				
			||||||
 | 
					            goto DONE;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            goto ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    goto RETURN;
 | 
				
			||||||
 | 
					ERROR:
 | 
				
			||||||
 | 
					    ibm4704_error = state;
 | 
				
			||||||
 | 
					    while (ibm4704_send(0xFE)) _delay_ms(1); // resend
 | 
				
			||||||
 | 
					    xprintf("R:%02X%02X\n", state, data);
 | 
				
			||||||
 | 
					DONE:
 | 
				
			||||||
 | 
					    state = INIT;
 | 
				
			||||||
 | 
					    data = 0;
 | 
				
			||||||
 | 
					    parity = false;
 | 
				
			||||||
 | 
					RETURN:
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,10 @@ ifdef MOUSEKEY_ENABLE
 | 
				
			|||||||
    SRC += $(PJRC_DIR)/usb_mouse.c
 | 
					    SRC += $(PJRC_DIR)/usb_mouse.c
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifdef ADB_MOUSE_ENABLE
 | 
				
			||||||
 | 
					    SRC += $(PJRC_DIR)/usb_mouse.c
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifdef PS2_MOUSE_ENABLE
 | 
					ifdef PS2_MOUSE_ENABLE
 | 
				
			||||||
    SRC += $(PJRC_DIR)/usb_mouse.c
 | 
					    SRC += $(PJRC_DIR)/usb_mouse.c
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										53
									
								
								ring_buffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								ring_buffer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					#ifndef RING_BUFFER_H
 | 
				
			||||||
 | 
					#define RING_BUFFER_H
 | 
				
			||||||
 | 
					/*--------------------------------------------------------------------
 | 
				
			||||||
 | 
					 * Ring buffer to store scan codes from keyboard
 | 
				
			||||||
 | 
					 *------------------------------------------------------------------*/
 | 
				
			||||||
 | 
					#define RBUF_SIZE 32
 | 
				
			||||||
 | 
					static uint8_t rbuf[RBUF_SIZE];
 | 
				
			||||||
 | 
					static uint8_t rbuf_head = 0;
 | 
				
			||||||
 | 
					static uint8_t rbuf_tail = 0;
 | 
				
			||||||
 | 
					static inline void rbuf_enqueue(uint8_t data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t sreg = SREG;
 | 
				
			||||||
 | 
					    cli();
 | 
				
			||||||
 | 
					    uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
 | 
				
			||||||
 | 
					    if (next != rbuf_tail) {
 | 
				
			||||||
 | 
					        rbuf[rbuf_head] = data;
 | 
				
			||||||
 | 
					        rbuf_head = next;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        print("rbuf: full\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SREG = sreg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline uint8_t rbuf_dequeue(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t val = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t sreg = SREG;
 | 
				
			||||||
 | 
					    cli();
 | 
				
			||||||
 | 
					    if (rbuf_head != rbuf_tail) {
 | 
				
			||||||
 | 
					        val = rbuf[rbuf_tail];
 | 
				
			||||||
 | 
					        rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SREG = sreg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline bool rbuf_has_data(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t sreg = SREG;
 | 
				
			||||||
 | 
					    cli();
 | 
				
			||||||
 | 
					    bool has_data = (rbuf_head != rbuf_tail);
 | 
				
			||||||
 | 
					    SREG = sreg;
 | 
				
			||||||
 | 
					    return has_data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline void rbuf_clear(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t sreg = SREG;
 | 
				
			||||||
 | 
					    cli();
 | 
				
			||||||
 | 
					    rbuf_head = rbuf_tail = 0;
 | 
				
			||||||
 | 
					    SREG = sreg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* RING_BUFFER_H */
 | 
				
			||||||
							
								
								
									
										6
									
								
								rules.mk
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								rules.mk
									
									
									
									
									
								
							@ -440,7 +440,11 @@ flip-ee: $(TARGET).hex $(TARGET).eep
 | 
				
			|||||||
	$(REMOVE) $(TARGET)eep.hex
 | 
						$(REMOVE) $(TARGET)eep.hex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dfu-ee: $(TARGET).hex $(TARGET).eep
 | 
					dfu-ee: $(TARGET).hex $(TARGET).eep
 | 
				
			||||||
	dfu-programmer $(MCU) eeprom-flash $(TARGET).eep
 | 
					ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
 | 
				
			||||||
 | 
						dfu-programmer $(MCU) flash --eeprom $(TARGET).eep
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
						dfu-programmer $(MCU) flash-eeprom $(TARGET).eep
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
	dfu-programmer $(MCU) reset
 | 
						dfu-programmer $(MCU) reset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user