diff options
Diffstat (limited to 'tmk_core')
46 files changed, 330 insertions, 3686 deletions
| diff --git a/tmk_core/common.mk b/tmk_core/common.mk index e44ff2f0ab..f0faa2dc3e 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -55,8 +55,6 @@ ifeq ($(strip $(NKRO_ENABLE)), yes)          $(info NKRO is not currently supported on V-USB, and has been disabled.)      else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)          $(info NKRO is not currently supported with Bluetooth, and has been disabled.) -    else ifneq ($(BLUETOOTH),) -        $(info NKRO is not currently supported with Bluetooth, and has been disabled.)      else          TMK_COMMON_DEFS += -DNKRO_ENABLE          SHARED_EP_ENABLE = yes @@ -77,23 +75,6 @@ ifeq ($(strip $(NO_SUSPEND_POWER_DOWN)), yes)      TMK_COMMON_DEFS += -DNO_SUSPEND_POWER_DOWN  endif -ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) -    TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE -	TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK -endif - -ifeq ($(strip $(BLUETOOTH)), AdafruitBLE) -	TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE -	TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE -	TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK -endif - -ifeq ($(strip $(BLUETOOTH)), RN42) -	TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE -	TMK_COMMON_DEFS += -DMODULE_RN42 -	TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK -endif -  ifeq ($(strip $(SWAP_HANDS_ENABLE)), yes)      TMK_COMMON_DEFS += -DSWAP_HANDS_ENABLE  endif diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c index ccd5d15a54..ff1a692623 100644 --- a/tmk_core/common/arm_atsam/eeprom.c +++ b/tmk_core/common/arm_atsam/eeprom.c @@ -13,24 +13,110 @@   * You should have received a copy of the GNU General Public License   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -  #include "eeprom.h" +#include "debug.h" +#include "samd51j18a.h" +#include "core_cm4.h" +#include "component/nvmctrl.h"  #ifndef EEPROM_SIZE  #    include "eeconfig.h"  #    define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4)  // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO  #endif -__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE]; +#ifndef MAX +#    define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) +#endif + +#ifndef BUSY_RETRIES +#    define BUSY_RETRIES 10000 +#endif + +// #define DEBUG_EEPROM_OUTPUT + +/* + * Debug print utils + */ +#if defined(DEBUG_EEPROM_OUTPUT) +#    define eeprom_printf(fmt, ...) xprintf(fmt, ##__VA_ARGS__); +#else /* NO_DEBUG */ +#    define eeprom_printf(fmt, ...) +#endif /* NO_DEBUG */ + +__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE] = {0}; +volatile uint8_t *                         SmartEEPROM8        = (uint8_t *)SEEPROM_ADDR; + +static inline bool eeprom_is_busy(void) { +    int timeout = BUSY_RETRIES; +    while (NVMCTRL->SEESTAT.bit.BUSY && timeout-- > 0) +        ; + +    return NVMCTRL->SEESTAT.bit.BUSY; +} + +static uint32_t get_virtual_eeprom_size(void) { +    // clang-format off +    static const uint32_t VIRTUAL_EEPROM_MAP[11][8] = { +    /*          4    8    16    32    64    128    256    512 */ +    /* 0*/ {   0,    0,    0,    0,    0,     0,     0,     0 }, +    /* 1*/ { 512, 1024, 2048, 4096, 4096,  4096,  4096,  4096 }, +    /* 2*/ { 512, 1024, 2048, 4096, 8192,  8192,  8192,  8192 }, +    /* 3*/ { 512, 1024, 2048, 4096, 8192, 16384, 16384, 16384 }, +    /* 4*/ { 512, 1024, 2048, 4096, 8192, 16384, 16384, 16384 }, +    /* 5*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, +    /* 6*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, +    /* 7*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, +    /* 8*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, +    /* 9*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }, +    /*10*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }, +    }; +    // clang-format on + +    static uint32_t virtual_eeprom_size = UINT32_MAX; +    if (virtual_eeprom_size == UINT32_MAX) { +        virtual_eeprom_size = VIRTUAL_EEPROM_MAP[NVMCTRL->SEESTAT.bit.PSZ][NVMCTRL->SEESTAT.bit.SBLK]; +    } +    // eeprom_printf("get_virtual_eeprom_size:: %d:%d:%d\n", NVMCTRL->SEESTAT.bit.PSZ, NVMCTRL->SEESTAT.bit.SBLK, virtual_eeprom_size); +    return virtual_eeprom_size; +}  uint8_t eeprom_read_byte(const uint8_t *addr) {      uintptr_t offset = (uintptr_t)addr; -    return buffer[offset]; +    if (offset >= MAX(EEPROM_SIZE, get_virtual_eeprom_size())) { +        eeprom_printf("eeprom_read_byte:: out of bounds\n"); +        return 0x0; +    } + +    if (get_virtual_eeprom_size() == 0) { +        return buffer[offset]; +    } + +    if (eeprom_is_busy()) { +        eeprom_printf("eeprom_write_byte:: timeout\n"); +        return 0x0; +    } + +    return SmartEEPROM8[offset];  }  void eeprom_write_byte(uint8_t *addr, uint8_t value) {      uintptr_t offset = (uintptr_t)addr; -    buffer[offset]   = value; +    if (offset >= MAX(EEPROM_SIZE, get_virtual_eeprom_size())) { +        eeprom_printf("eeprom_write_byte:: out of bounds\n"); +        return; +    } + +    if (get_virtual_eeprom_size() == 0) { +        buffer[offset] = value; +        return; +    } + +    if (eeprom_is_busy()) { +        eeprom_printf("eeprom_write_byte:: timeout\n"); +        return; +    } + +    SmartEEPROM8[offset] = value;  }  uint16_t eeprom_read_word(const uint16_t *addr) { diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 690d7f38ca..b614746e6c 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c @@ -16,25 +16,6 @@  #    include "vusb.h"  #endif -#ifdef BACKLIGHT_ENABLE -#    include "backlight.h" -#endif - -#ifdef AUDIO_ENABLE -#    include "audio.h" -#endif /* AUDIO_ENABLE */ - -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -#    include "rgblight.h" -#endif - -#ifdef LED_MATRIX_ENABLE -#    include "led_matrix.h" -#endif -#ifdef RGB_MATRIX_ENABLE -#    include "rgb_matrix.h" -#endif -  /** \brief Suspend idle   *   * FIXME: needs doc @@ -50,17 +31,6 @@ void suspend_idle(uint8_t time) {  // TODO: This needs some cleanup -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_user(void) {} -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } -  #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)  // clang-format off @@ -135,41 +105,9 @@ void suspend_power_down(void) {      if (!vusb_suspended) return;  #endif -    suspend_power_down_kb(); +    suspend_power_down_quantum();  #ifndef NO_SUSPEND_POWER_DOWN -    // Turn off backlight -#    ifdef BACKLIGHT_ENABLE -    backlight_set(0); -#    endif - -    // Turn off LED indicators -    uint8_t leds_off = 0; -#    if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) -    if (is_backlight_enabled()) { -        // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off -        leds_off |= (1 << USB_LED_CAPS_LOCK); -    } -#    endif -    led_set(leds_off); - -    // Turn off audio -#    ifdef AUDIO_ENABLE -    stop_all_notes(); -#    endif - -    // Turn off underglow -#    if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -    rgblight_suspend(); -#    endif - -#    if defined(LED_MATRIX_ENABLE) -    led_matrix_set_suspend_state(true); -#    endif -#    if defined(RGB_MATRIX_ENABLE) -    rgb_matrix_set_suspend_state(true); -#    endif -      // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt)  #    if defined(WDT_vect)      power_down(WDTO_15MS); @@ -189,18 +127,6 @@ bool                       suspend_wakeup_condition(void) {      return false;  } -/** \brief run user level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_user(void) {} - -/** \brief run keyboard level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } -  /** \brief run immediately after wakeup   *   * FIXME: needs doc @@ -209,27 +135,7 @@ void suspend_wakeup_init(void) {      // clear keyboard state      clear_keyboard(); -    // Turn on backlight -#ifdef BACKLIGHT_ENABLE -    backlight_init(); -#endif - -    // Restore LED indicators -    led_set(host_keyboard_leds()); - -    // Wake up underglow -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -    rgblight_wakeup(); -#endif - -#if defined(LED_MATRIX_ENABLE) -    led_matrix_set_suspend_state(false); -#endif -#if defined(RGB_MATRIX_ENABLE) -    rgb_matrix_set_suspend_state(false); -#endif - -    suspend_wakeup_init_kb(); +    suspend_wakeup_init_quantum();  }  #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) diff --git a/tmk_core/common/chibios/_wait.h b/tmk_core/common/chibios/_wait.h index b740afbd24..2f36c64a2e 100644 --- a/tmk_core/common/chibios/_wait.h +++ b/tmk_core/common/chibios/_wait.h @@ -43,8 +43,6 @@ void wait_us(uint16_t duration);  #include "_wait.c" -#define CPU_CLOCK STM32_SYSCLK -  /* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus   * to which the GPIO is connected.   * The connected buses differ depending on the various series of MCUs. diff --git a/tmk_core/common/chibios/chibios_config.h b/tmk_core/common/chibios/chibios_config.h index 23c65f9428..c35f589557 100644 --- a/tmk_core/common/chibios/chibios_config.h +++ b/tmk_core/common/chibios/chibios_config.h @@ -19,22 +19,33 @@  #    define SPLIT_USB_DETECT  // Force this on when dedicated pin is not used  #endif -#if defined(STM32F1XX) -#    define USE_GPIOV1 -#endif +// STM32 compatibility +#if defined(MCU_STM32) +#    define CPU_CLOCK STM32_SYSCLK -#if defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32L1XX) -#    define USE_I2CV1 -#endif +#    if defined(STM32F1XX) +#        define USE_GPIOV1 +#        define PAL_MODE_ALTERNATE_OPENDRAIN PAL_MODE_STM32_ALTERNATE_OPENDRAIN +#        define PAL_MODE_ALTERNATE_PUSHPULL PAL_MODE_STM32_ALTERNATE_PUSHPULL +#    else +#        define PAL_OUTPUT_TYPE_OPENDRAIN PAL_STM32_OTYPE_OPENDRAIN +#        define PAL_OUTPUT_TYPE_PUSHPULL PAL_STM32_OTYPE_PUSHPULL +#        define PAL_OUTPUT_SPEED_HIGHEST PAL_STM32_OSPEED_HIGHEST +#        define PAL_PUPDR_FLOATING PAL_STM32_PUPDR_FLOATING +#    endif -// teensy -#if defined(K20x) || defined(KL2x) -#    define USE_I2CV1 -#    define USE_I2CV1_CONTRIB  // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed -#    define USE_GPIOV1 -#    define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY +#    if defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32L1XX) +#        define USE_I2CV1 +#    endif  #endif -#if defined(MK66F18) -#    define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY -#endif +// teensy compatibility +#if defined(MCU_KINETIS) +#    define CPU_CLOCK KINETIS_SYSCLK_FREQUENCY + +#    if defined(K20x) || defined(KL2x) +#        define USE_I2CV1 +#        define USE_I2CV1_CONTRIB  // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed +#        define USE_GPIOV1 +#    endif +#endif
\ No newline at end of file diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c index 1fdf8c1e29..acc6a48516 100644 --- a/tmk_core/common/chibios/eeprom_stm32.c +++ b/tmk_core/common/chibios/eeprom_stm32.c @@ -620,48 +620,11 @@ uint16_t EEPROM_ReadDataWord(uint16_t Address) {  }  /***************************************************************************** - *  Wrap library in AVR style functions. + *  Bind to eeprom_driver.c   *******************************************************************************/ -uint8_t eeprom_read_byte(const uint8_t *Address) { return EEPROM_ReadDataByte((const uintptr_t)Address); } +void eeprom_driver_init(void) { EEPROM_Init(); } -void eeprom_write_byte(uint8_t *Address, uint8_t Value) { EEPROM_WriteDataByte((uintptr_t)Address, Value); } - -void eeprom_update_byte(uint8_t *Address, uint8_t Value) { EEPROM_WriteDataByte((uintptr_t)Address, Value); } - -uint16_t eeprom_read_word(const uint16_t *Address) { return EEPROM_ReadDataWord((const uintptr_t)Address); } - -void eeprom_write_word(uint16_t *Address, uint16_t Value) { EEPROM_WriteDataWord((uintptr_t)Address, Value); } - -void eeprom_update_word(uint16_t *Address, uint16_t Value) { EEPROM_WriteDataWord((uintptr_t)Address, Value); } - -uint32_t eeprom_read_dword(const uint32_t *Address) { -    const uint16_t p = (const uintptr_t)Address; -    /* Check word alignment */ -    if (p % 2) { -        /* Not aligned */ -        return (uint32_t)EEPROM_ReadDataByte(p) | (uint32_t)(EEPROM_ReadDataWord(p + 1) << 8) | (uint32_t)(EEPROM_ReadDataByte(p + 3) << 24); -    } else { -        /* Aligned */ -        return EEPROM_ReadDataWord(p) | (EEPROM_ReadDataWord(p + 2) << 16); -    } -} - -void eeprom_write_dword(uint32_t *Address, uint32_t Value) { -    uint16_t p = (const uintptr_t)Address; -    /* Check word alignment */ -    if (p % 2) { -        /* Not aligned */ -        EEPROM_WriteDataByte(p, (uint8_t)Value); -        EEPROM_WriteDataWord(p + 1, (uint16_t)(Value >> 8)); -        EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24)); -    } else { -        /* Aligned */ -        EEPROM_WriteDataWord(p, (uint16_t)Value); -        EEPROM_WriteDataWord(p + 2, (uint16_t)(Value >> 16)); -    } -} - -void eeprom_update_dword(uint32_t *Address, uint32_t Value) { eeprom_write_dword(Address, Value); } +void eeprom_driver_erase(void) { EEPROM_Erase(); }  void eeprom_read_block(void *buf, const void *addr, size_t len) {      const uint8_t *src  = (const uint8_t *)addr; @@ -670,14 +633,14 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) {      /* Check word alignment */      if (len && (uintptr_t)src % 2) {          /* Read the unaligned first byte */ -        *dest++ = eeprom_read_byte(src++); +        *dest++ = EEPROM_ReadDataByte((const uintptr_t)src++);          --len;      }      uint16_t value;      bool     aligned = ((uintptr_t)dest % 2 == 0);      while (len > 1) { -        value = eeprom_read_word((uint16_t *)src); +        value = EEPROM_ReadDataWord((const uintptr_t)((uint16_t *)src));          if (aligned) {              *(uint16_t *)dest = value;              dest += 2; @@ -689,7 +652,7 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) {          len -= 2;      }      if (len) { -        *dest = eeprom_read_byte(src); +        *dest = EEPROM_ReadDataByte((const uintptr_t)src);      }  } @@ -700,7 +663,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {      /* Check word alignment */      if (len && (uintptr_t)dest % 2) {          /* Write the unaligned first byte */ -        eeprom_write_byte(dest++, *src++); +        EEPROM_WriteDataByte((uintptr_t)dest++, *src++);          --len;      } @@ -712,15 +675,13 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {          } else {              value = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8);          } -        eeprom_write_word((uint16_t *)dest, value); +        EEPROM_WriteDataWord((uintptr_t)((uint16_t *)dest), value);          dest += 2;          src += 2;          len -= 2;      }      if (len) { -        eeprom_write_byte(dest, *src); +        EEPROM_WriteDataByte((uintptr_t)dest, *src);      }  } - -void eeprom_update_block(const void *buf, void *addr, size_t len) { eeprom_write_block(buf, addr, len); } diff --git a/tmk_core/common/chibios/eeprom_stm32_defs.h b/tmk_core/common/chibios/eeprom_stm32_defs.h index 22b4ab858e..3499796264 100644 --- a/tmk_core/common/chibios/eeprom_stm32_defs.h +++ b/tmk_core/common/chibios/eeprom_stm32_defs.h @@ -32,6 +32,13 @@  #        ifndef FEE_PAGE_COUNT  #            define FEE_PAGE_COUNT 4  // How many pages are used  #        endif +#    elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) +#        ifndef FEE_PAGE_SIZE +#            define FEE_PAGE_SIZE 0x4000  // Page size = 16KByte +#        endif +#        ifndef FEE_PAGE_COUNT +#            define FEE_PAGE_COUNT 1  // How many pages are used +#        endif  #    endif  #endif @@ -40,17 +47,21 @@  #        define FEE_MCU_FLASH_SIZE 32  // Size in Kb  #    elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB)  #        define FEE_MCU_FLASH_SIZE 128  // Size in Kb -#    elif defined(STM32F303xC) +#    elif defined(STM32F303xC) || defined(STM32F401xC)  #        define FEE_MCU_FLASH_SIZE 256  // Size in Kb -#    elif defined(STM32F103xE) +#    elif defined(STM32F103xE) || defined(STM32F401xE) || defined(STM32F411xE)  #        define FEE_MCU_FLASH_SIZE 512  // Size in Kb +#    elif defined(STM32F405xG) +#        define FEE_MCU_FLASH_SIZE 1024  // Size in Kb  #    endif  #endif  /* Start of the emulated eeprom */  #if !defined(FEE_PAGE_BASE_ADDRESS) -#    if 0 -/* TODO: Add support for F4 */ +#    if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) +#        ifndef FEE_PAGE_BASE_ADDRESS +#            define FEE_PAGE_BASE_ADDRESS 0x08004000  // bodge to force 2nd 16k page +#        endif  #    else  #        ifndef FEE_FLASH_BASE  #            define FEE_FLASH_BASE 0x8000000 diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index 6b80ff71c3..8f10903d3d 100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c @@ -23,6 +23,29 @@  #    define FLASH_SR_WRPERR FLASH_SR_WRPRTERR  #endif +#if defined(EEPROM_EMU_STM32F401xC) +#    define FLASH_SR_PGERR (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR) + +#    define FLASH_KEY1 0x45670123U +#    define FLASH_KEY2 0xCDEF89ABU + +static uint8_t ADDR2PAGE(uint32_t Page_Address) { +    switch (Page_Address) { +        case 0x08000000 ... 0x08003FFF: +            return 0; +        case 0x08004000 ... 0x08007FFF: +            return 1; +        case 0x08008000 ... 0x0800BFFF: +            return 2; +        case 0x0800C000 ... 0x0800FFFF: +            return 3; +    } + +    // TODO: bad times... +    return 7; +} +#endif +  /* Delay definition */  #define EraseTimeout ((uint32_t)0x00000FFF)  #define ProgramTimeout ((uint32_t)0x0000001F) @@ -53,7 +76,9 @@ FLASH_Status FLASH_GetStatus(void) {      if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; +#if defined(FLASH_OBR_OPTERR)      if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; +#endif      return FLASH_COMPLETE;  } @@ -95,15 +120,24 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {      if (status == FLASH_COMPLETE) {          /* if the previous operation is completed, proceed to erase the page */ +#if defined(FLASH_CR_SNB) +        FLASH->CR &= ~FLASH_CR_SNB; +        FLASH->CR |= FLASH_CR_SER | (ADDR2PAGE(Page_Address) << FLASH_CR_SNB_Pos); +#else          FLASH->CR |= FLASH_CR_PER;          FLASH->AR = Page_Address; +#endif          FLASH->CR |= FLASH_CR_STRT;          /* Wait for last operation to be completed */          status = FLASH_WaitForLastOperation(EraseTimeout);          if (status != FLASH_TIMEOUT) { -            /* if the erase operation is completed, disable the PER Bit */ +            /* if the erase operation is completed, disable the configured Bits */ +#if defined(FLASH_CR_SNB) +            FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB); +#else              FLASH->CR &= ~FLASH_CR_PER; +#endif          }          FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);      } @@ -126,6 +160,11 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {          status = FLASH_WaitForLastOperation(ProgramTimeout);          if (status == FLASH_COMPLETE) {              /* if the previous operation is completed, proceed to program the new data */ + +#if defined(FLASH_CR_PSIZE) +            FLASH->CR &= ~FLASH_CR_PSIZE; +            FLASH->CR |= FLASH_CR_PSIZE_0; +#endif              FLASH->CR |= FLASH_CR_PG;              *(__IO uint16_t*)Address = Data;              /* Wait for last operation to be completed */ diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 38517e06f0..9310a99920 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c @@ -7,30 +7,12 @@  #include "action.h"  #include "action_util.h"  #include "mousekey.h" +#include "programmable_button.h"  #include "host.h"  #include "suspend.h"  #include "led.h"  #include "wait.h" -#ifdef AUDIO_ENABLE -#    include "audio.h" -#endif /* AUDIO_ENABLE */ - -#ifdef BACKLIGHT_ENABLE -#    include "backlight.h" -#endif - -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -#    include "rgblight.h" -#endif - -#ifdef LED_MATRIX_ENABLE -#    include "led_matrix.h" -#endif -#ifdef RGB_MATRIX_ENABLE -#    include "rgb_matrix.h" -#endif -  /** \brief suspend idle   *   * FIXME: needs doc @@ -40,61 +22,12 @@ void suspend_idle(uint8_t time) {      wait_ms(time);  } -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_user(void) {} -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } -  /** \brief suspend power down   *   * FIXME: needs doc   */  void suspend_power_down(void) { -#ifdef BACKLIGHT_ENABLE -    backlight_set(0); -#endif - -#ifdef LED_MATRIX_ENABLE -    led_matrix_task(); -#endif -#ifdef RGB_MATRIX_ENABLE -    rgb_matrix_task(); -#endif - -    // Turn off LED indicators -    uint8_t leds_off = 0; -#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) -    if (is_backlight_enabled()) { -        // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off -        leds_off |= (1 << USB_LED_CAPS_LOCK); -    } -#endif -    led_set(leds_off); - -    // TODO: figure out what to power down and how -    // shouldn't power down TPM/FTM if we want a breathing LED -    // also shouldn't power down USB -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -    rgblight_suspend(); -#endif - -#if defined(LED_MATRIX_ENABLE) -    led_matrix_set_suspend_state(true); -#endif -#if defined(RGB_MATRIX_ENABLE) -    rgb_matrix_set_suspend_state(true); -#endif -#ifdef AUDIO_ENABLE -    stop_all_notes(); -#endif /* AUDIO_ENABLE */ - -    suspend_power_down_kb(); +    suspend_power_down_quantum();      // on AVR, this enables the watchdog for 15ms (max), and goes to      // SLEEP_MODE_PWR_DOWN @@ -147,23 +80,13 @@ void suspend_wakeup_init(void) {  #ifdef MOUSEKEY_ENABLE      mousekey_clear();  #endif /* MOUSEKEY_ENABLE */ +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    programmable_button_clear(); +#endif /* PROGRAMMABLE_BUTTON_ENABLE */  #ifdef EXTRAKEY_ENABLE      host_system_send(0);      host_consumer_send(0);  #endif /* EXTRAKEY_ENABLE */ -#ifdef BACKLIGHT_ENABLE -    backlight_init(); -#endif /* BACKLIGHT_ENABLE */ -    led_set(host_keyboard_leds()); -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -    rgblight_wakeup(); -#endif -#if defined(LED_MATRIX_ENABLE) -    led_matrix_set_suspend_state(false); -#endif -#if defined(RGB_MATRIX_ENABLE) -    rgb_matrix_set_suspend_state(false); -#endif -    suspend_wakeup_init_kb(); +    suspend_wakeup_init_quantum();  } diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c index f0c396b189..56d4bb0847 100644 --- a/tmk_core/common/host.c +++ b/tmk_core/common/host.c @@ -30,8 +30,9 @@ extern keymap_config_t keymap_config;  #endif  static host_driver_t *driver; -static uint16_t       last_system_report   = 0; -static uint16_t       last_consumer_report = 0; +static uint16_t       last_system_report              = 0; +static uint16_t       last_consumer_report            = 0; +static uint32_t       last_programmable_button_report = 0;  void host_set_driver(host_driver_t *d) { driver = d; } @@ -122,6 +123,16 @@ void host_digitizer_send(digitizer_t *digitizer) {  __attribute__((weak)) void send_digitizer(report_digitizer_t *report) {} +void host_programmable_button_send(uint32_t report) { +    if (report == last_programmable_button_report) return; +    last_programmable_button_report = report; + +    if (!driver) return; +    (*driver->send_programmable_button)(report); +} +  uint16_t host_last_system_report(void) { return last_system_report; }  uint16_t host_last_consumer_report(void) { return last_consumer_report; } + +uint32_t host_last_programmable_button_report(void) { return last_programmable_button_report; } diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h index 2cffef6e15..6b15f0d0c1 100644 --- a/tmk_core/common/host.h +++ b/tmk_core/common/host.h @@ -47,9 +47,11 @@ void    host_keyboard_send(report_keyboard_t *report);  void    host_mouse_send(report_mouse_t *report);  void    host_system_send(uint16_t data);  void    host_consumer_send(uint16_t data); +void    host_programmable_button_send(uint32_t data);  uint16_t host_last_system_report(void);  uint16_t host_last_consumer_report(void); +uint32_t host_last_programmable_button_report(void);  #ifdef __cplusplus  } diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h index 2aebca043d..affd0dcb34 100644 --- a/tmk_core/common/host_driver.h +++ b/tmk_core/common/host_driver.h @@ -29,6 +29,7 @@ typedef struct {      void (*send_mouse)(report_mouse_t *);      void (*send_system)(uint16_t);      void (*send_consumer)(uint16_t); +    void (*send_programmable_button)(uint32_t);  } host_driver_t;  void send_digitizer(report_digitizer_t *report);
\ No newline at end of file diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h index f2223e8063..1adc892f3b 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h @@ -29,6 +29,7 @@ enum hid_report_ids {      REPORT_ID_MOUSE,      REPORT_ID_SYSTEM,      REPORT_ID_CONSUMER, +    REPORT_ID_PROGRAMMABLE_BUTTON,      REPORT_ID_NKRO,      REPORT_ID_JOYSTICK,      REPORT_ID_DIGITIZER @@ -196,6 +197,11 @@ typedef struct {  } __attribute__((packed)) report_extra_t;  typedef struct { +    uint8_t  report_id; +    uint32_t usage; +} __attribute__((packed)) report_programmable_button_t; + +typedef struct {  #ifdef MOUSE_SHARED_EP      uint8_t report_id;  #endif diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h index 95845e4b63..081735f90e 100644 --- a/tmk_core/common/suspend.h +++ b/tmk_core/common/suspend.h @@ -10,8 +10,10 @@ void suspend_wakeup_init(void);  void suspend_wakeup_init_user(void);  void suspend_wakeup_init_kb(void); +void suspend_wakeup_init_quantum(void);  void suspend_power_down_user(void);  void suspend_power_down_kb(void); +void suspend_power_down_quantum(void);  #ifndef USB_SUSPEND_WAKEUP_DELAY  #    define USB_SUSPEND_WAKEUP_DELAY 0 diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c index 68b92d8b43..de24b463b6 100644 --- a/tmk_core/common/sync_timer.c +++ b/tmk_core/common/sync_timer.c @@ -26,7 +26,7 @@ SOFTWARE.  #include "sync_timer.h"  #include "keyboard.h" -#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) +#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)  volatile int32_t sync_timer_ms;  void sync_timer_init(void) { sync_timer_ms = 0; } diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h index 744e2b50d5..9ddef45bb2 100644 --- a/tmk_core/common/sync_timer.h +++ b/tmk_core/common/sync_timer.h @@ -32,7 +32,7 @@ SOFTWARE.  extern "C" {  #endif -#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) +#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)  void     sync_timer_init(void);  void     sync_timer_update(uint32_t time);  uint16_t sync_timer_read(void); diff --git a/tmk_core/common/test/rules.mk b/tmk_core/common/test/rules.mk index 48632a095b..73d2302da7 100644 --- a/tmk_core/common/test/rules.mk +++ b/tmk_core/common/test/rules.mk @@ -16,6 +16,7 @@ eeprom_stm32_tiny_INC := $(eeprom_stm32_INC)  eeprom_stm32_large_INC := $(eeprom_stm32_INC)  eeprom_stm32_SRC := \ +	$(TOP_DIR)/drivers/eeprom/eeprom_driver.c \  	$(TMK_PATH)/common/test/eeprom_stm32_tests.cpp \  	$(TMK_PATH)/common/test/flash_stm32_mock.c \  	$(TMK_PATH)/common/chibios/eeprom_stm32.c diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index b61f2f5463..30c87a0f12 100644 --- a/tmk_core/protocol.mk +++ b/tmk_core/protocol.mk @@ -45,15 +45,6 @@ ifeq ($(strip $(SERIAL_MOUSE_USE_UART)), yes)      SRC += $(PROTOCOL_DIR)/serial_uart.c  endif -ifeq ($(strip $(ADB_MOUSE_ENABLE)), yes) -    OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE -endif - -ifeq ($(strip $(XT_ENABLE)), yes) -    SRC += $(PROTOCOL_DIR)/xt_interrupt.c -    OPT_DEFS += -DXT_ENABLE -endif -  ifeq ($(strip $(USB_HID_ENABLE)), yes)      include $(TMK_DIR)/protocol/usb_hid.mk  endif diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c deleted file mode 100644 index 367f1b09fa..0000000000 --- a/tmk_core/protocol/adb.c +++ /dev/null @@ -1,535 +0,0 @@ -/* -Copyright 2011-19 Jun WAKO <wakojun@gmail.com> -Copyright 2013 Shay Green <gblargg@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#include <stdbool.h> -#include <util/delay.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include "adb.h" -#include "print.h" - -// GCC doesn't inline functions normally -#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) -#define data_hi() (ADB_DDR &= ~(1 << ADB_DATA_BIT)) -#define data_in() (ADB_PIN & (1 << ADB_DATA_BIT)) - -#ifdef ADB_PSW_BIT -static inline void psw_lo(void); -static inline void psw_hi(void); -static inline bool psw_in(void); -#endif - -static inline void     attention(void); -static inline void     place_bit0(void); -static inline void     place_bit1(void); -static inline void     send_byte(uint8_t data); -static inline uint16_t wait_data_lo(uint16_t us); -static inline uint16_t wait_data_hi(uint16_t us); - -void adb_host_init(void) { -    ADB_PORT &= ~(1 << ADB_DATA_BIT); -    data_hi(); -#ifdef ADB_PSW_BIT -    psw_hi(); -#endif -} - -#ifdef ADB_PSW_BIT -bool adb_host_psw(void) { return psw_in(); } -#endif - -/* - * Don't call this in a row without the delay, otherwise it makes some of poor controllers - * overloaded and misses strokes. Recommended interval is 12ms. - * - * Thanks a lot, blargg! - * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> - * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> - */ -uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); } - -#ifdef ADB_MOUSE_ENABLE -__attribute__((weak)) void adb_mouse_init(void) { return; } - -__attribute__((weak)) void adb_mouse_task(void) { return; } - -uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); } -#endif - -// 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) { -    for (int8_t i = 0; i < len; i++) buf[i] = 0; - -    cli(); -    attention(); -    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 0; -    } -    if (!wait_data_lo(500)) {  // Tlt/Stop to Start(140-260us) -        sei(); -        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 = 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;  // no more bit or after stop bit - -        uint8_t hi = (uint8_t)wait_data_lo(lo); -        if (!hi) goto error;  // stop bit extedned by Srq? - -        if (n / 8 >= len) continue;  // can't store in buf - -        buf[n / 8] <<= 1; -        if ((130 - lo) < (lo - hi)) { -            buf[n / 8] |= 1; -        } -    } while (++n); - -error: -    sei(); -    return n / 8; -} - -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 | reg); -    place_bit0();  // Stopbit(0) -    // TODO: Service Request -    _delay_us(200);  // Tlt/Stop to Start -    place_bit1();    // Startbit(1) -    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 led) { -    // Listen Register2 -    //  upper byte: not used -    //  lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock -    adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07); -} - -#ifdef ADB_PSW_BIT -static inline void psw_lo() { -    ADB_DDR |= (1 << ADB_PSW_BIT); -    ADB_PORT &= ~(1 << ADB_PSW_BIT); -} -static inline void psw_hi() { -    ADB_PORT |= (1 << ADB_PSW_BIT); -    ADB_DDR &= ~(1 << ADB_PSW_BIT); -} -static inline bool psw_in() { -    ADB_PORT |= (1 << ADB_PSW_BIT); -    ADB_DDR &= ~(1 << ADB_PSW_BIT); -    return ADB_PIN & (1 << ADB_PSW_BIT); -} -#endif - -static inline void attention(void) { -    data_lo(); -    _delay_us(800 - 35);  // bit1 holds lo for 35 more -    place_bit1(); -} - -static inline void place_bit0(void) { -    data_lo(); -    _delay_us(65); -    data_hi(); -    _delay_us(35); -} - -static inline void place_bit1(void) { -    data_lo(); -    _delay_us(35); -    data_hi(); -    _delay_us(65); -} - -static inline void send_byte(uint8_t data) { -    for (int i = 0; i < 8; i++) { -        if (data & (0x80 >> i)) -            place_bit1(); -        else -            place_bit0(); -    } -} - -// These are carefully coded to take 6 cycles of overhead. -// inline asm approach became too convoluted -static inline uint16_t wait_data_lo(uint16_t us) { -    do { -        if (!data_in()) break; -        _delay_us(1 - (6 * 1000000.0 / F_CPU)); -    } while (--us); -    return us; -} - -static inline uint16_t wait_data_hi(uint16_t us) { -    do { -        if (data_in()) break; -        _delay_us(1 - (6 * 1000000.0 / F_CPU)); -    } while (--us); -    return us; -} - -/* -ADB Protocol -============ - -Resources ---------- -ADB - The Untold Story: Space Aliens Ate My Mouse -    http://developer.apple.com/legacy/mac/library/#technotes/hw/hw_01.html -ADB Manager -    http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Devices/ADB_Manager.pdf -    Service request(5-17) -Apple IIgs Hardware Reference Second Edition [Chapter6 p121] -    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple%20IIgs%20Hardware%20Reference.pdf -ADB Keycode -    http://72.0.193.250/Documentation/macppc/adbkeycodes/ -    http://m0115.web.fc2.com/m0115.jpg -    [Inside Macintosh volume V, pages 191-192] -    http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c -ADB Signaling -    http://kbdbabel.sourceforge.net/doc/kbd_signaling_pcxt_ps2_adb.pdf -ADB Overview & History -    http://en.wikipedia.org/wiki/Apple_Desktop_Bus -Microchip Application Note: ADB device(with code for PIC16C) -    http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011062 -AVR ATtiny2131 ADB to PS/2 converter(Japanese) -    http://hp.vector.co.jp/authors/VA000177/html/KeyBoardA5DEA5CBA5A2II.html - - -Pinouts -------- -    ADB female socket from the front: -    __________ -    |        | <--- top -    | 4o  o3 | -    |2o    o1| -    |   ==   | -    |________| <--- bottom -      |    |   <--- 4pins - - -    ADB female socket from bottom: - -    ========== <--- front -    |        | -    |        | -    |2o    o1| -    |4o    o3| -    ---------- <--- back - -    1: Data -    2: Power SW(low when press Power key) -    3: Vcc(5V) -    4: GND - - -Commands --------- -    ADB command is 1byte and consists of 4bit-address, 2bit-command -    type and 2bit-register. The commands are always sent by Host. - -    Command format: -    7 6 5 4 3 2 1 0 -    | | | |------------ address -            | |-------- command type -                | |---- register - -    bits                commands -    ------------------------------------------------------ -    - - - - 0 0 0 0     Send Reset(reset all devices) -    A A A A 0 0 0 1     Flush(reset a device) -    - - - - 0 0 1 0     Reserved -    - - - - 0 0 1 1     Reserved -    - - - - 0 1 - -     Reserved -    A A A A 1 0 R R     Listen(write to a device) -    A A A A 1 1 R R     Talk(read from a device) - -    The command to read keycodes from keyboard is 0x2C which -    consist of keyboard address 2 and Talk against register 0. - -    Address: -    2:  keyboard -    3:  mice - -    Registers: -    0: application(keyboard uses this to store its data.) -    1: application -    2: application(keyboard uses this for LEDs and state of modifiers) -    3: status and command - - -Communication -------------- -    This is a minimum information for keyboard communication. -    See "Resources" for detail. - -    Signaling: - -    ~~~~____________~~||||||||||||__~~~~~_~~|||||||||||||||__~~~~ - -        |800us     |  |7 Command 0|  |   |  |15-64  Data  0|Stopbit(0) -        +Attention |              |  |   +Startbit(1) -                   +Startbit(1)   |  +Tlt(140-260us) -                                  +stopbit(0) - -    Bit cells: - -    bit0: ______~~~ -          65    :35us - -    bit1: ___~~~~~~ -          35 :65us - -    bit0 low time: 60-70% of bit cell(42-91us) -    bit1 low time: 30-40% of bit cell(21-52us) -    bit cell time: 70-130us -    [from Apple IIgs Hardware Reference Second Edition] - -    Criterion for bit0/1: -    After 55us if line is low/high then bit is 0/1. - -    Attention & start bit: -    Host asserts low in 560-1040us then places start bit(1). - -    Tlt(Stop to Start): -    Bus stays high in 140-260us then device places start bit(1). - -    Global reset: -    Host asserts low in 2.8-5.2ms. All devices are forced to reset. - -    Service request from device(Srq): -    Device can request to send at commad(Global only?) stop bit. -    Requesting device keeps low for 140-260us at stop bit of command. - - -Keyboard Data(Register0) -    This 16bit data can contains two keycodes and two released flags. -    First keycode is palced in upper byte. When one keyocode is sent, -    lower byte is 0xFF. -    Release flag is 1 when key is released. - -    1514 . . . . . 8 7 6 . . . . . 0 -     | | | | | | | | | +-+-+-+-+-+-+-   Keycode2 -     | | | | | | | | +---------------   Released2(1 when the key is released) -     | +-+-+-+-+-+-+-----------------   Keycode1 -     +-------------------------------   Released1(1 when the key is released) - -    Keycodes: -    Scancode consists of 7bit keycode and 1bit release flag. -    Device can send two keycodes at once. If just one keycode is sent -    keycode1 contains it and keyocode2 is 0xFF. - -    Power switch: -    You can read the state from PSW line(active low) however -    the switch has a special scancode 0x7F7F, so you can -    also read from Data line. It uses 0xFFFF for release scancode. - -Keyboard LEDs & state of keys(Register2) -    This register hold current state of three LEDs and nine keys. -    The state of LEDs can be changed by sending Listen command. - -    1514 . . . . . . 7 6 5 . 3 2 1 0 -     | | | | | | | | | | | | | | | +-   LED1(NumLock) -     | | | | | | | | | | | | | | +---   LED2(CapsLock) -     | | | | | | | | | | | | | +-----   LED3(ScrollLock) -     | | | | | | | | | | +-+-+-------   Reserved -     | | | | | | | | | +-------------   ScrollLock -     | | | | | | | | +---------------   NumLock -     | | | | | | | +-----------------   Apple/Command -     | | | | | | +-------------------   Option -     | | | | | +---------------------   Shift -     | | | | +-----------------------   Control -     | | | +-------------------------   Reset/Power -     | | +---------------------------   CapsLock -     | +-----------------------------   Delete -     +-------------------------------   Reserved - -Address, Handler ID and bits(Register3) -    1514131211 . . 8 7 . . . . . . 0 -     | | | | | | | | | | | | | | | | -     | | | | | | | | +-+-+-+-+-+-+-+-   Handler ID -     | | | | +-+-+-+-----------------   Address -     | | | +-------------------------   0 -     | | +---------------------------   Service request enable(1 = enabled) -     | +-----------------------------   Exceptional event(alwyas 1 if not used) -     +-------------------------------   0 - -ADB Bit Cells -    bit cell time: 70-130us -    low part of bit0: 60-70% of bit cell -    low part of bit1: 30-40% of bit cell - -       bit cell time         70us        130us -       -------------------------------------------- -       low  part of bit0     42-49       78-91 -       high part of bit0     21-28       39-52 -       low  part of bit1     21-28       39-52 -       high part of bit1     42-49       78-91 - - -    bit0: -       70us bit cell: -         ____________~~~~~~ -         42-49        21-28 - -       130us bit cell: -         ____________~~~~~~ -         78-91        39-52 - -    bit1: -       70us bit cell: -         ______~~~~~~~~~~~~ -         21-28        42-49 - -       130us bit cell: -         ______~~~~~~~~~~~~ -         39-52        78-91 - -    [from Apple IIgs Hardware Reference Second Edition] - -Keyboard Handle ID -    Apple Standard Keyboard M0116:      0x01 -    Apple Extended Keyboard M0115:      0x02 -    Apple Extended Keyboard II M3501:   0x02 -    Apple Adjustable Keybaord:          0x10 - -    http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 - -END_OF_ADB -*/ diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h deleted file mode 100644 index fe8becc2d5..0000000000 --- a/tmk_core/protocol/adb.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright 2011-19 Jun WAKO <wakojun@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -#include <stdint.h> -#include <stdbool.h> - -#if !(defined(ADB_PORT) && defined(ADB_PIN) && defined(ADB_DDR) && defined(ADB_DATA_BIT)) -#    error "ADB port setting is required in config.h" -#endif - -#define ADB_POWER 0x7F -#define ADB_CAPS 0x39 - -/* ADB commands */ -// Default Address -#define ADB_ADDR_0 0 -#define ADB_ADDR_DONGLE 1 -#define ADB_ADDR_KEYBOARD 2 -#define ADB_ADDR_MOUSE 3 -#define ADB_ADDR_TABLET 4 -#define ADB_ADDR_APPLIANCE 7 -#define ADB_ADDR_8 8 -#define ADB_ADDR_9 9 -#define ADB_ADDR_10 10 -#define ADB_ADDR_11 11 -#define ADB_ADDR_12 12 -#define ADB_ADDR_13 13 -#define ADB_ADDR_14 14 -#define ADB_ADDR_15 15 -// for temporary purpose, do not use for polling -#define ADB_ADDR_TMP 15 -#define ADB_ADDR_MOUSE_POLL 10 -// Command Type -#define ADB_CMD_RESET 0 -#define ADB_CMD_FLUSH 1 -#define ADB_CMD_LISTEN 8 -#define ADB_CMD_TALK 12 -// Register -#define ADB_REG_0 0 -#define ADB_REG_1 1 -#define ADB_REG_2 2 -#define ADB_REG_3 3 - -/* ADB keyboard handler id */ -#define ADB_HANDLER_STD 0x01        /* IIGS, M0116 */ -#define ADB_HANDLER_AEK 0x02        /* M0115, M3501 */ -#define ADB_HANDLER_AEK_RMOD 0x03   /* M0115, M3501, alternate mode enableing right modifiers */ -#define ADB_HANDLER_STD_ISO 0x04    /* M0118, ISO swapping keys */ -#define ADB_HANDLER_AEK_ISO 0x05    /* M0115, M3501, ISO swapping keys */ -#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */ -#define ADB_HANDLER_CLASSIC1_MOUSE 0x01 -#define ADB_HANDLER_CLASSIC2_MOUSE 0x02 -#define ADB_HANDLER_EXTENDED_MOUSE 0x04 -#define ADB_HANDLER_TURBO_MOUSE 0x32 - -// ADB host -void     adb_host_init(void); -bool     adb_host_psw(void); -uint16_t adb_host_talk(uint8_t addr, uint8_t reg); -uint8_t  adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); -void     adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); -void     adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); -void     adb_host_flush(uint8_t addr); -void     adb_host_kbd_led(uint8_t led); -uint16_t adb_host_kbd_recv(void); -uint16_t adb_host_mouse_recv(void); - -// ADB Mouse -void adb_mouse_task(void); -void adb_mouse_init(void); diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index 78a2e3fcbb..c860328c80 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c @@ -27,6 +27,7 @@  #include "keyboard.h"  #include "action.h"  #include "action_util.h" +#include "usb_device_state.h"  #include "mousekey.h"  #include "led.h"  #include "sendchar.h" @@ -42,12 +43,6 @@  #ifdef SLEEP_LED_ENABLE  #    include "sleep_led.h"  #endif -#ifdef SERIAL_LINK_ENABLE -#    include "serial_link/system/serial_link.h" -#endif -#ifdef VISUALIZER_ENABLE -#    include "visualizer/visualizer.h" -#endif  #ifdef MIDI_ENABLE  #    include "qmk_midi.h"  #endif @@ -139,6 +134,8 @@ void boardInit(void) {  }  void protocol_setup(void) { +    usb_device_state_init(); +      // TESTING      // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); @@ -154,19 +151,11 @@ void protocol_init(void) {      setup_midi();  #endif -#ifdef SERIAL_LINK_ENABLE -    init_serial_link(); -#endif - -#ifdef VISUALIZER_ENABLE -    visualizer_init(); -#endif -      host_driver_t *driver = NULL; -    /* Wait until the USB or serial link is active */ +    /* Wait until USB is active */      while (true) { -#if defined(WAIT_FOR_USB) || defined(SERIAL_LINK_ENABLE) +#if defined(WAIT_FOR_USB)          if (USB_DRIVER.state == USB_ACTIVE) {              driver = &chibios_driver;              break; @@ -175,13 +164,6 @@ void protocol_init(void) {          driver = &chibios_driver;          break;  #endif -#ifdef SERIAL_LINK_ENABLE -        if (is_serial_link_connected()) { -            driver = get_serial_link_driver(); -            break; -        } -        serial_link_update(); -#endif          wait_ms(50);      } @@ -211,14 +193,8 @@ void protocol_task(void) {  #if !defined(NO_USB_STARTUP_CHECK)      if (USB_DRIVER.state == USB_SUSPENDED) {          print("[s]"); -#    ifdef VISUALIZER_ENABLE -        visualizer_suspend(); -#    endif          while (USB_DRIVER.state == USB_SUSPENDED) {              /* Do this in the suspended state */ -#    ifdef SERIAL_LINK_ENABLE -            serial_link_update(); -#    endif              suspend_power_down();  // on AVR this deep sleeps for 15ms              /* Remote wakeup */              if (suspend_wakeup_condition()) { @@ -232,10 +208,6 @@ void protocol_task(void) {  #    ifdef MOUSEKEY_ENABLE          mousekey_send();  #    endif /* MOUSEKEY_ENABLE */ - -#    ifdef VISUALIZER_ENABLE -        visualizer_resume(); -#    endif      }  #endif diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index cc282e6a9b..9b139b3992 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -39,6 +39,7 @@  #    include "led.h"  #endif  #include "wait.h" +#include "usb_device_state.h"  #include "usb_descriptor.h"  #include "usb_driver.h" @@ -412,6 +413,7 @@ static inline bool usb_event_queue_dequeue(usbevent_t *event) {  }  static inline void usb_event_suspend_handler(void) { +    usb_device_state_set_suspend(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);  #ifdef SLEEP_LED_ENABLE      sleep_led_enable();  #endif /* SLEEP_LED_ENABLE */ @@ -419,6 +421,7 @@ static inline void usb_event_suspend_handler(void) {  static inline void usb_event_wakeup_handler(void) {      suspend_wakeup_init(); +    usb_device_state_set_resume(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);  #ifdef SLEEP_LED_ENABLE      sleep_led_disable();      // NOTE: converters may not accept this @@ -440,6 +443,15 @@ void usb_event_queue_task(void) {                  last_suspend_state = false;                  usb_event_wakeup_handler();                  break; +            case USB_EVENT_CONFIGURED: +                usb_device_state_set_configuration(USB_DRIVER.configuration != 0, USB_DRIVER.configuration); +                break; +            case USB_EVENT_UNCONFIGURED: +                usb_device_state_set_configuration(false, 0); +                break; +            case USB_EVENT_RESET: +                usb_device_state_set_reset(); +                break;              default:                  // Nothing to do, we don't handle it.                  break; @@ -482,13 +494,14 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {              if (last_suspend_state) {                  usb_event_queue_enqueue(USB_EVENT_WAKEUP);              } +            usb_event_queue_enqueue(USB_EVENT_CONFIGURED);              return;          case USB_EVENT_SUSPEND: -            usb_event_queue_enqueue(USB_EVENT_SUSPEND);              /* Falls into.*/          case USB_EVENT_UNCONFIGURED:              /* Falls into.*/          case USB_EVENT_RESET: +            usb_event_queue_enqueue(event);              for (int i = 0; i < NUM_USB_DRIVERS; i++) {                  chSysLockFromISR();                  /* Disconnection event on suspend.*/ diff --git a/tmk_core/protocol/ibm4704.c b/tmk_core/protocol/ibm4704.c deleted file mode 100644 index a19443976e..0000000000 --- a/tmk_core/protocol/ibm4704.c +++ /dev/null @@ -1,185 +0,0 @@ -/* -Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com> -*/ -#include <stdbool.h> -#include <util/delay.h> -#include "debug.h" -#include "ring_buffer.h" -#include "ibm4704.h" - -#define WAIT(stat, us, err)      \ -    do {                         \ -        if (!wait_##stat(us)) {  \ -            ibm4704_error = err; \ -            goto ERROR;          \ -        }                        \ -    } while (0) - -uint8_t ibm4704_error = 0; - -void ibm4704_init(void) { -    inhibit();  // keep keyboard from sending -    IBM4704_INT_INIT(); -    IBM4704_INT_ON(); -    idle();  // allow keyboard sending -} - -/* -Host to Keyboard ----------------- -Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part. - -        ____        __   __   __   __   __   __   __   __   __   ________ -Clock       \______/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/ -            ^   ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___ -Data    ____|__/    X____X____X____X____X____X____X____X____X____X   \___ -            |  Start   0    1    2    3    4    5    6    7    P   Stop -            Request by host - -Start bit:  can be long as 300-350us. -Request:    Host pulls Clock line down to request to send a command. -Timing:     After Request keyboard pull up Data and down Clock line to low for start bit. -            After request host release Clock line once Data line becomes hi. -            Host writes a bit while Clock is hi and Keyboard reads while low. -Stop bit:   Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo. -*/ -uint8_t ibm4704_send(uint8_t data) { -    bool parity   = true;  // odd parity -    ibm4704_error = 0; - -    IBM4704_INT_OFF(); - -    /* Request to send */ -    idle(); -    clock_lo(); - -    /* wait for Start bit(Clock:lo/Data:hi) */ -    WAIT(data_hi, 300, 0x30); - -    /* Data bit */ -    for (uint8_t i = 0; i < 8; i++) { -        WAIT(clock_hi, 100, 0x40 + i); -        if (data & (1 << i)) { -            parity = !parity; -            data_hi(); -        } else { -            data_lo(); -        } -        WAIT(clock_lo, 100, 0x48 + i); -    } - -    /* Parity bit */ -    WAIT(clock_hi, 100, 0x34); -    if (parity) { -        data_hi(); -    } else { -        data_lo(); -    } -    WAIT(clock_lo, 100, 0x35); - -    /* Stop bit */ -    WAIT(clock_hi, 100, 0x34); -    data_hi(); - -    /* End */ -    WAIT(data_lo, 100, 0x36); - -    idle(); -    IBM4704_INT_ON(); -    return 0; -ERROR: -    idle(); -    if (ibm4704_error > 0x30) { -        xprintf("S:%02X ", ibm4704_error); -    } -    IBM4704_INT_ON(); -    return -1; -} - -/* wait forever to receive data */ -uint8_t ibm4704_recv_response(void) { -    while (!rbuf_has_data()) { -        _delay_ms(1); -    } -    return rbuf_dequeue(); -} - -uint8_t ibm4704_recv(void) { -    if (rbuf_has_data()) { -        return rbuf_dequeue(); -    } else { -        return -1; -    } -} - -/* -Keyboard to Host ----------------- -Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part. - -        ____       __   __   __   __   __   __   __   __   __   _______ -Clock       \_____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/ -             ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ -Data    ____/    X____X____X____X____X____X____X____X____X____X________ -            Start   0    1    2    3    4    5    6    7    P  Stop - -Start bit:  can be long as 300-350us. -Inhibit:    Pull Data line down to inhibit keyboard to send. -Timing:     Host reads bit while Clock is hi.(rising edge) -Stop bit:   Keyboard pulls down Data line to lo after 9th clock. -*/ -ISR(IBM4704_INT_VECT) { -    static enum { BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, STOP } state = BIT0; -    // LSB first -    static uint8_t data = 0; -    // Odd parity -    static uint8_t parity = false; - -    ibm4704_error = 0; - -    switch (state) { -        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; -            break; -        case STOP: -            // Data:Low -            WAIT(data_lo, 100, state); -            if (!rbuf_enqueue(data)) { -                print("rbuf: full\n"); -            } -            ibm4704_error = IBM4704_ERR_NONE; -            goto DONE; -            break; -        default: -            goto ERROR; -    } -    state++; -    goto RETURN; -ERROR: -    ibm4704_error = state; -    while (ibm4704_send(0xFE)) _delay_ms(1);  // resend -    xprintf("R:%02X%02X\n", state, data); -DONE: -    state  = BIT0; -    data   = 0; -    parity = false; -RETURN: -    return; -} diff --git a/tmk_core/protocol/ibm4704.h b/tmk_core/protocol/ibm4704.h deleted file mode 100644 index 4f88d148b3..0000000000 --- a/tmk_core/protocol/ibm4704.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2014 Jun WAKO <wakojun@gmail.com> -*/ - -#pragma once - -#define IBM4704_ERR_NONE 0 -#define IBM4704_ERR_PARITY 0x70 - -void    ibm4704_init(void); -uint8_t ibm4704_send(uint8_t data); -uint8_t ibm4704_recv_response(void); -uint8_t ibm4704_recv(void); - -/* Check pin configuration */ -#if !(defined(IBM4704_CLOCK_PORT) && defined(IBM4704_CLOCK_PIN) && defined(IBM4704_CLOCK_DDR) && defined(IBM4704_CLOCK_BIT)) -#    error "ibm4704 clock pin configuration is required in config.h" -#endif - -#if !(defined(IBM4704_DATA_PORT) && defined(IBM4704_DATA_PIN) && defined(IBM4704_DATA_DDR) && defined(IBM4704_DATA_BIT)) -#    error "ibm4704 data pin configuration is required in config.h" -#endif - -/*-------------------------------------------------------------------- - * static functions - *------------------------------------------------------------------*/ -static inline void clock_lo(void) { -    IBM4704_CLOCK_PORT &= ~(1 << IBM4704_CLOCK_BIT); -    IBM4704_CLOCK_DDR |= (1 << IBM4704_CLOCK_BIT); -} -static inline void clock_hi(void) { -    /* input with pull up */ -    IBM4704_CLOCK_DDR &= ~(1 << IBM4704_CLOCK_BIT); -    IBM4704_CLOCK_PORT |= (1 << IBM4704_CLOCK_BIT); -} -static inline bool clock_in(void) { -    IBM4704_CLOCK_DDR &= ~(1 << IBM4704_CLOCK_BIT); -    IBM4704_CLOCK_PORT |= (1 << IBM4704_CLOCK_BIT); -    _delay_us(1); -    return IBM4704_CLOCK_PIN & (1 << IBM4704_CLOCK_BIT); -} -static inline void data_lo(void) { -    IBM4704_DATA_PORT &= ~(1 << IBM4704_DATA_BIT); -    IBM4704_DATA_DDR |= (1 << IBM4704_DATA_BIT); -} -static inline void data_hi(void) { -    /* input with pull up */ -    IBM4704_DATA_DDR &= ~(1 << IBM4704_DATA_BIT); -    IBM4704_DATA_PORT |= (1 << IBM4704_DATA_BIT); -} -static inline bool data_in(void) { -    IBM4704_DATA_DDR &= ~(1 << IBM4704_DATA_BIT); -    IBM4704_DATA_PORT |= (1 << IBM4704_DATA_BIT); -    _delay_us(1); -    return IBM4704_DATA_PIN & (1 << IBM4704_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; -} - -/* idle state that device can send */ -static inline void idle(void) { -    clock_hi(); -    data_hi(); -} - -/* inhibit device to send - * keyboard checks Data line on start bit(Data:hi) and it stops sending if Data line is low. - */ -static inline void inhibit(void) { -    clock_hi(); -    data_lo(); -} diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk index c8935dacb7..00fec478ac 100644 --- a/tmk_core/protocol/lufa.mk +++ b/tmk_core/protocol/lufa.mk @@ -3,7 +3,6 @@ LUFA_DIR = protocol/lufa  # Path to the LUFA library  LUFA_PATH = $(LIB_PATH)/lufa -  # Create the LUFA source path variables by including the LUFA makefile  ifneq (, $(wildcard $(LUFA_PATH)/LUFA/Build/lufa_sources.mk))      # New build system from 20120730 @@ -22,23 +21,6 @@ ifeq ($(strip $(MIDI_ENABLE)), yes)  	include $(TMK_PATH)/protocol/midi.mk  endif -ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) -	LUFA_SRC += outputselect.c \ -		$(TMK_DIR)/protocol/serial_uart.c -endif - -ifeq ($(strip $(BLUETOOTH)), AdafruitBLE) -	LUFA_SRC += spi_master.c \ -		analog.c \ -		outputselect.c \ -		$(LUFA_DIR)/adafruit_ble.cpp -endif - -ifeq ($(strip $(BLUETOOTH)), RN42) -	LUFA_SRC += outputselect.c \ -		$(TMK_DIR)/protocol/serial_uart.c -endif -  ifeq ($(strip $(VIRTSER_ENABLE)), yes)  	LUFA_SRC += $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CDCClassDevice.c  endif @@ -50,19 +32,10 @@ SRC += $(LUFA_DIR)/usb_util.c  VPATH += $(TMK_PATH)/$(LUFA_DIR)  VPATH += $(LUFA_PATH) -# Option modules -#ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE) -#endif - -#ifdef EXTRAKEY_ENABLE -#endif -  # LUFA library compile-time options and predefined tokens  LUFA_OPTS  = -DUSB_DEVICE_ONLY  LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS  LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" -#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT -LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8  LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8  LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1 diff --git a/tmk_core/protocol/lufa/adafruit_ble.cpp b/tmk_core/protocol/lufa/adafruit_ble.cpp deleted file mode 100644 index 3f2cc35734..0000000000 --- a/tmk_core/protocol/lufa/adafruit_ble.cpp +++ /dev/null @@ -1,701 +0,0 @@ -#include "adafruit_ble.h" - -#include <stdio.h> -#include <stdlib.h> -#include <alloca.h> -#include "debug.h" -#include "timer.h" -#include "action_util.h" -#include "ringbuffer.hpp" -#include <string.h> -#include "spi_master.h" -#include "wait.h" -#include "analog.h" -#include "progmem.h" - -// These are the pin assignments for the 32u4 boards. -// You may define them to something else in your config.h -// if yours is wired up differently. -#ifndef AdafruitBleResetPin -#    define AdafruitBleResetPin D4 -#endif - -#ifndef AdafruitBleCSPin -#    define AdafruitBleCSPin B4 -#endif - -#ifndef AdafruitBleIRQPin -#    define AdafruitBleIRQPin E6 -#endif - -#ifndef AdafruitBleSpiClockSpeed -#    define AdafruitBleSpiClockSpeed 4000000UL  // SCK frequency -#endif - -#define SCK_DIVISOR (F_CPU / AdafruitBleSpiClockSpeed) - -#define SAMPLE_BATTERY -#define ConnectionUpdateInterval 1000 /* milliseconds */ - -#ifndef BATTERY_LEVEL_PIN -#    define BATTERY_LEVEL_PIN B5 -#endif - -static struct { -    bool is_connected; -    bool initialized; -    bool configured; - -#define ProbedEvents 1 -#define UsingEvents 2 -    bool event_flags; - -#ifdef SAMPLE_BATTERY -    uint16_t last_battery_update; -    uint32_t vbat; -#endif -    uint16_t last_connection_update; -} state; - -// Commands are encoded using SDEP and sent via SPI -// https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/blob/master/SDEP.md - -#define SdepMaxPayload 16 -struct sdep_msg { -    uint8_t type; -    uint8_t cmd_low; -    uint8_t cmd_high; -    struct __attribute__((packed)) { -        uint8_t len : 7; -        uint8_t more : 1; -    }; -    uint8_t payload[SdepMaxPayload]; -} __attribute__((packed)); - -// The recv latency is relatively high, so when we're hammering keys quickly, -// we want to avoid waiting for the responses in the matrix loop.  We maintain -// a short queue for that.  Since there is quite a lot of space overhead for -// the AT command representation wrapped up in SDEP, we queue the minimal -// information here. - -enum queue_type { -    QTKeyReport,  // 1-byte modifier + 6-byte key report -    QTConsumer,   // 16-bit key code -#ifdef MOUSE_ENABLE -    QTMouseMove,  // 4-byte mouse report -#endif -}; - -struct queue_item { -    enum queue_type queue_type; -    uint16_t        added; -    union __attribute__((packed)) { -        struct __attribute__((packed)) { -            uint8_t modifier; -            uint8_t keys[6]; -        } key; - -        uint16_t consumer; -        struct __attribute__((packed)) { -            int8_t  x, y, scroll, pan; -            uint8_t buttons; -        } mousemove; -    }; -}; - -// Items that we wish to send -static RingBuffer<queue_item, 40> send_buf; -// Pending response; while pending, we can't send any more requests. -// This records the time at which we sent the command for which we -// are expecting a response. -static RingBuffer<uint16_t, 2> resp_buf; - -static bool process_queue_item(struct queue_item *item, uint16_t timeout); - -enum sdep_type { -    SdepCommand       = 0x10, -    SdepResponse      = 0x20, -    SdepAlert         = 0x40, -    SdepError         = 0x80, -    SdepSlaveNotReady = 0xFE,  // Try again later -    SdepSlaveOverflow = 0xFF,  // You read more data than is available -}; - -enum ble_cmd { -    BleInitialize = 0xBEEF, -    BleAtWrapper  = 0x0A00, -    BleUartTx     = 0x0A01, -    BleUartRx     = 0x0A02, -}; - -enum ble_system_event_bits { -    BleSystemConnected    = 0, -    BleSystemDisconnected = 1, -    BleSystemUartRx       = 8, -    BleSystemMidiRx       = 10, -}; - -#define SdepTimeout 150             /* milliseconds */ -#define SdepShortTimeout 10         /* milliseconds */ -#define SdepBackOff 25              /* microseconds */ -#define BatteryUpdateInterval 10000 /* milliseconds */ - -static bool at_command(const char *cmd, char *resp, uint16_t resplen, bool verbose, uint16_t timeout = SdepTimeout); -static bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose = false); - -// Send a single SDEP packet -static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) { -    spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR); -    uint16_t timerStart = timer_read(); -    bool     success    = false; -    bool     ready      = false; - -    do { -        ready = spi_write(msg->type) != SdepSlaveNotReady; -        if (ready) { -            break; -        } - -        // Release it and let it initialize -        spi_stop(); -        wait_us(SdepBackOff); -        spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR); -    } while (timer_elapsed(timerStart) < timeout); - -    if (ready) { -        // Slave is ready; send the rest of the packet -        spi_transmit(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len); -        success = true; -    } - -    spi_stop(); - -    return success; -} - -static inline void sdep_build_pkt(struct sdep_msg *msg, uint16_t command, const uint8_t *payload, uint8_t len, bool moredata) { -    msg->type     = SdepCommand; -    msg->cmd_low  = command & 0xFF; -    msg->cmd_high = command >> 8; -    msg->len      = len; -    msg->more     = (moredata && len == SdepMaxPayload) ? 1 : 0; - -    static_assert(sizeof(*msg) == 20, "msg is correctly packed"); - -    memcpy(msg->payload, payload, len); -} - -// Read a single SDEP packet -static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) { -    bool     success    = false; -    uint16_t timerStart = timer_read(); -    bool     ready      = false; - -    do { -        ready = readPin(AdafruitBleIRQPin); -        if (ready) { -            break; -        } -        wait_us(1); -    } while (timer_elapsed(timerStart) < timeout); - -    if (ready) { -        spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR); - -        do { -            // Read the command type, waiting for the data to be ready -            msg->type = spi_read(); -            if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) { -                // Release it and let it initialize -                spi_stop(); -                wait_us(SdepBackOff); -                spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR); -                continue; -            } - -            // Read the rest of the header -            spi_receive(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload))); - -            // and get the payload if there is any -            if (msg->len <= SdepMaxPayload) { -                spi_receive(msg->payload, msg->len); -            } -            success = true; -            break; -        } while (timer_elapsed(timerStart) < timeout); - -        spi_stop(); -    } -    return success; -} - -static void resp_buf_read_one(bool greedy) { -    uint16_t last_send; -    if (!resp_buf.peek(last_send)) { -        return; -    } - -    if (readPin(AdafruitBleIRQPin)) { -        struct sdep_msg msg; - -    again: -        if (sdep_recv_pkt(&msg, SdepTimeout)) { -            if (!msg.more) { -                // We got it; consume this entry -                resp_buf.get(last_send); -                dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send)); -            } - -            if (greedy && resp_buf.peek(last_send) && readPin(AdafruitBleIRQPin)) { -                goto again; -            } -        } - -    } else if (timer_elapsed(last_send) > SdepTimeout * 2) { -        dprintf("waiting_for_result: timeout, resp_buf size %d\n", (int)resp_buf.size()); - -        // Timed out: consume this entry -        resp_buf.get(last_send); -    } -} - -static void send_buf_send_one(uint16_t timeout = SdepTimeout) { -    struct queue_item item; - -    // Don't send anything more until we get an ACK -    if (!resp_buf.empty()) { -        return; -    } - -    if (!send_buf.peek(item)) { -        return; -    } -    if (process_queue_item(&item, timeout)) { -        // commit that peek -        send_buf.get(item); -        dprintf("send_buf_send_one: have %d remaining\n", (int)send_buf.size()); -    } else { -        dprint("failed to send, will retry\n"); -        wait_ms(SdepTimeout); -        resp_buf_read_one(true); -    } -} - -static void resp_buf_wait(const char *cmd) { -    bool didPrint = false; -    while (!resp_buf.empty()) { -        if (!didPrint) { -            dprintf("wait on buf for %s\n", cmd); -            didPrint = true; -        } -        resp_buf_read_one(true); -    } -} - -static bool ble_init(void) { -    state.initialized  = false; -    state.configured   = false; -    state.is_connected = false; - -    setPinInput(AdafruitBleIRQPin); - -    spi_init(); - -    // Perform a hardware reset -    setPinOutput(AdafruitBleResetPin); -    writePinHigh(AdafruitBleResetPin); -    writePinLow(AdafruitBleResetPin); -    wait_ms(10); -    writePinHigh(AdafruitBleResetPin); - -    wait_ms(1000);  // Give it a second to initialize - -    state.initialized = true; -    return state.initialized; -} - -static inline uint8_t min(uint8_t a, uint8_t b) { return a < b ? a : b; } - -static bool read_response(char *resp, uint16_t resplen, bool verbose) { -    char *dest = resp; -    char *end  = dest + resplen; - -    while (true) { -        struct sdep_msg msg; - -        if (!sdep_recv_pkt(&msg, 2 * SdepTimeout)) { -            dprint("sdep_recv_pkt failed\n"); -            return false; -        } - -        if (msg.type != SdepResponse) { -            *resp = 0; -            return false; -        } - -        uint8_t len = min(msg.len, end - dest); -        if (len > 0) { -            memcpy(dest, msg.payload, len); -            dest += len; -        } - -        if (!msg.more) { -            // No more data is expected! -            break; -        } -    } - -    // Ensure the response is NUL terminated -    *dest = 0; - -    // "Parse" the result text; we want to snip off the trailing OK or ERROR line -    // Rewind past the possible trailing CRLF so that we can strip it -    --dest; -    while (dest > resp && (dest[0] == '\n' || dest[0] == '\r')) { -        *dest = 0; -        --dest; -    } - -    // Look back for start of preceeding line -    char *last_line = strrchr(resp, '\n'); -    if (last_line) { -        ++last_line; -    } else { -        last_line = resp; -    } - -    bool              success       = false; -    static const char kOK[] PROGMEM = "OK"; - -    success = !strcmp_P(last_line, kOK); - -    if (verbose || !success) { -        dprintf("result: %s\n", resp); -    } -    return success; -} - -static bool at_command(const char *cmd, char *resp, uint16_t resplen, bool verbose, uint16_t timeout) { -    const char *    end = cmd + strlen(cmd); -    struct sdep_msg msg; - -    if (verbose) { -        dprintf("ble send: %s\n", cmd); -    } - -    if (resp) { -        // They want to decode the response, so we need to flush and wait -        // for all pending I/O to finish before we start this one, so -        // that we don't confuse the results -        resp_buf_wait(cmd); -        *resp = 0; -    } - -    // Fragment the command into a series of SDEP packets -    while (end - cmd > SdepMaxPayload) { -        sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, SdepMaxPayload, true); -        if (!sdep_send_pkt(&msg, timeout)) { -            return false; -        } -        cmd += SdepMaxPayload; -    } - -    sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, end - cmd, false); -    if (!sdep_send_pkt(&msg, timeout)) { -        return false; -    } - -    if (resp == NULL) { -        uint16_t now = timer_read(); -        while (!resp_buf.enqueue(now)) { -            resp_buf_read_one(false); -        } -        uint16_t later = timer_read(); -        if (TIMER_DIFF_16(later, now) > 0) { -            dprintf("waited %dms for resp_buf\n", TIMER_DIFF_16(later, now)); -        } -        return true; -    } - -    return read_response(resp, resplen, verbose); -} - -bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose) { -    char *cmdbuf = (char *)alloca(strlen_P(cmd) + 1); -    strcpy_P(cmdbuf, cmd); -    return at_command(cmdbuf, resp, resplen, verbose); -} - -bool adafruit_ble_is_connected(void) { return state.is_connected; } - -bool adafruit_ble_enable_keyboard(void) { -    char resbuf[128]; - -    if (!state.initialized && !ble_init()) { -        return false; -    } - -    state.configured = false; - -    // Disable command echo -    static const char kEcho[] PROGMEM = "ATE=0"; -    // Make the advertised name match the keyboard -    static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" STR(PRODUCT); -    // Turn on keyboard support -    static const char kHidEnOn[] PROGMEM = "AT+BLEHIDEN=1"; - -    // Adjust intervals to improve latency.  This causes the "central" -    // system (computer/tablet) to poll us every 10-30 ms.  We can't -    // set a smaller value than 10ms, and 30ms seems to be the natural -    // processing time on my macbook.  Keeping it constrained to that -    // feels reasonable to type to. -    static const char kGapIntervals[] PROGMEM = "AT+GAPINTERVALS=10,30,,"; - -    // Reset the device so that it picks up the above changes -    static const char kATZ[] PROGMEM = "ATZ"; - -    // Turn down the power level a bit -    static const char  kPower[] PROGMEM             = "AT+BLEPOWERLEVEL=-12"; -    static PGM_P const configure_commands[] PROGMEM = { -        kEcho, kGapIntervals, kGapDevName, kHidEnOn, kPower, kATZ, -    }; - -    uint8_t i; -    for (i = 0; i < sizeof(configure_commands) / sizeof(configure_commands[0]); ++i) { -        PGM_P cmd; -        memcpy_P(&cmd, configure_commands + i, sizeof(cmd)); - -        if (!at_command_P(cmd, resbuf, sizeof(resbuf))) { -            dprintf("failed BLE command: %S: %s\n", cmd, resbuf); -            goto fail; -        } -    } - -    state.configured = true; - -    // Check connection status in a little while; allow the ATZ time -    // to kick in. -    state.last_connection_update = timer_read(); -fail: -    return state.configured; -} - -static void set_connected(bool connected) { -    if (connected != state.is_connected) { -        if (connected) { -            dprint("BLE connected\n"); -        } else { -            dprint("BLE disconnected\n"); -        } -        state.is_connected = connected; - -        // TODO: if modifiers are down on the USB interface and -        // we cut over to BLE or vice versa, they will remain stuck. -        // This feels like a good point to do something like clearing -        // the keyboard and/or generating a fake all keys up message. -        // However, I've noticed that it takes a couple of seconds -        // for macOS to to start recognizing key presses after BLE -        // is in the connected state, so I worry that doing that -        // here may not be good enough. -    } -} - -void adafruit_ble_task(void) { -    char resbuf[48]; - -    if (!state.configured && !adafruit_ble_enable_keyboard()) { -        return; -    } -    resp_buf_read_one(true); -    send_buf_send_one(SdepShortTimeout); - -    if (resp_buf.empty() && (state.event_flags & UsingEvents) && readPin(AdafruitBleIRQPin)) { -        // Must be an event update -        if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) { -            uint32_t mask = strtoul(resbuf, NULL, 16); - -            if (mask & BleSystemConnected) { -                set_connected(true); -            } else if (mask & BleSystemDisconnected) { -                set_connected(false); -            } -        } -    } - -    if (timer_elapsed(state.last_connection_update) > ConnectionUpdateInterval) { -        bool shouldPoll = true; -        if (!(state.event_flags & ProbedEvents)) { -            // Request notifications about connection status changes. -            // This only works in SPIFRIEND firmware > 0.6.7, which is why -            // we check for this conditionally here. -            // Note that at the time of writing, HID reports only work correctly -            // with Apple products on firmware version 0.6.7! -            // https://forums.adafruit.com/viewtopic.php?f=8&t=104052 -            if (at_command_P(PSTR("AT+EVENTENABLE=0x1"), resbuf, sizeof(resbuf))) { -                at_command_P(PSTR("AT+EVENTENABLE=0x2"), resbuf, sizeof(resbuf)); -                state.event_flags |= UsingEvents; -            } -            state.event_flags |= ProbedEvents; - -            // leave shouldPoll == true so that we check at least once -            // before relying solely on events -        } else { -            shouldPoll = false; -        } - -        static const char kGetConn[] PROGMEM = "AT+GAPGETCONN"; -        state.last_connection_update         = timer_read(); - -        if (at_command_P(kGetConn, resbuf, sizeof(resbuf))) { -            set_connected(atoi(resbuf)); -        } -    } - -#ifdef SAMPLE_BATTERY -    if (timer_elapsed(state.last_battery_update) > BatteryUpdateInterval && resp_buf.empty()) { -        state.last_battery_update = timer_read(); - -        state.vbat = analogReadPin(BATTERY_LEVEL_PIN); -    } -#endif -} - -static bool process_queue_item(struct queue_item *item, uint16_t timeout) { -    char cmdbuf[48]; -    char fmtbuf[64]; - -    // Arrange to re-check connection after keys have settled -    state.last_connection_update = timer_read(); - -#if 1 -    if (TIMER_DIFF_16(state.last_connection_update, item->added) > 0) { -        dprintf("send latency %dms\n", TIMER_DIFF_16(state.last_connection_update, item->added)); -    } -#endif - -    switch (item->queue_type) { -        case QTKeyReport: -            strcpy_P(fmtbuf, PSTR("AT+BLEKEYBOARDCODE=%02x-00-%02x-%02x-%02x-%02x-%02x-%02x")); -            snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->key.modifier, item->key.keys[0], item->key.keys[1], item->key.keys[2], item->key.keys[3], item->key.keys[4], item->key.keys[5]); -            return at_command(cmdbuf, NULL, 0, true, timeout); - -        case QTConsumer: -            strcpy_P(fmtbuf, PSTR("AT+BLEHIDCONTROLKEY=0x%04x")); -            snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->consumer); -            return at_command(cmdbuf, NULL, 0, true, timeout); - -#ifdef MOUSE_ENABLE -        case QTMouseMove: -            strcpy_P(fmtbuf, PSTR("AT+BLEHIDMOUSEMOVE=%d,%d,%d,%d")); -            snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->mousemove.x, item->mousemove.y, item->mousemove.scroll, item->mousemove.pan); -            if (!at_command(cmdbuf, NULL, 0, true, timeout)) { -                return false; -            } -            strcpy_P(cmdbuf, PSTR("AT+BLEHIDMOUSEBUTTON=")); -            if (item->mousemove.buttons & MOUSE_BTN1) { -                strcat(cmdbuf, "L"); -            } -            if (item->mousemove.buttons & MOUSE_BTN2) { -                strcat(cmdbuf, "R"); -            } -            if (item->mousemove.buttons & MOUSE_BTN3) { -                strcat(cmdbuf, "M"); -            } -            if (item->mousemove.buttons == 0) { -                strcat(cmdbuf, "0"); -            } -            return at_command(cmdbuf, NULL, 0, true, timeout); -#endif -        default: -            return true; -    } -} - -void adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys) { -    struct queue_item item; -    bool              didWait = false; - -    item.queue_type   = QTKeyReport; -    item.key.modifier = hid_modifier_mask; -    item.added        = timer_read(); - -    while (nkeys >= 0) { -        item.key.keys[0] = keys[0]; -        item.key.keys[1] = nkeys >= 1 ? keys[1] : 0; -        item.key.keys[2] = nkeys >= 2 ? keys[2] : 0; -        item.key.keys[3] = nkeys >= 3 ? keys[3] : 0; -        item.key.keys[4] = nkeys >= 4 ? keys[4] : 0; -        item.key.keys[5] = nkeys >= 5 ? keys[5] : 0; - -        if (!send_buf.enqueue(item)) { -            if (!didWait) { -                dprint("wait for buf space\n"); -                didWait = true; -            } -            send_buf_send_one(); -            continue; -        } - -        if (nkeys <= 6) { -            return; -        } - -        nkeys -= 6; -        keys += 6; -    } -} - -void adafruit_ble_send_consumer_key(uint16_t usage) { -    struct queue_item item; - -    item.queue_type = QTConsumer; -    item.consumer   = usage; - -    while (!send_buf.enqueue(item)) { -        send_buf_send_one(); -    } -} - -#ifdef MOUSE_ENABLE -void adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) { -    struct queue_item item; - -    item.queue_type        = QTMouseMove; -    item.mousemove.x       = x; -    item.mousemove.y       = y; -    item.mousemove.scroll  = scroll; -    item.mousemove.pan     = pan; -    item.mousemove.buttons = buttons; - -    while (!send_buf.enqueue(item)) { -        send_buf_send_one(); -    } -} -#endif - -uint32_t adafruit_ble_read_battery_voltage(void) { return state.vbat; } - -bool adafruit_ble_set_mode_leds(bool on) { -    if (!state.configured) { -        return false; -    } - -    // The "mode" led is the red blinky one -    at_command_P(on ? PSTR("AT+HWMODELED=1") : PSTR("AT+HWMODELED=0"), NULL, 0); - -    // Pin 19 is the blue "connected" LED; turn that off too. -    // When turning LEDs back on, don't turn that LED on if we're -    // not connected, as that would be confusing. -    at_command_P(on && state.is_connected ? PSTR("AT+HWGPIO=19,1") : PSTR("AT+HWGPIO=19,0"), NULL, 0); -    return true; -} - -// https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/ble-generic#at-plus-blepowerlevel -bool adafruit_ble_set_power_level(int8_t level) { -    char cmd[46]; -    if (!state.configured) { -        return false; -    } -    snprintf(cmd, sizeof(cmd), "AT+BLEPOWERLEVEL=%d", level); -    return at_command(cmd, NULL, 0, false); -} diff --git a/tmk_core/protocol/lufa/adafruit_ble.h b/tmk_core/protocol/lufa/adafruit_ble.h deleted file mode 100644 index b43e0771d9..0000000000 --- a/tmk_core/protocol/lufa/adafruit_ble.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Bluetooth Low Energy Protocol for QMK. - * Author: Wez Furlong, 2016 - * Supports the Adafruit BLE board built around the nRF51822 chip. - */ - -#pragma once - -#include <stdbool.h> -#include <stdint.h> -#include <string.h> - -#include "config_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Instruct the module to enable HID keyboard support and reset */ -extern bool adafruit_ble_enable_keyboard(void); - -/* Query to see if the BLE module is connected */ -extern bool adafruit_ble_query_is_connected(void); - -/* Returns true if we believe that the BLE module is connected. - * This uses our cached understanding that is maintained by - * calling ble_task() periodically. */ -extern bool adafruit_ble_is_connected(void); - -/* Call this periodically to process BLE-originated things */ -extern void adafruit_ble_task(void); - -/* Generates keypress events for a set of keys. - * The hid modifier mask specifies the state of the modifier keys for - * this set of keys. - * Also sends a key release indicator, so that the keys do not remain - * held down. */ -extern void adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys); - -/* Send a consumer usage. - * (milliseconds) */ -extern void adafruit_ble_send_consumer_key(uint16_t usage); - -#ifdef MOUSE_ENABLE -/* Send a mouse/wheel movement report. - * The parameters are signed and indicate positive or negative direction - * change. */ -extern void adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons); -#endif - -/* Compute battery voltage by reading an analog pin. - * Returns the integer number of millivolts */ -extern uint32_t adafruit_ble_read_battery_voltage(void); - -extern bool adafruit_ble_set_mode_leds(bool on); -extern bool adafruit_ble_set_power_level(int8_t level); - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 5b56e8a03c..753762358d 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -52,6 +52,7 @@  #include "usb_descriptor.h"  #include "lufa.h"  #include "quantum.h" +#include "usb_device_state.h"  #include <util/atomic.h>  #ifdef NKRO_ENABLE @@ -142,7 +143,8 @@ static void    send_keyboard(report_keyboard_t *report);  static void    send_mouse(report_mouse_t *report);  static void    send_system(uint16_t data);  static void    send_consumer(uint16_t data); -host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; +static void    send_programmable_button(uint32_t data); +host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, send_programmable_button};  #ifdef VIRTSER_ENABLE  // clang-format off @@ -413,7 +415,10 @@ void EVENT_USB_Device_Disconnect(void) {   *   * FIXME: Needs doc   */ -void EVENT_USB_Device_Reset(void) { print("[R]"); } +void EVENT_USB_Device_Reset(void) { +    print("[R]"); +    usb_device_state_set_reset(); +}  /** \brief Event USB Device Connect   * @@ -421,6 +426,8 @@ void EVENT_USB_Device_Reset(void) { print("[R]"); }   */  void EVENT_USB_Device_Suspend() {      print("[S]"); +    usb_device_state_set_suspend(USB_Device_ConfigurationNumber != 0, USB_Device_ConfigurationNumber); +  #ifdef SLEEP_LED_ENABLE      sleep_led_enable();  #endif @@ -436,6 +443,8 @@ void EVENT_USB_Device_WakeUp() {      suspend_wakeup_init();  #endif +    usb_device_state_set_resume(USB_DeviceState == DEVICE_STATE_Configured, USB_Device_ConfigurationNumber); +  #ifdef SLEEP_LED_ENABLE      sleep_led_disable();      // NOTE: converters may not accept this @@ -528,6 +537,8 @@ void EVENT_USB_Device_ConfigurationChanged(void) {      /* Setup digitizer endpoint */      ConfigSuccess &= Endpoint_ConfigureEndpoint((DIGITIZER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, DIGITIZER_EPSIZE, 1);  #endif + +    usb_device_state_set_configuration(USB_DeviceState == DEVICE_STATE_Configured, USB_Device_ConfigurationNumber);  }  /* FIXME: Expose this table in the docs somehow @@ -760,29 +771,35 @@ static void send_mouse(report_mouse_t *report) {  #endif  } -/** \brief Send Extra - * - * FIXME: Needs doc - */ -#ifdef EXTRAKEY_ENABLE -static void send_extra(uint8_t report_id, uint16_t data) { +#if defined(EXTRAKEY_ENABLE) || defined(PROGRAMMABLE_BUTTON_ENABLE) +static void send_report(void *report, size_t size) {      uint8_t timeout = 255;      if (USB_DeviceState != DEVICE_STATE_Configured) return; -    static report_extra_t r; -    r = (report_extra_t){.report_id = report_id, .usage = data};      Endpoint_SelectEndpoint(SHARED_IN_EPNUM);      /* Check if write ready for a polling interval around 10ms */      while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);      if (!Endpoint_IsReadWriteAllowed()) return; -    Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); +    Endpoint_Write_Stream_LE(report, size, NULL);      Endpoint_ClearIN();  }  #endif +/** \brief Send Extra + * + * FIXME: Needs doc + */ +#ifdef EXTRAKEY_ENABLE +static void send_extra(uint8_t report_id, uint16_t data) { +    static report_extra_t r; +    r = (report_extra_t){.report_id = report_id, .usage = data}; +    send_report(&r, sizeof(r)); +} +#endif +  /** \brief Send System   *   * FIXME: Needs doc @@ -822,6 +839,14 @@ static void send_consumer(uint16_t data) {  #endif  } +static void send_programmable_button(uint32_t data) { +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    static report_programmable_button_t r; +    r = (report_programmable_button_t){.report_id = REPORT_ID_PROGRAMMABLE_BUTTON, .usage = data}; +    send_report(&r, sizeof(r)); +#endif +} +  /*******************************************************************************   * sendchar   ******************************************************************************/ @@ -1044,6 +1069,7 @@ void protocol_setup(void) {  #endif      setup_mcu(); +    usb_device_state_init();      keyboard_setup();  } diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index 348a84c031..6a5205609e 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -56,14 +56,3 @@ extern host_driver_t lufa_driver;  #ifdef __cplusplus  }  #endif - -#ifdef API_ENABLE -#    include "api.h" -#endif - -#ifdef API_SYSEX_ENABLE -#    include "api_sysex.h" -// Allocate space for encoding overhead. -// The header and terminator are not stored to save a few bytes of precious ram -#    define MIDI_SYSEX_BUFFER (API_SYSEX_MAX_SIZE + API_SYSEX_MAX_SIZE / 7 + (API_SYSEX_MAX_SIZE % 7 ? 1 : 0)) -#endif diff --git a/tmk_core/protocol/lufa/outputselect.c b/tmk_core/protocol/lufa/outputselect.c deleted file mode 100644 index f758c65280..0000000000 --- a/tmk_core/protocol/lufa/outputselect.c +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 2017 Priyadi Iman Nurcahyo -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "outputselect.h" - -#if defined(PROTOCOL_LUFA) -#    include "lufa.h" -#endif - -#ifdef MODULE_ADAFRUIT_BLE -#    include "adafruit_ble.h" -#endif - -uint8_t desired_output = OUTPUT_DEFAULT; - -/** \brief Set Output - * - * FIXME: Needs doc - */ -void set_output(uint8_t output) { -    set_output_user(output); -    desired_output = output; -} - -/** \brief Set Output User - * - * FIXME: Needs doc - */ -__attribute__((weak)) void set_output_user(uint8_t output) {} - -static bool is_usb_configured(void) { -#if defined(PROTOCOL_LUFA) -    return USB_DeviceState == DEVICE_STATE_Configured; -#endif -} - -/** \brief Auto Detect Output - * - * FIXME: Needs doc - */ -uint8_t auto_detect_output(void) { -    if (is_usb_configured()) { -        return OUTPUT_USB; -    } - -#ifdef MODULE_ADAFRUIT_BLE -    if (adafruit_ble_is_connected()) { -        return OUTPUT_BLUETOOTH; -    } -#endif - -#ifdef BLUETOOTH_ENABLE -    return OUTPUT_BLUETOOTH;  // should check if BT is connected here -#endif - -    return OUTPUT_NONE; -} - -/** \brief Where To Send - * - * FIXME: Needs doc - */ -uint8_t where_to_send(void) { -    if (desired_output == OUTPUT_AUTO) { -        return auto_detect_output(); -    } -    return desired_output; -} diff --git a/tmk_core/protocol/lufa/outputselect.h b/tmk_core/protocol/lufa/outputselect.h deleted file mode 100644 index c4548e1122..0000000000 --- a/tmk_core/protocol/lufa/outputselect.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2017 Priyadi Iman Nurcahyo -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include <stdint.h> - -enum outputs { -    OUTPUT_AUTO, - -    OUTPUT_NONE, -    OUTPUT_USB, -    OUTPUT_BLUETOOTH -}; - -#ifndef OUTPUT_DEFAULT -#    define OUTPUT_DEFAULT OUTPUT_AUTO -#endif - -void    set_output(uint8_t output); -void    set_output_user(uint8_t output); -uint8_t auto_detect_output(void); -uint8_t where_to_send(void); diff --git a/tmk_core/protocol/lufa/ringbuffer.hpp b/tmk_core/protocol/lufa/ringbuffer.hpp deleted file mode 100644 index 70a3c4881d..0000000000 --- a/tmk_core/protocol/lufa/ringbuffer.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -// A simple ringbuffer holding Size elements of type T -template <typename T, uint8_t Size> -class RingBuffer { - protected: -  T buf_[Size]; -  uint8_t head_{0}, tail_{0}; - public: -  inline uint8_t nextPosition(uint8_t position) { -    return (position + 1) % Size; -  } - -  inline uint8_t prevPosition(uint8_t position) { -    if (position == 0) { -      return Size - 1; -    } -    return position - 1; -  } - -  inline bool enqueue(const T &item) { -    static_assert(Size > 1, "RingBuffer size must be > 1"); -    uint8_t next = nextPosition(head_); -    if (next == tail_) { -      // Full -      return false; -    } - -    buf_[head_] = item; -    head_ = next; -    return true; -  } - -  inline bool get(T &dest, bool commit = true) { -    auto tail = tail_; -    if (tail == head_) { -      // No more data -      return false; -    } - -    dest = buf_[tail]; -    tail = nextPosition(tail); - -    if (commit) { -      tail_ = tail; -    } -    return true; -  } - -  inline bool empty() const { return head_ == tail_; } - -  inline uint8_t size() const { -    int diff = head_ - tail_; -    if (diff >= 0) { -      return diff; -    } -    return Size + diff; -  } - -  inline T& front() { -    return buf_[tail_]; -  } - -  inline bool peek(T &item) { -    return get(item, false); -  } -}; diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c deleted file mode 100644 index 64f2fa50ab..0000000000 --- a/tmk_core/protocol/m0110.c +++ /dev/null @@ -1,583 +0,0 @@ -/* -Copyright 2011,2012 Jun WAKO <wakojun@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ -/* M0110A Support was contributed by skagon@github */ - -#include <stdbool.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include <util/delay.h> -#include "m0110.h" -#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); -static inline void     clock_hi(void); -static inline bool     clock_in(void); -static inline void     data_lo(void); -static inline void     data_hi(void); -static inline bool     data_in(void); -static inline uint16_t wait_clock_lo(uint16_t us); -static inline uint16_t wait_clock_hi(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 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) - -#define KEY(raw) ((raw)&0x7f) -#define IS_BREAK(raw) (((raw)&0x80) == 0x80) - -uint8_t m0110_error = 0; - -void m0110_init(void) { -    idle(); -    _delay_ms(1000); - -    /* Not needed to initialize in fact. -        uint8_t data; -        m0110_send(M0110_MODEL); -        data = m0110_recv(); -        print("m0110_init model: "); print_hex8(data); print("\n"); - -        m0110_send(M0110_TEST); -        data = m0110_recv(); -        print("m0110_init test: "); print_hex8(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: "); -    print_hex8(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: "); -    print_hex8(m0110_error); -    print("\n"); -    _delay_ms(500); -    idle(); -    return 0xFF; -} - -/* -Handling for exceptional case of key combinations for M0110A - -Shift and Calc/Arrow key could be operated simultaneously: - -    Case Shift   Arrow   Events          Interpret -    ------------------------------------------------------------------- -    1    Down    Down    71, 79, DD      Calc(d)*a *b -    2    Down    Up      71, 79, UU      Arrow&Calc(u)*a -    3    Up      Down    F1, 79, DD      Shift(u) *c -    4    Up      Up      F1, 79, UU      Shift(u) and Arrow&Calc(u)*a - -    Case Shift   Calc    Events          Interpret -    ------------------------------------------------------------------- -    5(1) Down    Down    71, 71, 79, DD  Shift(d) and Cacl(d) -    6(2) Down    Up      F1, 71, 79, UU  Shift(u) and Arrow&Calc(u)*a -    7(1) Up      Down    F1, 71, 79, DD  Shift(u) and Calc(d) -    8(4) Up      Up      F1, F1, 79, UU  Shift(ux2) and Arrow&Calc(u)*a - -During Calc key is hold: -    Case Shift   Arrow   Events          Interpret -    ------------------------------------------------------------------- -    A(3) ----    Down    F1, 79, DD      Shift(u) *c -    B    ----    Up      79, UU          Arrow&Calc(u)*a -    C    Down    ----    F1, 71          Shift(u) and Shift(d) -    D    Up      ----    F1              Shift(u) -    E    Hold    Down    79, DD          Normal -    F    Hold    Up      79, UU          Arrow&Calc(u)*a -    G(1) Down    Down    F1, 71, 79, DD  Shift(u)*b and Calc(d)*a -    H(2) Down    Up      F1, 71, 79, UU  Shift(u) and Arrow&Calc(u)*a -    I(3) Up      Down    F1, F1, 79, DD  Shift(ux2) *c -    J(4) Up      Up      F1, 79, UU      Shift(u) and Arrow&Calc(u)*a - -    Case Shift   Calc    Events          Interpret -    ------------------------------------------------------------------- -    K(1) ----    Down    71, 79, DD      Calc(d)*a -    L(4) ----    Up      F1, 79, UU      Shift(u) and Arrow&Calc(u)*a -    M(1) Hold    Down    71, 79, DD      Calc(d)*a -    N    Hold    Up      79, UU          Arrow&Calc(u)*a - -    Where DD/UU indicates part of Keypad Down/Up event. -    *a: Impossible to distinguish btween Arrow and Calc event. -    *b: Shift(d) event is ignored. -    *c: Arrow/Calc(d) event is ignored. -*/ -uint8_t m0110_recv_key(void) { -    static uint8_t keybuf  = 0x00; -    static uint8_t keybuf2 = 0x00; -    static uint8_t rawbuf  = 0x00; -    uint8_t        raw, raw2, raw3; - -    if (keybuf) { -        raw    = keybuf; -        keybuf = 0x00; -        return raw; -    } -    if (keybuf2) { -        raw     = keybuf2; -        keybuf2 = 0x00; -        return raw; -    } - -    if (rawbuf) { -        raw    = rawbuf; -        rawbuf = 0x00; -    } else { -        raw = instant();  // Use INSTANT for better response. Should be INQUIRY ? -    } -    switch (KEY(raw)) { -        case M0110_KEYPAD: -            raw2 = instant(); -            switch (KEY(raw2)) { -                case M0110_ARROW_UP: -                case M0110_ARROW_DOWN: -                case M0110_ARROW_LEFT: -                case M0110_ARROW_RIGHT: -                    if (IS_BREAK(raw2)) { -                        // Case B,F,N: -                        keybuf = (raw2scan(raw2) | M0110_CALC_OFFSET);  // Calc(u) -                        return (raw2scan(raw2) | M0110_KEYPAD_OFFSET);  // Arrow(u) -                    } -                    break; -            } -            // Keypad or Arrow -            return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); -            break; -        case M0110_SHIFT: -            raw2 = instant(); -            switch (KEY(raw2)) { -                case M0110_SHIFT: -                    // Case: 5-8,C,G,H -                    rawbuf = raw2; -                    return raw2scan(raw);  // Shift(d/u) -                    break; -                case M0110_KEYPAD: -                    // Shift + Arrow, Calc, or etc. -                    raw3 = instant(); -                    switch (KEY(raw3)) { -                        case M0110_ARROW_UP: -                        case M0110_ARROW_DOWN: -                        case M0110_ARROW_LEFT: -                        case M0110_ARROW_RIGHT: -                            if (IS_BREAK(raw)) { -                                if (IS_BREAK(raw3)) { -                                    // Case 4: -                                    print("(4)\n"); -                                    keybuf2 = raw2scan(raw);                         // Shift(u) -                                    keybuf  = (raw2scan(raw3) | M0110_CALC_OFFSET);  // Calc(u) -                                    return (raw2scan(raw3) | M0110_KEYPAD_OFFSET);   // Arrow(u) -                                } else { -                                    // Case 3: -                                    print("(3)\n"); -                                    return (raw2scan(raw));  // Shift(u) -                                } -                            } else { -                                if (IS_BREAK(raw3)) { -                                    // Case 2: -                                    print("(2)\n"); -                                    keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET);  // Calc(u) -                                    return (raw2scan(raw3) | M0110_KEYPAD_OFFSET);  // Arrow(u) -                                } else { -                                    // Case 1: -                                    print("(1)\n"); -                                    return (raw2scan(raw3) | M0110_CALC_OFFSET);  // Calc(d) -                                } -                            } -                            break; -                        default: -                            // Shift + Keypad -                            keybuf = (raw2scan(raw3) | M0110_KEYPAD_OFFSET); -                            return raw2scan(raw);  // Shift(d/u) -                            break; -                    } -                    break; -                default: -                    // Shift + Normal keys -                    keybuf = raw2scan(raw2); -                    return raw2scan(raw);  // Shift(d/u) -                    break; -            } -            break; -        default: -            // Normal keys -            return raw2scan(raw); -            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); -    uint8_t data = m0110_recv(); -    if (data != M0110_NULL) { -        debug_hex(data); -        debug(" "); -    } -    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 -============================== - - -Signaling ---------- -CLOCK is always from KEYBOARD. DATA are sent with MSB first. - -1) IDLE: both lines are high. -    CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -    DATA  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -2) KEYBOARD->HOST: HOST reads bit on rising edge. -    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ -    DATA  ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ -                      <--> 160us(clock low) -                         <---> 180us(clock high) - -3) HOST->KEYBOARD: HOST asserts bit on falling edge. -    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ -    DATA  ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ -                <----> 840us(request to send by host)                     <---> 80us(hold DATA) -                      <--> 180us(clock low) -                         <---> 220us(clock high) - - -Protocol --------- -COMMAND: -    Inquiry     0x10    get key event with block -    Instant     0x12    get key event -    Model       0x14    get model number(M0110 responds with 0x09) -                        bit 7   1 if another device connected(used when keypad exists?) -                        bit4-6  next device model number -                        bit1-3  keyboard model number -                        bit 0   always 1 -    Test        0x16    test(ACK:0x7D/NAK:0x77) - -KEY EVENT: -    bit 7       key state(0:press 1:release) -    bit 6-1     scan code(see below) -    bit 0       always 1 -    To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). - -    Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79. -          Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release. - -ARROW KEYS: -    Arrow keys and Calc keys(+,*,/,= on keypad) share same byte sequence and preceding byte of -    Calc keys(0x71 and 0xF1) means press and release event of SHIFT. This causes a very confusing situation, -    it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases. - -    Raw key events: -            press               release -            ----------------    ---------------- -    Left:         0x79, 0x0D          0x79, 0x8D -    Right:        0x79, 0x05          0x79, 0x85 -    Up:           0x79, 0x1B          0x79, 0x9B -    Down:         0x79, 0x11          0x79, 0x91 -    Pad+:   0x71, 0x79, 0x0D    0xF1, 0x79, 0x8D -    Pad*:   0x71, 0x79, 0x05    0xF1, 0x79, 0x85 -    Pad/:   0x71, 0x79, 0x1B    0xF1, 0x79, 0x9B -    Pad=:   0x71, 0x79, 0x11    0xF1, 0x79, 0x91 - - -RAW CODE: -    M0110A -    ,---------------------------------------------------------. ,---------------. -    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Bcksp| |Clr|  =|  /|  *| -    |---------------------------------------------------------| |---------------| -    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|   | |  7|  8|  9|  -| -    |-----------------------------------------------------'   | |---------------| -    |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return| |  4|  5|  6|  +| -    |---------------------------------------------------------| |---------------| -    |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shft|Up | |  1|  2|  3|   | -    |---------------------------------------------------------' |-----------|Ent| -    |Optio|Mac    |           Space           |  \|Lft|Rgt|Dn | |      0|  .|   | -    `---------------------------------------------------------' `---------------' -    ,---------------------------------------------------------. ,---------------. -    | 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31|   67| |+0F|*11|*1B|*05| -    |---------------------------------------------------------| |---------------| -    |   61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D|   | |+33|+37|+39|+1D| -    |-----------------------------------------------------'   | |---------------| -    |    73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F|    49| |+2D|+2F|+31|*0D| -    |---------------------------------------------------------| |---------------| -    |      71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59|  71|+1B| |+27|+29|+2B|   | -    |---------------------------------------------------------' |-----------|+19| -    |   75|     6F|            63             | 55|+0D|+05|+11| |    +25|+03|   | -    `---------------------------------------------------------' `---------------' -    + 0x79, 0xDD / 0xF1, 0xUU -    * 0x71, 0x79,DD / 0xF1, 0x79, 0xUU - - -MODEL NUMBER: -    M0110:           0x09  00001001 : model number 4 (100) -    M0110A:          0x0B  00001011 : model number 5 (101) -    M0110 & M0120:   ??? - - -Scan Code ---------- -    m0110_recv_key() function returns following scan codes instead of M0110 raw codes. -    Scan codes are 1 byte size and MSB(bit7) is set when key is released. - -        scancode = ((raw&0x80) | ((raw&0x7F)>>1)) - -    M0110                                                          M0120 -    ,---------------------------------------------------------.    ,---------------. -    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backs|    |Clr|  -|Lft|Rgt| -    |---------------------------------------------------------|    |---------------| -    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \|    |  7|  8|  9|Up | -    |---------------------------------------------------------|    |---------------| -    |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return|    |  4|  5|  6|Dn | -    |---------------------------------------------------------|    |---------------| -    |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|        |    |  1|  2|  3|   | -    `---------------------------------------------------------'    |-----------|Ent| -         |Opt|Mac |         Space               |Enter|Opt|        |      0|  .|   | -         `------------------------------------------------'        `---------------' -    ,---------------------------------------------------------.    ,---------------. -    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|    | 47| 4E| 46| 42| -    |---------------------------------------------------------|    |---------------| -    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|    | 59| 5B| 5C| 4D| -    |---------------------------------------------------------|    |---------------| -    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24|    | 56| 57| 58| 48| -    |---------------------------------------------------------|    |---------------| -    |      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|      38|    | 53| 54| 55|   | -    `---------------------------------------------------------'    |-----------| 4C| -         | 3A|  37|             31              |   34| 3A|        |     52| 41|   | -         `------------------------------------------------'        `---------------' - -    International keyboard(See page 22 of "Technical Info for 128K/512K") -    ,---------------------------------------------------------. -    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33| -    |---------------------------------------------------------| -    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| -    |------------------------------------------------------   | -    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24|  | -    |---------------------------------------------------------| -    |  38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 0A|      38| -    `---------------------------------------------------------' -         | 3A|  37|             34              |   31| 3A| -         `------------------------------------------------' - -    M0110A -    ,---------------------------------------------------------. ,---------------. -    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Bcksp| |Clr|  =|  /|  *| -    |---------------------------------------------------------| |---------------| -    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|   | |  7|  8|  9|  -| -    |-----------------------------------------------------'   | |---------------| -    |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return| |  4|  5|  6|  +| -    |---------------------------------------------------------| |---------------| -    |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|Shft|Up | |  1|  2|  3|   | -    |---------------------------------------------------------' |-----------|Ent| -    |Optio|Mac    |           Space           |  \|Lft|Rgt|Dn | |      0|  .|   | -    `---------------------------------------------------------' `---------------' -    ,---------------------------------------------------------. ,---------------. -    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33| | 47| 68| 6D| 62| -    |---------------------------------------------------------| |---------------| -    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E|   | | 59| 5B| 5C| 4E| -    |-----------------------------------------------------'   | |---------------| -    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24| | 56| 57| 58| 66| -    |---------------------------------------------------------| |---------------| -    |      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|  38| 4D| | 53| 54| 55|   | -    |---------------------------------------------------------' |-----------| 4C| -    |   3A|     37|            31             | 2A| 46| 42| 48| |     52| 41|   | -    `---------------------------------------------------------' `---------------' - - -References ----------- -Technical Info for 128K/512K and Plus -    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf -    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf -Protocol: -    Page 20 of Tech Info for 128K/512K -    http://www.mac.linux-m68k.org/devel/plushw.php -Connector: -    Page 20 of Tech Info for 128K/512K -    http://www.kbdbabel.org/conn/kbd_connector_macplus.png -Signaling: -    http://www.kbdbabel.org/signaling/kbd_signaling_mac.png -    http://typematic.blog.shinobi.jp/Entry/14/ -M0110 raw scan codes: -    Page 22 of Tech Info for 128K/512K -    Page 07 of Tech Info for Plus -    http://m0115.web.fc2.com/m0110.jpg -    http://m0115.web.fc2.com/m0110a.jpg -*/ diff --git a/tmk_core/protocol/m0110.h b/tmk_core/protocol/m0110.h deleted file mode 100644 index 63ff3e90ec..0000000000 --- a/tmk_core/protocol/m0110.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2011,2012 Jun WAKO <wakojun@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -/* port settings for clock and data line */ -#if !(defined(M0110_CLOCK_PORT) && defined(M0110_CLOCK_PIN) && defined(M0110_CLOCK_DDR) && defined(M0110_CLOCK_BIT)) -#    error "M0110 clock port setting is required in config.h" -#endif - -#if !(defined(M0110_DATA_PORT) && defined(M0110_DATA_PIN) && defined(M0110_DATA_DDR) && defined(M0110_DATA_BIT)) -#    error "M0110 data port setting is required in config.h" -#endif - -/* Commands */ -#define M0110_INQUIRY 0x10 -#define M0110_INSTANT 0x14 -#define M0110_MODEL 0x16 -#define M0110_TEST 0x36 - -/* Response(raw byte from M0110) */ -#define M0110_NULL 0x7B -#define M0110_KEYPAD 0x79 -#define M0110_TEST_ACK 0x7D -#define M0110_TEST_NAK 0x77 -#define M0110_SHIFT 0x71 -#define M0110_ARROW_UP 0x1B -#define M0110_ARROW_DOWN 0x11 -#define M0110_ARROW_LEFT 0x0D -#define M0110_ARROW_RIGHT 0x05 - -/* This inidcates no response. */ -#define M0110_ERROR 0xFF - -/* scan code offset for keypad and arrow keys */ -#define M0110_KEYPAD_OFFSET 0x40 -#define M0110_CALC_OFFSET 0x60 - -extern uint8_t m0110_error; - -/* host role */ -void    m0110_init(void); -uint8_t m0110_send(uint8_t data); -uint8_t m0110_recv(void); -uint8_t m0110_recv_key(void); -uint8_t m0110_inquiry(void); -uint8_t m0110_instant(void); diff --git a/tmk_core/protocol/midi/qmk_midi.c b/tmk_core/protocol/midi/qmk_midi.c index c18dbf9930..3a454d61ae 100644 --- a/tmk_core/protocol/midi/qmk_midi.c +++ b/tmk_core/protocol/midi/qmk_midi.c @@ -4,9 +4,6 @@  #include "midi.h"  #include "usb_descriptor.h"  #include "process_midi.h" -#if API_SYSEX_ENABLE -#    include "api_sysex.h" -#endif  /*******************************************************************************   * MIDI @@ -124,41 +121,6 @@ static void cc_callback(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t v      // midi_send_cc(device, (chan + 1) % 16, num, val);  } -#ifdef API_SYSEX_ENABLE -uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; - -static void sysex_callback(MidiDevice* device, uint16_t start, uint8_t length, uint8_t* data) { -    // SEND_STRING("\n"); -    // send_word(start); -    // SEND_STRING(": "); -    // Don't store the header -    int16_t pos = start - 4; -    for (uint8_t place = 0; place < length; place++) { -        // send_byte(*data); -        if (pos >= 0) { -            if (*data == 0xF7) { -                // SEND_STRING("\nRD: "); -                // for (uint8_t i = 0; i < start + place + 1; i++){ -                //     send_byte(midi_buffer[i]); -                // SEND_STRING(" "); -                // } -                const unsigned decoded_length = sysex_decoded_length(pos); -                uint8_t        decoded[API_SYSEX_MAX_SIZE]; -                sysex_decode(decoded, midi_buffer, pos); -                process_api(decoded_length, decoded); -                return; -            } else if (pos >= MIDI_SYSEX_BUFFER) { -                return; -            } -            midi_buffer[pos] = *data; -        } -        // SEND_STRING(" "); -        data++; -        pos++; -    } -} -#endif -  void midi_init(void);  void setup_midi(void) { @@ -170,7 +132,4 @@ void setup_midi(void) {      midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);      midi_register_fallthrough_callback(&midi_device, fallthrough_callback);      midi_register_cc_callback(&midi_device, cc_callback); -#ifdef API_SYSEX_ENABLE -    midi_register_sysex_callback(&midi_device, sysex_callback); -#endif  } diff --git a/tmk_core/protocol/news.c b/tmk_core/protocol/news.c deleted file mode 100644 index 4463e8dd42..0000000000 --- a/tmk_core/protocol/news.c +++ /dev/null @@ -1,161 +0,0 @@ -/* -Copyright 2012 Jun WAKO <wakojun@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#include <stdbool.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include "news.h" - -void news_init(void) { NEWS_KBD_RX_INIT(); } - -// RX ring buffer -#define RBUF_SIZE 8 -static uint8_t rbuf[RBUF_SIZE]; -static uint8_t rbuf_head = 0; -static uint8_t rbuf_tail = 0; - -uint8_t news_recv(void) { -    uint8_t data = 0; -    if (rbuf_head == rbuf_tail) { -        return 0; -    } - -    data      = rbuf[rbuf_tail]; -    rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; -    return data; -} - -// USART RX complete interrupt -ISR(NEWS_KBD_RX_VECT) { -    uint8_t next = (rbuf_head + 1) % RBUF_SIZE; -    if (next != rbuf_tail) { -        rbuf[rbuf_head] = NEWS_KBD_RX_DATA; -        rbuf_head       = next; -    } -} - -/* -SONY NEWS Keyboard Protocol -=========================== - -Resources ---------- -    Mouse protocol of NWA-5461(Japanese) -    http://groups.google.com/group/fj.sys.news/browse_thread/thread/a01b3e3ac6ae5b2d - -    SONY NEWS Info(Japanese) -    http://katsu.watanabe.name/doc/sonynews/ - - -Pinouts -------- -    EIA 232 male connector from NWP-5461 -    ------------- -    \ 1 2 3 4 5 / -     \ 6 7 8 9 / -      --------- -    1 VCC -    2 BZ(Speaker) -    3 Keyboard Data(from keyboard MCU TxD) -    4 NC -    5 GND -    6 Unknown Input(to keyboard MCU RxD via schmitt trigger) -    7 Mouse Data(from Mouse Ext connector) -    8 Unknown Input(to Keyboard MCU Input via diode and buffer) -    9 FG -    NOTE: Two LED on keyboard are controlled by pin 6,8? - -    EIA 232 male connector from NWP-411A -    ------------- -    \ 1 2 3 4 5 / -     \ 6 7 8 9 / -      --------- -    1 VCC -    2 BZ(Speaker) -    3 Keyboard Data(from keyboard MCU TxD) -    4 NC -    5 GND -    6 NC -    7 Mouse Data(from Mouse Ext connector) -    8 NC -    9 FG -    NOTE: These are just from my guess and not confirmed. - - -Signaling ---------- -    ~~~~~~~~~~ ____XOO0X111X222X333X444X555X666X777~~~~ ~~~~~~~ -    Idle    Start  LSB                         MSB Stop Idle - -    Idle:       High -    Start bit:  Low -    Stop bit:   High -    Bit order:  LSB first - -    Baud rate:  9600 -    Interface:  TTL level(5V) UART - -    NOTE: This is observed on NWP-5461 with its DIP switch all OFF. - - -Format ------- -    MSB         LSB -    7 6 5 4 3 2 1 0   bit -    | | | | | | | | -    | +-+-+-+-+-+-+-- scan code(00-7F) -    +---------------- break flag: sets when released - - -Scan Codes ----------- -    SONY NEWS NWP-5461 -    ,---.   ,------------------------, ,------------------------. ,---------. -    | 7A|   | 01 | 02 | 03 | 04 | 05 | | 06 | 07 | 08 | 09 | 0A | | 68 | 69 | ,-----------. -    `---'   `------------------------' `------------------------' `---------' | 64| 65| 52| -    ,-------------------------------------------------------------. ,---. ,---------------| -    | 0B| 0C| 0D| 0E| 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18|  19 | | 6A| | 4B| 4C| 4D| 4E| -    |-------------------------------------------------------------| |---| |---------------| -    |  1A | 1B| 1C| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27|   | | 6B| | 4F| 50| 51| 56| -    |---------------------------------------------------------'   | |---| |---------------| -    |  28  | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34|  35  | | 6C| | 53| 54| 55|   | -    |-------------------------------------------------------------| |---| |-----------| 5A| -    |  36    | 37| 38| 39| 3A| 3B| 3C| 3D| 3E| 3F| 40| 41|   42   | | 6D| | 57| 59| 58|   | -    |-------------------------------------------------------------| |---| |---------------| -    | 43  | 44 | 45 |       46          |    47    | 48| 49|  4A  | | 6E| | 66| 5B| 5C| 5D| -    `-------------------------------------------------------------' `---' `---------------' -*/ diff --git a/tmk_core/protocol/news.h b/tmk_core/protocol/news.h deleted file mode 100644 index 327a13856d..0000000000 --- a/tmk_core/protocol/news.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2012 Jun WAKO <wakojun@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -/* - * Primitive PS/2 Library for AVR - */ - -/* host role */ -void    news_init(void); -uint8_t news_recv(void); - -/* device role */ diff --git a/tmk_core/protocol/next_kbd.c b/tmk_core/protocol/next_kbd.c deleted file mode 100644 index 6f118e6172..0000000000 --- a/tmk_core/protocol/next_kbd.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - -NeXT non-ADB Keyboard Protocol - -Copyright 2013, Benjamin Gould (bgould@github.com) - -Based on: -TMK firmware code Copyright 2011,2012 Jun WAKO <wakojun@gmail.com> -Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license - -Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB -Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html -Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include <stdint.h> -#include <stdbool.h> -#include <util/atomic.h> -#include <util/delay.h> -#include "next_kbd.h" -#include "debug.h" - -static inline void     out_lo(void); -static inline void     out_hi(void); -static inline void     query(void); -static inline void     reset(void); -static inline uint32_t response(void); - -/* The keyboard sends signal with 50us pulse width on OUT line - * while it seems to miss the 50us pulse on In line. - * next_kbd_set_leds() often fails to sync LED status with 50us - * but it works well with 51us(+1us) on TMK converter(ATMeaga32u2) at least. - * TODO: test on Teensy and Pro Micro configuration - */ -#define out_hi_delay(intervals)                       \ -    do {                                              \ -        out_hi();                                     \ -        _delay_us((NEXT_KBD_TIMING + 1) * intervals); \ -    } while (0); -#define out_lo_delay(intervals)                       \ -    do {                                              \ -        out_lo();                                     \ -        _delay_us((NEXT_KBD_TIMING + 1) * intervals); \ -    } while (0); -#define query_delay(intervals)                        \ -    do {                                              \ -        query();                                      \ -        _delay_us((NEXT_KBD_TIMING + 1) * intervals); \ -    } while (0); -#define reset_delay(intervals)                        \ -    do {                                              \ -        reset();                                      \ -        _delay_us((NEXT_KBD_TIMING + 1) * intervals); \ -    } while (0); - -void next_kbd_init(void) { -    out_hi(); -    NEXT_KBD_IN_DDR &= ~(1 << NEXT_KBD_IN_BIT);  // KBD_IN  to input -    NEXT_KBD_IN_PORT |= (1 << NEXT_KBD_IN_BIT);  // KBD_IN  pull up - -    query_delay(5); -    reset_delay(8); - -    query_delay(5); -    reset_delay(8); -} - -void next_kbd_set_leds(bool left, bool right) { -    cli(); -    out_lo_delay(9); - -    out_hi_delay(3); -    out_lo_delay(1); - -    if (left) { -        out_hi_delay(1); -    } else { -        out_lo_delay(1); -    } - -    if (right) { -        out_hi_delay(1); -    } else { -        out_lo_delay(1); -    } - -    out_lo_delay(7); -    out_hi(); -    sei(); -} - -#define NEXT_KBD_READ (NEXT_KBD_IN_PIN & (1 << NEXT_KBD_IN_BIT)) -uint32_t next_kbd_recv(void) { -    // First check to make sure that the keyboard is actually connected; -    // if not, just return -    // TODO: reflect the status of the keyboard in a return code -    if (!NEXT_KBD_READ) { -        sei(); -        return 0; -    } - -    query(); -    uint32_t resp = response(); - -    return resp; -} - -static inline uint32_t response(void) { -    cli(); - -    // try a 5ms read; this should be called after the query method has -    // been run so if a key is pressed we should get a response within -    // 5ms; if not then send a reset and exit -    uint8_t  i             = 0; -    uint32_t data          = 0; -    uint16_t reset_timeout = 50000; -    while (NEXT_KBD_READ && reset_timeout) { -        asm(""); -        _delay_us(1); -        reset_timeout--; -    } -    if (!reset_timeout) { -        reset(); -        sei(); -        return 0; -    } -    _delay_us(NEXT_KBD_TIMING / 2); -    for (; i < 22; i++) { -        if (NEXT_KBD_READ) { -            data |= ((uint32_t)1 << i); -            /* Note: -             * My testing with the ATmega32u4 showed that there might -             * something wrong with the timing here; by the end of the -             * second data byte some of the modifiers can get bumped out -             * to the next bit over if we just cycle through the data -             * based on the expected interval.  There is a bit (i = 10) -             * in the middle of the data that is always on followed by -             * one that is always off - so we'll use that to reset our -             * timing in case we've gotten ahead of the keyboard; -             */ -            if (i == 10) { -                i++; -                while (NEXT_KBD_READ) -                    ; -                _delay_us(NEXT_KBD_TIMING / 2); -            } -        } else { -            /* redundant - but I don't want to remove if it might screw -             * up the timing -             */ -            data |= ((uint32_t)0 << i); -        } -        _delay_us(NEXT_KBD_TIMING); -    } - -    sei(); - -    return data; -} - -static inline void out_lo(void) { -    NEXT_KBD_OUT_PORT &= ~(1 << NEXT_KBD_OUT_BIT); -    NEXT_KBD_OUT_DDR |= (1 << NEXT_KBD_OUT_BIT); -} - -static inline void out_hi(void) { -    /* input with pull up */ -    NEXT_KBD_OUT_DDR &= ~(1 << NEXT_KBD_OUT_BIT); -    NEXT_KBD_OUT_PORT |= (1 << NEXT_KBD_OUT_BIT); -} - -static inline void query(void) { -    out_lo_delay(5); -    out_hi_delay(1); -    out_lo_delay(3); -    out_hi(); -} - -static inline void reset(void) { -    out_lo_delay(1); -    out_hi_delay(4); -    out_lo_delay(1); -    out_hi_delay(6); -    out_lo_delay(10); -    out_hi(); -} diff --git a/tmk_core/protocol/next_kbd.h b/tmk_core/protocol/next_kbd.h deleted file mode 100644 index 1249ebf392..0000000000 --- a/tmk_core/protocol/next_kbd.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -NeXT non-ADB Keyboard Protocol - -Copyright 2013, Benjamin Gould (bgould@github.com) - -Based on: -TMK firmware code Copyright 2011,2012 Jun WAKO <wakojun@gmail.com> -Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license - -Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB -Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html -Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ - -#pragma once - -#include <stdbool.h> - -#define NEXT_KBD_KMBUS_IDLE 0x300600 -#define NEXT_KBD_TIMING 50 - -extern uint8_t next_kbd_error; - -/* host role */ -void     next_kbd_init(void); -void     next_kbd_set_leds(bool left, bool right); -uint32_t next_kbd_recv(void); diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 099964ae56..a43755f899 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -237,6 +237,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {      HID_RI_END_COLLECTION(0),  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    HID_RI_USAGE_PAGE(8, 0x0C),            // Consumer +    HID_RI_USAGE(8, 0x01),                 // Consumer Control +    HID_RI_COLLECTION(8, 0x01),            // Application +        HID_RI_REPORT_ID(8, REPORT_ID_PROGRAMMABLE_BUTTON), +        HID_RI_USAGE(8, 0x03),             // Programmable Buttons +        HID_RI_COLLECTION(8, 0x04),        // Named Array +            HID_RI_USAGE_PAGE(8, 0x09),    // Button +            HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 +            HID_RI_USAGE_MAXIMUM(8, 0x20), // Button 32 +            HID_RI_LOGICAL_MINIMUM(8, 0x00), +            HID_RI_LOGICAL_MAXIMUM(8, 0x01), +            HID_RI_REPORT_COUNT(8, 32), +            HID_RI_REPORT_SIZE(8, 1), +            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), +        HID_RI_END_COLLECTION(0), +    HID_RI_END_COLLECTION(0), +#endif +  #ifdef NKRO_ENABLE      HID_RI_USAGE_PAGE(8, 0x01),        // Generic Desktop      HID_RI_USAGE(8, 0x06),             // Keyboard diff --git a/tmk_core/protocol/usb_hid/parser.h b/tmk_core/protocol/usb_hid/parser.h index 036281fa66..ba35b7af5a 100644 --- a/tmk_core/protocol/usb_hid/parser.h +++ b/tmk_core/protocol/usb_hid/parser.h @@ -1,5 +1,4 @@ -#ifndef PARSER_H -#define PARSER_H +#pragma once  #include "hid.h"  #include "report.h" @@ -11,5 +10,3 @@ public:      uint16_t time_stamp;      virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);  }; - -#endif diff --git a/tmk_core/protocol/usb_hid/usb_hid.h b/tmk_core/protocol/usb_hid/usb_hid.h index 083b68d1f5..5cb5f5d035 100644 --- a/tmk_core/protocol/usb_hid/usb_hid.h +++ b/tmk_core/protocol/usb_hid/usb_hid.h @@ -1,10 +1,6 @@ -#ifndef USB_HID_H -#define USB_HID_H +#pragma once  #include "report.h" -  extern report_keyboard_t usb_hid_keyboard_report;  extern uint16_t usb_hid_time_stamp; - -#endif diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index 485b20c900..e4db5d0654 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -226,8 +226,9 @@ static void    send_keyboard(report_keyboard_t *report);  static void    send_mouse(report_mouse_t *report);  static void    send_system(uint16_t data);  static void    send_consumer(uint16_t data); +static void    send_programmable_button(uint32_t data); -static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; +static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, send_programmable_button};  host_driver_t *vusb_driver(void) { return &driver; } @@ -296,6 +297,19 @@ void send_digitizer(report_digitizer_t *report) {  #ifdef DIGITIZER_ENABLE      if (usbInterruptIsReadyShared()) {          usbSetInterruptShared((void *)report, sizeof(report_digitizer_t)); +#endif +} + +static void send_programmable_button(uint32_t data) { +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    static report_programmable_button_t report = { +        .report_id = REPORT_ID_PROGRAMMABLE_BUTTON, +    }; + +    report.usage = data; + +    if (usbInterruptIsReadyShared()) { +        usbSetInterruptShared((void *)&report, sizeof(report));      }  #endif  } @@ -558,6 +572,26 @@ const PROGMEM uchar shared_hid_report[] = {      0xC0               // End Collection  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    // Programmable buttons report descriptor +    0x05, 0x0C,                           // Usage Page (Consumer) +    0x09, 0x01,                           // Usage (Consumer Control) +    0xA1, 0x01,                           // Collection (Application) +    0x85, REPORT_ID_PROGRAMMABLE_BUTTON,  //   Report ID +    0x09, 0x03,                           //   Usage (Programmable Buttons) +    0xA1, 0x04,                           //   Collection (Named Array) +    0x05, 0x09,                           //     Usage Page (Button) +    0x19, 0x01,                           //     Usage Minimum (Button 1) +    0x29, 0x20,                           //     Usage Maximum (Button 32) +    0x15, 0x00,                           //     Logical Minimum (0) +    0x25, 0x01,                           //     Logical Maximum (1) +    0x95, 0x20,                           //     Report Count (32) +    0x75, 0x01,                           //     Report Size (1) +    0x81, 0x02,                           //     Input (Data, Variable, Absolute) +    0xC0,                                 //   End Collection +    0xC0                                  // End Collection +#endif +  #ifdef SHARED_EP_ENABLE  };  #endif diff --git a/tmk_core/protocol/xt.h b/tmk_core/protocol/xt.h deleted file mode 100644 index 538ff0e459..0000000000 --- a/tmk_core/protocol/xt.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2018 Jun WAKO <wakojun@gmail.com> -Copyright 2016 Ethan Apodaca <papodaca@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -#include "quantum.h" - -#define XT_DATA_IN()               \ -    do {                           \ -        setPinInput(XT_DATA_PIN);  \ -        writePinHigh(XT_DATA_PIN); \ -    } while (0) - -#define XT_DATA_READ() readPin(XT_DATA_PIN) - -#define XT_DATA_LO()               \ -    do {                           \ -        writePinLow(XT_DATA_PIN);  \ -        setPinOutput(XT_DATA_PIN); \ -    } while (0) - -#define XT_CLOCK_IN()               \ -    do {                            \ -        setPinInput(XT_CLOCK_PIN);  \ -        writePinHigh(XT_CLOCK_PIN); \ -    } while (0) - -#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN) - -#define XT_CLOCK_LO()               \ -    do {                            \ -        writePinLow(XT_CLOCK_PIN);  \ -        setPinOutput(XT_CLOCK_PIN); \ -    } while (0) - -void xt_host_init(void); - -uint8_t xt_host_recv(void); diff --git a/tmk_core/protocol/xt_interrupt.c b/tmk_core/protocol/xt_interrupt.c deleted file mode 100644 index ba9d71848f..0000000000 --- a/tmk_core/protocol/xt_interrupt.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -Copyright 2018 Jun WAKO <wakojun@gmail.com> -Copyright 2016 Ethan Apodaca <papodaca@gmail.com> - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright -  notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright -  notice, this list of conditions and the following disclaimer in -  the documentation and/or other materials provided with the -  distribution. - -* Neither the name of the copyright holders nor the names of -  contributors may be used to endorse or promote products derived -  from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#include <stdbool.h> -#include <avr/interrupt.h> -#include "xt.h" -#include "wait.h" -#include "debug.h" - -static inline uint8_t pbuf_dequeue(void); -static inline void    pbuf_enqueue(uint8_t data); -static inline bool    pbuf_has_data(void); -static inline void    pbuf_clear(void); - -void xt_host_init(void) { -    XT_INT_INIT(); -    XT_INT_OFF(); - -    /* hard reset */ -#ifdef XT_RESET -    XT_RESET(); -#endif - -    /* soft reset: pull clock line down for 20ms */ -    XT_DATA_LO(); -    XT_CLOCK_LO(); -    wait_ms(20); - -    /* input mode with pullup */ -    XT_CLOCK_IN(); -    XT_DATA_IN(); - -    XT_INT_ON(); -} - -/* get data received by interrupt */ -uint8_t xt_host_recv(void) { -    if (pbuf_has_data()) { -        return pbuf_dequeue(); -    } else { -        return 0; -    } -} - -ISR(XT_INT_VECT) { -    /* -     * XT signal format consits of 10 or 9 clocks and sends start bits and 8-bit data, -     * which should be read on falling edge of clock. -     * -     *  start(0), start(1), bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7 -     * -     * Original IBM XT keyboard sends start(0) bit while some of clones don't. -     * Start(0) bit is read as low on data line while start(1) as high. -     * -     * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol -     */ -    static enum { START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7 } state = START; -    static uint8_t data                                                         = 0; - -    uint8_t dbit = XT_DATA_READ(); - -    // This is needed if using PCINT which can be called on both falling and rising edge -    // if (XT_CLOCK_READ()) return; - -    switch (state) { -        case START: -            // ignore start(0) bit -            if (!dbit) return; -            break; -        case BIT0 ... BIT7: -            data >>= 1; -            if (dbit) data |= 0x80; -            break; -    } -    if (state++ == BIT7) { -        pbuf_enqueue(data); -        state = START; -        data  = 0; -    } -    return; -} - -/*-------------------------------------------------------------------- - * Ring buffer to store scan codes from keyboard - *------------------------------------------------------------------*/ -#define PBUF_SIZE 32 -static uint8_t pbuf[PBUF_SIZE]; -static uint8_t pbuf_head = 0; -static uint8_t pbuf_tail = 0; - -static inline void pbuf_enqueue(uint8_t data) { -    uint8_t sreg = SREG; -    cli(); -    uint8_t next = (pbuf_head + 1) % PBUF_SIZE; -    if (next != pbuf_tail) { -        pbuf[pbuf_head] = data; -        pbuf_head       = next; -    } else { -        dprintf("pbuf: full\n"); -    } -    SREG = sreg; -} - -static inline uint8_t pbuf_dequeue(void) { -    uint8_t val = 0; - -    uint8_t sreg = SREG; -    cli(); -    if (pbuf_head != pbuf_tail) { -        val       = pbuf[pbuf_tail]; -        pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; -    } -    SREG = sreg; - -    return val; -} - -static inline bool pbuf_has_data(void) { -    uint8_t sreg = SREG; -    cli(); -    bool has_data = (pbuf_head != pbuf_tail); -    SREG          = sreg; -    return has_data; -} - -static inline void pbuf_clear(void) { -    uint8_t sreg = SREG; -    cli(); -    pbuf_head = pbuf_tail = 0; -    SREG                  = sreg; -} diff --git a/tmk_core/readme.md b/tmk_core/readme.md index a754cfee42..a47dc88185 100644 --- a/tmk_core/readme.md +++ b/tmk_core/readme.md @@ -25,7 +25,6 @@ These features can be used in your keyboard.  * Media Control Key   - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc  * USB NKRO            - 248 keys(+ 8 modifiers) simultaneously  * PS/2 mouse support  - PS/2 mouse(TrackPoint) as composite device -* Keyboard protocols  - PS/2, ADB, M0110, Sun and other old keyboard protocols  * User Function       - Customizable function of key with writing code  * Macro               - Very primitive at this time  * Keyboard Tricks     - Oneshot modifier and modifier with tapping feature @@ -84,9 +83,9 @@ Architecture        /          /| Keys/Mouse | Protocol  |d| | Action      | | | Protocol  |       /__________/ |<-----------|  LUFA     |r| |  Layer, Tap | | |  Matrix   |       |.--------.| |   LED      |  V-USB    |i| |-------------| | |  PS/2,IBM |             __________________ -     ||        || |----------->|  UART     |v| | Keymap      | | |  ADB,M0110|  Keys      / /_/_/_/_/_/_/_/ /| -     ||  Host  || |  Console   |           |e| | Mousekey    | | |  SUN/NEWS |<----------/ /_/_/_/_/_/_/_/ / / -     ||________||/.<-----------|           |r| | Report      | | |  X68K/PC98| Control  / /_/_/_/_/_/_/_/ / / +     ||        || |----------->|  UART     |v| | Keymap      | | |           |  Keys      / /_/_/_/_/_/_/_/ /| +     ||  Host  || |  Console   |           |e| | Mousekey    | | |           |<----------/ /_/_/_/_/_/_/_/ / / +     ||________||/.<-----------|           |r| | Report      | | |           | Control  / /_/_/_/_/_/_/_/ / /       `_========_'/|            |---------------------------------------------|-------->/___ /_______/ ___/ /       |_o______o_|/             | Sendchar, Print, Debug, Command, ...        |         |_________________|/                                 +---------------------------------------------+              Keyboard @@ -134,10 +133,6 @@ Files and Directories  * lufa/     - LUFA USB stack  * vusb/     - Objective Development V-USB  * ps2.c     - PS/2 protocol -* adb.c     - Apple Desktop Bus protocol -* m0110.c   - Macintosh 128K/512K/Plus keyboard protocol -* news.c    - Sony NEWS keyboard protocol -* x68k.c    - Sharp X68000 keyboard protocol  * serial_soft.c - Asynchronous Serial protocol implemented by software | 
