Fix bug on RAW2SCAN. Add work around for M0110A.
- Bug fix: Macro RAW2SCAN doesn't work and converted into static inline function. - Add Exceptional handling for M0110A arrow keys and calc keys. - Fix keymap.
This commit is contained in:
		
							parent
							
								
									d553289e7e
								
							
						
					
					
						commit
						f5f48c2a24
					
				
							
								
								
									
										457
									
								
								m0110.c
									
									
									
									
									
								
							
							
						
						
									
										457
									
								
								m0110.c
									
									
									
									
									
								
							@ -44,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline uint8_t raw2scan(uint8_t raw);
 | 
			
		||||
static inline uint8_t inquiry(void);
 | 
			
		||||
static inline uint8_t instant(void);
 | 
			
		||||
static inline void clock_lo(void);
 | 
			
		||||
@ -60,6 +61,241 @@ static inline void idle(void);
 | 
			
		||||
static inline void request(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WAIT_US(stat, us, err) do { \
 | 
			
		||||
    if (!wait_##stat(us)) { \
 | 
			
		||||
        m0110_error = err; \
 | 
			
		||||
        goto ERROR; \
 | 
			
		||||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define WAIT_MS(stat, ms, err) do { \
 | 
			
		||||
    uint16_t _ms = ms; \
 | 
			
		||||
    while (_ms) { \
 | 
			
		||||
        if (wait_##stat(1000)) { \
 | 
			
		||||
            break; \
 | 
			
		||||
        } \
 | 
			
		||||
        _ms--; \
 | 
			
		||||
    } \
 | 
			
		||||
    if (_ms == 0) { \
 | 
			
		||||
        m0110_error = err; \
 | 
			
		||||
        goto ERROR; \
 | 
			
		||||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void m0110_init(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data;
 | 
			
		||||
    idle();
 | 
			
		||||
    _delay_ms(1000);
 | 
			
		||||
 | 
			
		||||
    // Model Number
 | 
			
		||||
    // M0110 : 0x09  00001001 : model number 4 (100)
 | 
			
		||||
    // M0110A: 0x0B  00001011 : model number 5 (101)
 | 
			
		||||
    // M0110 & M0120: ???
 | 
			
		||||
    m0110_send(M0110_MODEL);
 | 
			
		||||
    data = m0110_recv();
 | 
			
		||||
    print("m0110_init model: "); phex(data); print("\n");
 | 
			
		||||
 | 
			
		||||
    m0110_send(M0110_TEST);
 | 
			
		||||
    data = m0110_recv();
 | 
			
		||||
    print("m0110_init test: "); phex(data); print("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_send(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
    request();
 | 
			
		||||
    WAIT_MS(clock_lo, 250, 1);  // keyboard may block long time
 | 
			
		||||
    for (uint8_t bit = 0x80; bit; bit >>= 1) {
 | 
			
		||||
        WAIT_US(clock_lo, 250, 3);
 | 
			
		||||
        if (data&bit) {
 | 
			
		||||
            data_hi();
 | 
			
		||||
        } else {
 | 
			
		||||
            data_lo();
 | 
			
		||||
        }
 | 
			
		||||
        WAIT_US(clock_hi, 200, 4);
 | 
			
		||||
    }
 | 
			
		||||
    _delay_us(100); // hold last bit for 80us
 | 
			
		||||
    idle();
 | 
			
		||||
    return 1;
 | 
			
		||||
ERROR:
 | 
			
		||||
    print("m0110_send err: "); phex(m0110_error); print("\n");
 | 
			
		||||
    _delay_ms(500);
 | 
			
		||||
    idle();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_recv(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
    m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
    WAIT_MS(clock_lo, 250, 1);  // keyboard may block long time
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        data <<= 1;
 | 
			
		||||
        WAIT_US(clock_lo, 200, 2);
 | 
			
		||||
        WAIT_US(clock_hi, 200, 3);
 | 
			
		||||
        if (data_in()) {
 | 
			
		||||
            data |= 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    idle();
 | 
			
		||||
    return data;
 | 
			
		||||
ERROR:
 | 
			
		||||
    print("m0110_recv err: "); phex(m0110_error); print("\n");
 | 
			
		||||
    _delay_ms(500);
 | 
			
		||||
    idle();
 | 
			
		||||
    return 0xFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_recv_key(void)
 | 
			
		||||
{
 | 
			
		||||
    static uint8_t keybuf = 0x00;
 | 
			
		||||
    uint8_t key, key2, key3;
 | 
			
		||||
 | 
			
		||||
    if (keybuf) {
 | 
			
		||||
        key = keybuf;
 | 
			
		||||
        keybuf = 0x00;
 | 
			
		||||
        return key;
 | 
			
		||||
    }
 | 
			
		||||
    key = instant();  // Use INSTANT for better response. Should be INQUIRY ?
 | 
			
		||||
    switch (key & 0x7F) {
 | 
			
		||||
        case M0110_KEYPAD:
 | 
			
		||||
            // Pad/Arrow keys
 | 
			
		||||
            return (raw2scan(instant()) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
            break;
 | 
			
		||||
        case M0110_SHIFT:
 | 
			
		||||
            key2 = instant();
 | 
			
		||||
            if (key2 == M0110_KEYPAD) {
 | 
			
		||||
                key3 = instant();
 | 
			
		||||
                switch (key3 & 0x7F) {
 | 
			
		||||
                    case M0110_ARROW_UP:
 | 
			
		||||
                    case M0110_ARROW_DOWN:
 | 
			
		||||
                    case M0110_ARROW_LEFT:
 | 
			
		||||
                    case M0110_ARROW_RIGHT:
 | 
			
		||||
                        // Calc keys
 | 
			
		||||
                        return (raw2scan(key3) | M0110_CALC_OFFSET);
 | 
			
		||||
                    default:
 | 
			
		||||
                        // Shift + Pad/Arrow keys
 | 
			
		||||
                        keybuf = raw2scan(key3);
 | 
			
		||||
                        return (raw2scan(key) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Shift + other keys
 | 
			
		||||
                keybuf = raw2scan(key2);
 | 
			
		||||
                return raw2scan(key);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            // other keys
 | 
			
		||||
            return raw2scan(key);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline uint8_t raw2scan(uint8_t raw) {
 | 
			
		||||
    return (raw == M0110_NULL) ?  M0110_NULL : (
 | 
			
		||||
                (raw == M0110_ERROR) ?  M0110_ERROR : (
 | 
			
		||||
                    ((raw&0x80) | ((raw&0x7F)>>1))
 | 
			
		||||
                )
 | 
			
		||||
           );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint8_t inquiry(void)
 | 
			
		||||
{
 | 
			
		||||
    m0110_send(M0110_INQUIRY);
 | 
			
		||||
    return m0110_recv();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint8_t instant(void)
 | 
			
		||||
{
 | 
			
		||||
    m0110_send(M0110_INSTANT);
 | 
			
		||||
    //return m0110_recv();
 | 
			
		||||
    uint8_t data = m0110_recv();
 | 
			
		||||
    if (data != 0x7B) {
 | 
			
		||||
        print("data: "); phex(data); print("\n");
 | 
			
		||||
    }
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void clock_lo()
 | 
			
		||||
{
 | 
			
		||||
    M0110_CLOCK_PORT &= ~(1<<M0110_CLOCK_BIT);
 | 
			
		||||
    M0110_CLOCK_DDR  |=  (1<<M0110_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void clock_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    M0110_CLOCK_DDR  &= ~(1<<M0110_CLOCK_BIT);
 | 
			
		||||
    M0110_CLOCK_PORT |=  (1<<M0110_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool clock_in()
 | 
			
		||||
{
 | 
			
		||||
    M0110_CLOCK_DDR  &= ~(1<<M0110_CLOCK_BIT);
 | 
			
		||||
    M0110_CLOCK_PORT |=  (1<<M0110_CLOCK_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return M0110_CLOCK_PIN&(1<<M0110_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_lo()
 | 
			
		||||
{
 | 
			
		||||
    M0110_DATA_PORT &= ~(1<<M0110_DATA_BIT);
 | 
			
		||||
    M0110_DATA_DDR  |=  (1<<M0110_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    M0110_DATA_DDR  &= ~(1<<M0110_DATA_BIT);
 | 
			
		||||
    M0110_DATA_PORT |=  (1<<M0110_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool data_in()
 | 
			
		||||
{
 | 
			
		||||
    M0110_DATA_DDR  &= ~(1<<M0110_DATA_BIT);
 | 
			
		||||
    M0110_DATA_PORT |=  (1<<M0110_DATA_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return M0110_DATA_PIN&(1<<M0110_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint16_t wait_clock_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (clock_in()  && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_clock_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void idle(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void request(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_lo();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Primitive M0110 Library for AVR
 | 
			
		||||
==============================
 | 
			
		||||
@ -199,224 +435,3 @@ Scan Codes:
 | 
			
		||||
    http://m0115.web.fc2.com/m0110.jpg
 | 
			
		||||
    http://m0115.web.fc2.com/m0110a.jpg
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WAIT_US(stat, us, err) do { \
 | 
			
		||||
    if (!wait_##stat(us)) { \
 | 
			
		||||
        m0110_error = err; \
 | 
			
		||||
        goto ERROR; \
 | 
			
		||||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define WAIT_MS(stat, ms, err) do { \
 | 
			
		||||
    uint16_t _ms = ms; \
 | 
			
		||||
    while (_ms) { \
 | 
			
		||||
        if (wait_##stat(1000)) { \
 | 
			
		||||
            break; \
 | 
			
		||||
        } \
 | 
			
		||||
        _ms--; \
 | 
			
		||||
    } \
 | 
			
		||||
    if (_ms == 0) { \
 | 
			
		||||
        m0110_error = err; \
 | 
			
		||||
        goto ERROR; \
 | 
			
		||||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void m0110_init(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data;
 | 
			
		||||
    idle();
 | 
			
		||||
    _delay_ms(1000);
 | 
			
		||||
 | 
			
		||||
    // Model Number
 | 
			
		||||
    // M0110 : 0x09  00001001 : model number 4 (100)
 | 
			
		||||
    // M0110A: 0x0B  00001011 : model number 5 (101)
 | 
			
		||||
    // M0110 & M0120: ???
 | 
			
		||||
    m0110_send(M0110_MODEL);
 | 
			
		||||
    data = m0110_recv();
 | 
			
		||||
    print("m0110_init model: "); phex(data); print("\n");
 | 
			
		||||
 | 
			
		||||
    m0110_send(M0110_TEST);
 | 
			
		||||
    data = m0110_recv();
 | 
			
		||||
    print("m0110_init test: "); phex(data); print("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_send(uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
    request();
 | 
			
		||||
    WAIT_MS(clock_lo, 250, 1);  // keyboard may block long time
 | 
			
		||||
    for (uint8_t bit = 0x80; bit; bit >>= 1) {
 | 
			
		||||
        WAIT_US(clock_lo, 250, 3);
 | 
			
		||||
        if (data&bit) {
 | 
			
		||||
            data_hi();
 | 
			
		||||
        } else {
 | 
			
		||||
            data_lo();
 | 
			
		||||
        }
 | 
			
		||||
        WAIT_US(clock_hi, 200, 4);
 | 
			
		||||
    }
 | 
			
		||||
    _delay_us(100); // hold last bit for 80us
 | 
			
		||||
    idle();
 | 
			
		||||
    return 1;
 | 
			
		||||
ERROR:
 | 
			
		||||
    print("m0110_send err: "); phex(m0110_error); print("\n");
 | 
			
		||||
    _delay_ms(500);
 | 
			
		||||
    idle();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_recv(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
    m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
    WAIT_MS(clock_lo, 250, 1);  // keyboard may block long time
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        data <<= 1;
 | 
			
		||||
        WAIT_US(clock_lo, 200, 2);
 | 
			
		||||
        WAIT_US(clock_hi, 200, 3);
 | 
			
		||||
        if (data_in()) {
 | 
			
		||||
            data |= 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    idle();
 | 
			
		||||
    return data;
 | 
			
		||||
ERROR:
 | 
			
		||||
    print("m0110_recv err: "); phex(m0110_error); print("\n");
 | 
			
		||||
    _delay_ms(500);
 | 
			
		||||
    idle();
 | 
			
		||||
    return 0xFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_recv_key(void)
 | 
			
		||||
{
 | 
			
		||||
    static uint8_t keybuf = 0x00;
 | 
			
		||||
    uint8_t key, key2, key3;
 | 
			
		||||
 | 
			
		||||
    if (keybuf) {
 | 
			
		||||
        key = keybuf;
 | 
			
		||||
        keybuf = 0x00;
 | 
			
		||||
        return key;
 | 
			
		||||
    }
 | 
			
		||||
    key = instant();  // Use INSTANT for better response. Should be INQUIRY ?
 | 
			
		||||
    switch (key & 0x7F) {
 | 
			
		||||
        case M0110_KEYPAD:
 | 
			
		||||
            // Pad/Arrow keys
 | 
			
		||||
            return (M0110_RAW2SCAN(instant()) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
            break;
 | 
			
		||||
        case M0110_SHIFT:
 | 
			
		||||
            key2 = instant();
 | 
			
		||||
            if (key2 == M0110_KEYPAD) {
 | 
			
		||||
                key3 = instant();
 | 
			
		||||
                switch (key3 & 0x7F) {
 | 
			
		||||
                    case M0110_ARROW_UP:
 | 
			
		||||
                    case M0110_ARROW_DOWN:
 | 
			
		||||
                    case M0110_ARROW_LEFT:
 | 
			
		||||
                    case M0110_ARROW_RIGHT:
 | 
			
		||||
                        // Calc keys
 | 
			
		||||
                        return (M0110_RAW2SCAN(key3) | M0110_CALC_OFFSET);
 | 
			
		||||
                    default:
 | 
			
		||||
                        // Shift + Pad/Arrow keys
 | 
			
		||||
                        keybuf = M0110_RAW2SCAN(key3);
 | 
			
		||||
                        return (M0110_RAW2SCAN(key) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Shift + other keys
 | 
			
		||||
                keybuf = M0110_RAW2SCAN(key2);
 | 
			
		||||
                return M0110_RAW2SCAN(key);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            // other keys
 | 
			
		||||
            return M0110_RAW2SCAN(key);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline uint8_t inquiry(void)
 | 
			
		||||
{
 | 
			
		||||
    m0110_send(M0110_INQUIRY);
 | 
			
		||||
    return m0110_recv();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint8_t instant(void)
 | 
			
		||||
{
 | 
			
		||||
    m0110_send(M0110_INSTANT);
 | 
			
		||||
    return m0110_recv();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void clock_lo()
 | 
			
		||||
{
 | 
			
		||||
    M0110_CLOCK_PORT &= ~(1<<M0110_CLOCK_BIT);
 | 
			
		||||
    M0110_CLOCK_DDR  |=  (1<<M0110_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void clock_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    M0110_CLOCK_DDR  &= ~(1<<M0110_CLOCK_BIT);
 | 
			
		||||
    M0110_CLOCK_PORT |=  (1<<M0110_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool clock_in()
 | 
			
		||||
{
 | 
			
		||||
    M0110_CLOCK_DDR  &= ~(1<<M0110_CLOCK_BIT);
 | 
			
		||||
    M0110_CLOCK_PORT |=  (1<<M0110_CLOCK_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return M0110_CLOCK_PIN&(1<<M0110_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_lo()
 | 
			
		||||
{
 | 
			
		||||
    M0110_DATA_PORT &= ~(1<<M0110_DATA_BIT);
 | 
			
		||||
    M0110_DATA_DDR  |=  (1<<M0110_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_hi()
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    M0110_DATA_DDR  &= ~(1<<M0110_DATA_BIT);
 | 
			
		||||
    M0110_DATA_PORT |=  (1<<M0110_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool data_in()
 | 
			
		||||
{
 | 
			
		||||
    M0110_DATA_DDR  &= ~(1<<M0110_DATA_BIT);
 | 
			
		||||
    M0110_DATA_PORT |=  (1<<M0110_DATA_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return M0110_DATA_PIN&(1<<M0110_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint16_t wait_clock_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (clock_in()  && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_clock_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void idle(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_hi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void request(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_hi();
 | 
			
		||||
    data_lo();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								m0110.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								m0110.h
									
									
									
									
									
								
							@ -78,15 +78,6 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#define M0110_KEYPAD_OFFSET 0x40
 | 
			
		||||
#define M0110_CALC_OFFSET   0x60
 | 
			
		||||
 | 
			
		||||
/* convert key event raw response into scan code */
 | 
			
		||||
#define M0110_RAW2SCAN(key) ( \
 | 
			
		||||
    (key == M0110_NULL) ?  M0110_NULL : ( \
 | 
			
		||||
        (key == M0110_ERROR) ?  M0110_ERROR : ( \
 | 
			
		||||
            ((key&0x80) | ((key&0x7F)>>1)) \
 | 
			
		||||
        ) \
 | 
			
		||||
    ) \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern uint8_t m0110_error;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								m0110_usb/doc/m0110.jpg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								m0110_usb/doc/m0110.jpg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
		 Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB  | 
							
								
								
									
										0
									
								
								m0110_usb/doc/teensy.jpg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								m0110_usb/doc/teensy.jpg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
		 Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB  | 
@ -58,7 +58,7 @@ static const uint8_t PROGMEM fn_layer[] = {
 | 
			
		||||
    1,              // Fn0
 | 
			
		||||
    2,              // Fn1
 | 
			
		||||
    3,              // Fn2
 | 
			
		||||
    0,              // Fn3
 | 
			
		||||
    1,              // Fn3
 | 
			
		||||
    0,              // Fn4
 | 
			
		||||
    0,              // Fn5
 | 
			
		||||
    0,              // Fn6
 | 
			
		||||
@ -68,15 +68,17 @@ static const uint8_t PROGMEM fn_layer[] = {
 | 
			
		||||
// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
 | 
			
		||||
// See layer.c for details.
 | 
			
		||||
static const uint8_t PROGMEM fn_keycode[] = {
 | 
			
		||||
#ifndef HASU
 | 
			
		||||
    KB_ESC,         // Fn0
 | 
			
		||||
#ifdef HASU
 | 
			
		||||
    KB_SCOLON,      // Fn1
 | 
			
		||||
    KB_SLASH,       // Fn2
 | 
			
		||||
#else
 | 
			
		||||
    KB_NO,          // Fn1
 | 
			
		||||
    KB_NO,          // Fn2
 | 
			
		||||
#endif
 | 
			
		||||
    KB_NO,          // Fn3
 | 
			
		||||
#else
 | 
			
		||||
    KB_NO,          // Fn0
 | 
			
		||||
    KB_SCOLON,      // Fn1
 | 
			
		||||
    KB_SLASH,       // Fn2
 | 
			
		||||
    KB_UP,          // Fn3
 | 
			
		||||
#endif
 | 
			
		||||
    KB_NO,          // Fn4
 | 
			
		||||
    KB_NO,          // Fn5
 | 
			
		||||
    KB_NO,          // Fn6
 | 
			
		||||
@ -107,7 +109,6 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
     * |---------------------------------------------------------| |-----------|Ent|
 | 
			
		||||
     * |Ctrl |Alt    |         Space         |Gui|  \|Lft|Rgt|Dn | |      0|  .|   |
 | 
			
		||||
     * `---------------------------------------------------------' `---------------'
 | 
			
		||||
     * You can register Esc by hitting(press&release) Fn0 quickly.
 | 
			
		||||
     *
 | 
			
		||||
     * HHKB/WASD cursor Layer(Fn0):
 | 
			
		||||
     * ,---------------------------------------------------------. ,---------------.
 | 
			
		||||
@ -122,49 +123,18 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
     * |Ctrl |Alt    |         Space        |Gui |  \|Lft|Rgt|Dn | |      0|  .|   |
 | 
			
		||||
     * `---------------------------------------------------------' `---------------'
 | 
			
		||||
     *
 | 
			
		||||
     * NOTE: Key between Space and \ in above diagram is M0110 Enter(assigned to Gui).
 | 
			
		||||
     * NOTE: You can register Esc by hitting(press&release) Fn0 quickly.
 | 
			
		||||
     * NOTE: Gui between Space and \ is Enter on M0110 not exists on M0110A.
 | 
			
		||||
     * NOTE: LShift and RShift are logically same key. (M0110, M0110A)
 | 
			
		||||
     * NOTE: LOption and ROption are logically same key. (M0110)
 | 
			
		||||
     */
 | 
			
		||||
#ifdef HASU
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    ESC, PEQL,PSLS,PAST,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,         P7,  P8,  P9,  PMNS,
 | 
			
		||||
    LCTL,A,   S,   D,   F,   G,   H,   J,   K,   L,   FN1, QUOT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2,           UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    FN0, LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // HHKB & WASD
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,HOME,UP,  PGUP,NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  INS,          P7,  P8,  P9,  PMNS,
 | 
			
		||||
    LCTL,LEFT,DOWN,RGHT,NO,  NO,  NO,  NO,  HOME,PGUP,LEFT,RGHT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    FN0, LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // vi mousekeys
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  WH_L,WH_D,WH_U,WH_R,NO,  NO,  NO,           P7,  P8,  P9,  PMNS,
 | 
			
		||||
    NO,  VOLD,VOLU,MUTE,NO,  NO,  MS_L,MS_D,MS_U,MS_R,FN1, NO,       ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,NO,  NO,  NO,  NO,  BTN3,BTN2,BTN1,NO,  NO,  NO,            UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               BTN1,               LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // vi cusorkeys
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, NO,  NO,  NO,           P7,  P8,  P9,  PMNS,
 | 
			
		||||
    NO,  NO,  NO,  NO,  NO,  NO,  LEFT,DOWN,UP,  RGHT,NO,  NO,       ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, FN2,           UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
#else
 | 
			
		||||
#ifndef HASU
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    LGUI,PEQL,PSLS,PAST,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,         P7,  P8,  P9,  PMNS,
 | 
			
		||||
    FN0, A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // HHKB & WASD
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
@ -172,7 +142,41 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
    CAPS,HOME,UP,  PGUP,NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  INS,          P7,  P8,  P9,  PMNS,
 | 
			
		||||
    FN0, LEFT,DOWN,RGHT,NO,  NO,  NO,  NO,  HOME,PGUP,LEFT,RGHT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
#else
 | 
			
		||||
    // hasu's keymap
 | 
			
		||||
    // To enable use this 'make' option: make EXTRAFLAGS=-DHASU
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    ESC, PEQL,PSLS,PAST,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,         P7,  P8,  P9,  PMNS,
 | 
			
		||||
    LCTL,A,   S,   D,   F,   G,   H,   J,   K,   L,   FN1, QUOT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2,           FN3,     P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // HHKB & WASD
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,HOME,UP,  PGUP,NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  INS,          P7,  P8,  P9,  PMNS,
 | 
			
		||||
    LCTL,LEFT,DOWN,RGHT,NO,  NO,  NO,  NO,  HOME,PGUP,LEFT,RGHT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          FN3,     P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // vi mousekeys
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  WH_L,WH_D,WH_U,WH_R,NO,  NO,  NO,           P7,  P8,  P9,  PMNS,
 | 
			
		||||
    NO,  VOLD,VOLU,MUTE,NO,  NO,  MS_L,MS_D,MS_U,MS_R,FN1, NO,       ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,NO,  NO,  NO,  NO,  BTN3,BTN2,BTN1,NO,  NO,  NO,            UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               BTN1,               LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
    // vi cusorkeys
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, NO,  NO,  NO,           P7,  P8,  P9,  PMNS,
 | 
			
		||||
    NO,  NO,  NO,  NO,  NO,  NO,  LEFT,DOWN,UP,  RGHT,NO,  NO,       ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, FN2,           UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ),
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -32,10 +32,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CAPS        0x39
 | 
			
		||||
#define CAPS_UP     (CAPS | 0x80)
 | 
			
		||||
#define CAPS_BREAK  (CAPS | 0x80)
 | 
			
		||||
#define ROW(key)    ((key)>>3&0x0F)
 | 
			
		||||
#define COL(key)    ((key)&0x07)
 | 
			
		||||
 | 
			
		||||
#define ARROW_UP_BREAK      (0x4D | 0x80)
 | 
			
		||||
#define ARROW_DOWN_BREAK    (0x48 | 0x80)
 | 
			
		||||
#define ARROW_LEFT_BREAK    (0x46 | 0x80)
 | 
			
		||||
#define ARROW_RIGHT_BREAK   (0x42 | 0x80)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool is_modified = false;
 | 
			
		||||
 | 
			
		||||
@ -88,14 +93,27 @@ uint8_t matrix_scan(void)
 | 
			
		||||
    // Send Caps key up event
 | 
			
		||||
    if (matrix_is_on(ROW(CAPS), COL(CAPS))) {
 | 
			
		||||
        is_modified = true;
 | 
			
		||||
        register_key(CAPS_UP);
 | 
			
		||||
        register_key(CAPS_BREAK);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    if (key == M0110_NULL) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else if (key == M0110_ERROR) {
 | 
			
		||||
        // TODO: error recovery or reinit
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else if (key == ARROW_UP_BREAK ||
 | 
			
		||||
               key == ARROW_DOWN_BREAK ||
 | 
			
		||||
               key == ARROW_LEFT_BREAK ||
 | 
			
		||||
               key == ARROW_RIGHT_BREAK) {
 | 
			
		||||
        // WORK AROUND: exceptional handling for M0110A
 | 
			
		||||
        // Unregister both Arrow key and coressponding Calc key when receive Arrow key break.
 | 
			
		||||
        //
 | 
			
		||||
        // Shift + Calc keys(=/*+):
 | 
			
		||||
        //    Send no Shift break(0xF1) when release Calc keys. Can't be desinguished from Arrow keys.
 | 
			
		||||
        //    (press: 0x71, 0x79, 0xXX      release: 0x79, 0xXX)
 | 
			
		||||
        //    See m0110.c for key events and scan codes.
 | 
			
		||||
        is_modified = true;
 | 
			
		||||
        register_key(key);
 | 
			
		||||
        register_key(key|M0110_CALC_OFFSET);
 | 
			
		||||
    } else {
 | 
			
		||||
#ifdef MATRIX_HAS_LOCKING_CAPS    
 | 
			
		||||
        if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
 | 
			
		||||
@ -103,11 +121,11 @@ uint8_t matrix_scan(void)
 | 
			
		||||
            // Ignore LockingCaps key down event
 | 
			
		||||
            if (key == CAPS) return 0;
 | 
			
		||||
            // Convert LockingCaps key up event into down event
 | 
			
		||||
            if (key == CAPS_UP) key = CAPS;
 | 
			
		||||
            if (key == CAPS_BREAK) key = CAPS;
 | 
			
		||||
        } else {
 | 
			
		||||
            // CAPS LOCK off:
 | 
			
		||||
            // Ignore LockingCaps key up event
 | 
			
		||||
            if (key == CAPS_UP) return 0;
 | 
			
		||||
            if (key == CAPS_BREAK) return 0;
 | 
			
		||||
        }
 | 
			
		||||
#endif        
 | 
			
		||||
        is_modified = true;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								rules.mk
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								rules.mk
									
									
									
									
									
								
							@ -317,7 +317,7 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
 | 
			
		||||
 | 
			
		||||
# Combine all necessary flags and optional flags.
 | 
			
		||||
# Add target processor to flags.
 | 
			
		||||
# You can give EXTRAFLAGS at 'make' command line.
 | 
			
		||||
# You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar
 | 
			
		||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
 | 
			
		||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
 | 
			
		||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user